Honest Minecraft server hosting
Gamocosm makes it easy to run cloud Minecraft servers. Digital Ocean is used as the backend/hosting service, due to cost, reliability, and accessibility. Gamocosm works well for friends who play together, but not 24/7. Running a server 14 hours a week (2 hours every day) may cost 40 cents a month, instead of $5.
The Minecraft Server Wrapper (for lack of a better name) is a light python webserver. It provides an HTTP API for starting and stopping Minecraft servers, downloading the world, etc. Please check it out and help improve it too!
The gamocosm-minecraft-flavours repository includes the setup scripts used to install different flavours of Minecraft on a new server. Read this wiki page for adding support for new flavours, or manually installing something yourself.
Pull requests are welcome!
You should have a Unix/Linux system. The following instructions were made for Fedora 31, but the steps should be similar on other distributions.
(sudo) dnf install postgresql-server postgresql-contrib postgresql-devel memcached redis nodejs
(sudo) dnf install gcc gcc-c++ openssl-devel readline-devel zlib-devel
rbenv install 2.6.5.
ruby -vinside your cloned
gamocosmfolder gives you version 2.6.5
gem install bundler
bundle install
cp env.sh.template env.sh
env.sh
(sudo) postgresql-setup initdb --unit postgresql
(sudo) systemctl start, or enable them to start at boot time:
(sudo) systemctl enable
./sysadmin/run.sh bundle exec rake db:setup
./sysadmin/run.sh bundle exec rails s
./sysadmin/run.sh bundle exec sidekiq
app: main source code
bin: rails stuff, don't touch
config: rails app configuration
db: rails app database stuff (schema, migrations, seeds)
lib: rails stuff, don't touch
log: 'nuff said
public: static files
sysadmin: stuff for the Gamocosm server (you can run your own server! This is a true open source project)
test-docker: use docker container to test most of
app/workers/setup_server_worker.rb(more below)
test: pooteeweet
vendor: rails stuff, don't touch
The script
./sysadmin/run.shbasically sources
env.shthen
execs the supplied command. You can
source env.shto load the relevant environment variables into your shell yourself. Then you can run stuff like
bundle exec ...directly.
DIGITAL_OCEAN_API_KEY: your Digital Ocean api token
DIGITAL_OCEAN_SSH_PUBLIC_KEY_PATH: ssh key to be added to new servers to SSH into
DIGITAL_OCEAN_SSH_PRIVATE_KEY_PATH: see above
DIGITAL_OCEAN_SSH_PRIVATE_KEY_PASSPHRASE: see above
SIDEKIQ_ADMIN_USERNAME: HTTP basic auth for Sidekiq web interface
SIDEKIQ_ADMIN_PASSWORD: see above
DATABASE_USER: hmmmm
DATABASE_PASSWORD: hmmmm
DATABASE_HOST: database host. If specified, Rails will use a TCP connection (e.g. "localhost"). If left blank, Rails will use a local Unix socket connection
MAIL_SERVER_*: see action mailer configuration in the Rails guide
USER_SERVERS_DOMAIN: subdomain for user servers (e.g.
gamocosm.com)
CLOUDFLARE_API_TOKEN: hmmm
CLOUDFLARE_EMAIL: hmmm
CLOUDFLARE_ZONE: shown on the bottom right of CloudFlare's control panel for the domain
DEVELOPMENT_HOST: only development, allowed host to access development server
DEVISE_SECRET_KEY: only test, production
SECRET_KEY: only production
DEVELOPER_EMAILS: comma separated list of emails to send exceptions to
BADNESS_SECRET: secret to protect
/badnessendpoint
Locate
pg_hba.conf. On Fedora this is in
/var/lib/pgsql/data/. This file tells postgresql how to authenticate users. Read about it on the PostgreSQL docs. To restart postgresql:
(sudo) service postgresql restart
config/database.ymlgets the database username from the environment variable
DATABASE_USER(default "gamocosm"). The default value in "env.sh.template" for
DATABASE_HOSTis blank, so if you don't change it Rails will use a local Unix socket connection. The postgres user you use must be a postgres superuser, as rails needs to enable the uuid extension. To create a postgres user "gamocosm":
postgresuser:
(sudo) su - postgres
createuser --createdb --pwprompt --superuser gamocosm(
createuser --helpfor more info)
Depending on what method you want to use, add the following under the line that looks like
# TYPE DATABASE USER ADDRESS METHOD.
local(local Unix socket) or
host(TCP connection)
postgresdatabase (to create new databases?)
postgres,gamocosm_development,gamocosm_test,gamocosm_production
gamocosm
localtype
127.0.0.1/32in ipv4 and
::1/128in ipv6. My system used ipv6 (postgres did not match the entry when I entered localhost ipv4)
config/database.ymlspecifies the database user to be "gamocosm", using this method is more troublesome, at least in development, because you have to either change that to your OS username and create a postgresql user with your username, or create a new OS account called "gamocosm" and a postgresql user "gamocosm"
peerbut for network connections
Example:
local postgres,gamocosm_development,gamocosm_test,gamocosm_production gamocosm md5
Hmmmm.
String#error!to mark a return value is an error
nil)
'API response code not 200'.error!(res)
String#error!returns an
Errorobject;
Error#to_sis overridden so the error message can be shown to the user, or the error data (
Error#data) can be further inspected for handling
.error?to check if a return value is an error.
Error#error?is overriden to return
true
config/initializers/monkey_patches.rb
server.remote.exists?:
!server.remote_id.nil?
server.remote.error?: whether there was an error or not retrieving info about a droplet from Digital Ocean
!server.remote.exists?
server.remoteactions (e.g.
server.remote.create)
server.running?:
server.remote.exists? && !server.remote.error? && server.remote.status == 'active'
user.digital_ocean.nil?: Digital Ocean API token missing
minecraft.node.error?: error communicating with Minecraft wrapper on server
minecraft.running?:
server.running? && !node.error? && node.pid > 0(notice symmetry with
server.running?)
ActiveRecord::Base.connection_pool.with_connection do |conn|if threads (e.g. timeout) access the database
server.reset_stateand
return
db/seed.rb): email "[email protected]", password "1234test", has the Digital Ocean api token from
env.sh
/sidekiq
/newrelic
bundle exec rails c
bundle exec rake db:reset
Sidekiq::Queue.new.each { |job| job.delete }in the rails console
Sidekiq::Stats.new.resetin the rails console
sysadmin/directory
rake dbcommands: Stack Overflow
bundle exec rails testor
./tests.sh
RAILS_ENV=test bundle exec railsto run the server or console (respectively) in test mode
Without a server to connect to, Gamocosm can't try SetupServerWorker or AutoshutdownMinecraftWorker. "test-docker/" contains a Dockerfile for building a basic Fedora container with an SSH server (simulating a bare Digital Ocean server). If you set
$TEST_DOCKERto "true", the tests will assume there is a running Docker Gamocosm container to connect to.
tests.shwill build the image, start the container, and delete the container for you if you specify to use Docker. Otherwise, it will run the tests normally (equivalent to
bundle exec rails test). You should have non-root access to Docker. You could also manage Docker yourself; you can look at the
tests.shfile for reference.
Example:
TEST_DOCKER=true ./tests.sh