mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
677e13353f
* Adds Dockerfile and Utility Scripts * Remove RUSTG_VERSION from _build_dependencies.sh * Moved documentation to references, added link to mkdocs.yml * Update references, finish documentation, fix typos * Fixed small error in docs and scripts * Add CI action to build and publish game server images * Bump CI action to compatible Ubuntu runner * Fix up the base image for NanoMap rendering * Remove commented out base for nanomap-build stage * Removed default values from Dockerfile build arguments Sanitized default arguments in Dockerfile Updated CI workflow to use _build_dependencies.sh to build the Docker image Added documentation on using --build-arg flags with the docker build command * Modify caching for Docker builds in CI * Add missing files to pacify Nanomap Renderer
855 lines
34 KiB
Markdown
855 lines
34 KiB
Markdown
# Docker
|
|
|
|
Docker provides an alternative environment for developing, building, testing,
|
|
and running software like Paradise. Keep reading to learn more.
|
|
|
|
## Quickstart
|
|
|
|
You just want to jump right into the thick of things? Awesome...
|
|
|
|
tools/docker/build
|
|
tools/docker/init-db
|
|
cp config/example/config.toml config/config.toml
|
|
cat secret/db-ss13-password.txt
|
|
nano config/config.toml
|
|
# --- edit 4 fields in [database_configuration] ---
|
|
# sql_enabled = true
|
|
# sql_address = "paradise_db"
|
|
# sql_username = "ss13"
|
|
# sql_password = "<insert secret/db-ss13-password.txt here>"
|
|
tools/docker/run
|
|
# --- connect: byond://<your-ip>:6666/ ---
|
|
|
|
Welcome to the station crew, enjoy your stay.
|
|
|
|
## Helpful Background
|
|
|
|
In order to get the most benefit out of this, you should probably have a few
|
|
things already set up:
|
|
|
|
- You should be able to run commands in a terminal window
|
|
- You need Docker installed and permissions to run it
|
|
|
|
On many distros, you will need to add your user to the `docker` group, and
|
|
perhaps login again in order to pick up the permissions change. Check the
|
|
instructions for installing Docker on your platform to verify what is needed.
|
|
|
|
If you don't know this stuff yet, that's OK. Ask around if anybody has
|
|
experience with Linux and/or Docker. Look up some tutorials online. Everybody
|
|
starts somewhere, and this could be where you start.
|
|
|
|
### Motivation for Using Docker with Paradise
|
|
|
|
Paradise is a complex service with many moving parts. Database, NanoMaps, Rust
|
|
libraries, TGUI, and the DreamMaker binary. The maintainers do a good job of
|
|
providing pre-baked dependencies for most of these. Advanced developers need to
|
|
learn how to compile Rust libraries and TGUI for themselves. This involves
|
|
installing other software like Node.js and Rust, then learning the special
|
|
commands to make things build. It is a complex task to learn everything that
|
|
goes into it.
|
|
|
|
What if it could be simple? What if you could rebuild a Paradise server image
|
|
from scratch with just one command?
|
|
|
|
tools/docker/build
|
|
|
|
Changed Rust libraries? Great, it'll recompile them. Changed TGUI stuff?
|
|
Great, it'll recompile that too. Changed the code? Great, it'll regenerate
|
|
the NanoMaps and build the game with DreamMaker. You'll create a new Docker
|
|
image for Paradise, complete and ready to test immediately.
|
|
|
|
tools/docker/run
|
|
|
|
There is a little more to it in practice. If you want to actually play on your
|
|
new server, you'll have to point BYOND at your machine. This means you need to
|
|
discover the IP address of your Linux machine on your network (`hostname -I`)
|
|
and feed it to BYOND like: `byond://192.168.0.xxx:6666/`. My network assigned
|
|
my machine `192.168.0.104` but you'll need to find yours for yourself!
|
|
|
|
### Fantastic Scripts and Where To Run Them
|
|
|
|
This repository contains several scripts in the `tools/docker` folder. These
|
|
scripts are intended as basic tools to get you set up, initialized, building,
|
|
and running with a minimum of effort and hassle.
|
|
|
|
Some of the names `paradise`, `paradise_db`, `paradise_db_data`, `paradise_net`
|
|
are baked into the scripts. If you want to run more than one database and more
|
|
than one server on the same machine (and yes, this is possible!), you'll need
|
|
to make some modifications to the scripts to make that happen.
|
|
|
|
In all cases, you should be running the scripts from the root of the
|
|
repository. That is, if you unzipped the source code into a folder, or if you
|
|
cloned the source repository from GitHub, you'll probably have a folder called
|
|
`Paradise`. That's where you should be when you run the scripts.
|
|
|
|
You invoke a script like so:
|
|
|
|
tools/docker/build
|
|
|
|
Don't change into subdirectories or run the scripts from other locations.
|
|
|
|
Most of the scripts have some checks built in, to make sure things that need to
|
|
be created have been created, and things that need to be running are running.
|
|
The only truly dangerous script is:
|
|
|
|
tools/docker/zzz-destroy-everything-zzz
|
|
|
|
If you invoke that, you will delete everything these scripts have done. Any
|
|
changes or other hard work you did will be permanently gone! Be careful!
|
|
|
|
## Docker Utility Scripts
|
|
|
|
There are eight utility scripts provided in the `tools/docker` folder. They
|
|
are:
|
|
|
|
- `backup-db`: Create a backup file of a running database container
|
|
- `build`: Build the `paradise:latest` Docker image
|
|
- `debug-db`: Get a MariaDB shell into a running database container
|
|
- `debug-server`: Create a server container, but run a bash shell instead of DreamDaemon
|
|
- `init-db`: Create a `paradise_db` database container and initialize it
|
|
- `restore-db`: Restore from backup file into a running database container
|
|
- `run`: Create a server container and run DreamDaemon
|
|
- `zzz-destroy-everything-zzz`: Delete all Paradise containers, images, networks, and volumes
|
|
|
|
## Creating a Local Paradise Server
|
|
|
|
This section will cover setting up a local Paradise server. You can use it to
|
|
test code that you're developing, practice making maxcap bombs that you could
|
|
never get away with on the real Paradise, or whatever you like.
|
|
|
|
### Building a Docker Image for Paradise
|
|
|
|
In order to create a Docker image, there must be a set of instructions for how
|
|
that image should be created. This blueprint for making an image is called a
|
|
`Dockerfile`. You can find the `Dockerfile` used to build the Paradise image
|
|
in the root (top level) of the codebase.
|
|
|
|
Docker uses a multi-stage build. This builds up each thing (NanoMaps, Rust
|
|
libraries, TGUI, the DreamMaker binary) in turn, then combines them all into a
|
|
final image. This image will be used to create server containers when you're
|
|
ready to run the software.
|
|
|
|
There is a script provided in the codebase to run this build command:
|
|
|
|
tools/docker/build
|
|
|
|
The first time you build, it may take several minutes to finish building.
|
|
Future builds will not take nearly as long, because Docker will remember the
|
|
intermediate steps in a cache, and re-use the result if nothing has changed
|
|
since the last time.
|
|
|
|
After the command is done, you can see your new Docker image by issuing the
|
|
command:
|
|
|
|
docker image ls
|
|
|
|
You should see something like this:
|
|
|
|
tux@linuxbox:~/Paradise$ docker image ls
|
|
IMAGE ID DISK USAGE CONTENT SIZE
|
|
paradise:latest bee29cf62073 398MB 0B
|
|
|
|
Note that our server image is named `paradise:latest`.
|
|
|
|
### Creating the Database Container
|
|
|
|
This is a script provided in the codebase to create and initialize a database
|
|
container:
|
|
|
|
tools/docker/init-db
|
|
|
|
That will grab the MariaDB image from Docker Hub, and use it to create a new
|
|
container with the MariaDB database software. It also does several other things
|
|
so we'll go over those one by one.
|
|
|
|
Here you can run a command to see the container in action:
|
|
|
|
docker ps --all
|
|
|
|
You should see something like this:
|
|
|
|
tux@linuxbox:~/Paradise$ docker ps --all
|
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
|
4aa9b04f056b mariadb:12 "docker-entrypoint.s" 3 hours ago Up 3 seconds 3306/tcp paradise_db
|
|
|
|
Now we're ready to talk about the other things that `tools/docker/init-db` did
|
|
behind the scenes.
|
|
|
|
#### Paradise Database Data Volume
|
|
|
|
Docker containers are ephemeral things; they are meant to be created and
|
|
destroyed quite often, and not good or safe homes for things we want to keep.
|
|
|
|
A database stores information that we want to keep around for an indefinite
|
|
period of time. So instead of allowing the database files to live in the
|
|
database container, the `init-db` script will create a Docker volume named
|
|
`paradise_db_data`. The volume is attached to a database container when that
|
|
container is created.
|
|
|
|
You can see the new `paradise_db_data` volume with this command:
|
|
|
|
docker volume ls
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ docker volume ls
|
|
DRIVER VOLUME NAME
|
|
local paradise_db_data
|
|
|
|
If you want to know where those database files actually live on disk, you can
|
|
use the following command:
|
|
|
|
docker volume inspect paradise_db_data
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ docker volume inspect paradise_db_data
|
|
[
|
|
{
|
|
"CreatedAt": "2026-01-16T21:39:10-06:00",
|
|
"Driver": "local",
|
|
"Labels": null,
|
|
"Mountpoint": "/home/tux/.local/share/docker/volumes/paradise_db_data/_data",
|
|
"Name": "paradise_db_data",
|
|
"Options": null,
|
|
"Scope": "local"
|
|
}
|
|
]
|
|
|
|
Here we see `/home/tux/.local/share/docker/volumes/paradise_db_data/_data` is
|
|
where the data actually lives on disk. Most of the time we don't really care.
|
|
The data lives in the Docker volume, and that's usually all we need to know.
|
|
|
|
##### Database Credentials
|
|
|
|
When the `init-db` script creates a new database volume, it generates secure
|
|
passwords for the newly created database. The MariaDB image includes some magic
|
|
to automatically create a user and set passwords. This is done through some
|
|
`MYSQL_*` environment variables; see the [Documentation for the MySQL Image](https://hub.docker.com/_/mysql#environment-variables).
|
|
|
|
MariaDB only applies the `MYSQL_*` environment variables the first time it
|
|
initializes an empty data directory. You can create and destroy the database
|
|
container as many times as you like. The passwords live in the database volume.
|
|
|
|
If you keep the `paradise_db_data` volume and recreate the container, the old
|
|
passwords remain. If you delete the volume, the "data" part of the database is
|
|
deleted. In that case `init-db` will create a new database volume, and generate
|
|
new passwords for this new database.
|
|
|
|
The `init-db` script will output the passwords to the `secret` directory. The
|
|
files are named:
|
|
|
|
secret/db-ss13-password.txt
|
|
secret/db-root-password.txt
|
|
|
|
The game server container uses the `ss13` user and password.
|
|
The utility scripts use the `root` user and password.
|
|
|
|
#### Paradise Network
|
|
|
|
One of the neat things about Docker is that it has an internal network concept.
|
|
A Docker network indicates which containers are allowed to talk to one another.
|
|
|
|
This can be nice from an organizational standpoint. Instead of having to find
|
|
IP addresses and individual ports for every container, they can live in their
|
|
own network, and not interfere with one another.
|
|
|
|
This can also be nice from a security standpoint. The database container shows
|
|
`3306/tcp`, but that means it's listening to port 3306 at the container on the
|
|
network it is attached to. Only other containers on that same network can reach
|
|
out to contact the database. By default it isn't exposed on the host, so
|
|
`localhost:3306` won't work unless you explicitly publish the port.
|
|
|
|
The `init-db` script will create a Docker network called `paradise_net`. You
|
|
can see the new network with the following command:
|
|
|
|
docker network ls
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ docker network ls
|
|
NETWORK ID NAME DRIVER SCOPE
|
|
760399a52cac bridge bridge local
|
|
0987646c9a0b host host local
|
|
f6aae2702134 none null local
|
|
e06521af6993 paradise_net bridge local
|
|
|
|
Our scripts will create two containers on the `paradise_net` network; the
|
|
database container, and the game server container. This means only containers
|
|
attached to `paradise_net` can reach the database.
|
|
|
|
### Creating the Game Server Container
|
|
|
|
Now that the `init-db` script has done all the difficult setup work, we can
|
|
create a container that runs the game server. That is, the container will be
|
|
created using the `paradise:latest` image, run DreamDaemon, and make the game
|
|
server available to the host network for connecting.
|
|
|
|
#### Configuration Work
|
|
|
|
Before we can create the game server container, it's important to talk about
|
|
volume mounts. This is similar to the Docker volume that we talked about
|
|
earlier, but is different because we are attaching specific folders from the
|
|
file system to the game server container when we create it.
|
|
|
|
The Paradise game server needs two folders:
|
|
|
|
- `/config`: Configuration options are stored here
|
|
- `/data`: Logs and current game mode are stored here
|
|
|
|
The `/data` folder does not need to exist. The script to create the game server
|
|
container will create it, if it doesn't already exist.
|
|
|
|
The `/config` folder has some information that we need to adjust before our
|
|
game server can start running.
|
|
|
|
##### Configuring config.toml
|
|
|
|
The main configuration file for a Paradise server is `config.toml`. You can
|
|
find an example in the code repository at `config/example/config.toml`.
|
|
|
|
The first thing we want to do is make our own copy of the example, so we can
|
|
modify it with our own configuration:
|
|
|
|
cp -v config/example/config.toml config/config.toml
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ cp -v config/example/config.toml config/config.toml
|
|
'config/example/config.toml' -> 'config/config.toml'
|
|
|
|
Before we get started on editing, we need the password to the database. When
|
|
`init-db` created the database container, it also generated a file to store
|
|
the database password: `secret/db-ss13-password.txt`
|
|
|
|
We need to see this password so we can copy-pasta it into our configuration
|
|
file. That is, tell the game server the secret password to talk to the
|
|
database. Run this command:
|
|
|
|
cat secret/db-ss13-password.txt
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ cat secret/db-ss13-password.txt
|
|
QFHvl6hRjRGAQsH8b45fhpgeilB11PcO
|
|
|
|
**NOTE**: This is a *secret*. You can write it down on a piece of paper for
|
|
yourself, but you should NOT share it online, nor share any screenshots of
|
|
the password.
|
|
|
|
Now we need a text editor to edit `config/config.toml`. Common text editors
|
|
on Linux are `nano` and `vim`, but you can use your favorite. We'll assume you
|
|
use `nano` and run a command like this:
|
|
|
|
nano config/config.toml
|
|
|
|
This will open the configuration file. If you scroll down, you'll find a
|
|
section under the heading `[database_configuration]`. This is what we want
|
|
to edit:
|
|
|
|
[database_configuration]
|
|
# This section contains all the settings for the ingame database
|
|
# If you are running in production, you will want to be using a database
|
|
|
|
# Enable/disable the database on a whole
|
|
sql_enabled = false
|
|
# SQL version. If this is a mismatch, round start will be delayed
|
|
sql_version = 71
|
|
# SQL server address. Can be an IP or DNS name
|
|
sql_address = "127.0.0.1"
|
|
# SQL server port
|
|
sql_port = 3306
|
|
# SQL server database name
|
|
sql_database = "paradise_gamedb"
|
|
# SQL server username
|
|
sql_username = "root"
|
|
# SQL server password
|
|
sql_password = "please use something secure in a production environment"
|
|
# Time in seconds for async queries to time out
|
|
async_query_timeout = 10
|
|
# How many threads is the async SQL engine allowed to open. 50 is normal. Trust me.
|
|
async_thread_limit = 50
|
|
|
|
There are four fields that we need to change. The first field is
|
|
`sql_enabled`. By default it is set to `false`. We want to change that to
|
|
`true`:
|
|
|
|
sql_enabled = true
|
|
|
|
The second field we need to change is `sql_address`. This identifies the
|
|
container that the game server will contact to reach the database. Our database
|
|
container is called `paradise_db`, so that's what we'll change it to:
|
|
|
|
sql_address = "paradise_db"
|
|
|
|
The third field we need to change is `sql_username`. Our database uses a
|
|
regular user called `ss13`. So we'll change the field as follows:
|
|
|
|
sql_username = "ss13"
|
|
|
|
The fourth field we need to change is `sql_password`. This is where we paste
|
|
in that secret password that we printed out before.
|
|
|
|
sql_password = "QFHvl6hRjRGAQsH8b45fhpgeilB11PcO"
|
|
|
|
**NOTE**: This random password is just an example for this documentation. If
|
|
you try to use the password written here, you won't be able to connect to your
|
|
database. You'll need to see what the `init-db` script created for you. Run
|
|
that command `cat secret/db-ss13-password.txt` and see what *your* password is.
|
|
|
|
When you are all done editing the file, save it. In `nano`, you type Ctrl-X,
|
|
then Y for (Yes, I want to save my changes), then Enter. Other text editors
|
|
will have their own command to save the file.
|
|
|
|
#### All Systems Go!
|
|
|
|
Now that we are fully configured, we are ready to create a game server
|
|
container. To do so, run the following command:
|
|
|
|
tools/docker/run
|
|
|
|
Unless you edit the script, this will run the container in the foreground.
|
|
You will see a long startup sequence, as DreamDaemon loads and initializes
|
|
the Paradise software.
|
|
|
|
In another terminal window, you can see the game server container running
|
|
with the following command:
|
|
|
|
docker ps --all
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ docker ps --all
|
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
|
62f9d7c37db7 paradise:latest "DreamDaemon paradis" 14 seconds ago Up 14 seconds 0.0.0.0:6666->6666/tcp, [::]:6666->6666/tcp paradise
|
|
|
|
While the database container had `3306/tcp`, we see that the game server
|
|
container has a more complicated `0.0.0.0:6666->6666/tcp`. This means that
|
|
the Docker host is forwarding it's own port 6666 to the game server container's
|
|
port 6666.
|
|
|
|
That is to say, if somebody connects to the Linux machine that is running
|
|
Docker on port 6666, then that network traffic will be sent to the game server
|
|
container on port 6666. If you point BYOND's DreamSeeker at the Linux machine
|
|
to port 6666, it will reach the running game server!
|
|
|
|
To stop the game server, you can press Ctrl+C in the terminal where you started
|
|
the game server container. Or in another terminal window you can run the
|
|
command:
|
|
|
|
docker stop paradise
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ docker stop paradise
|
|
paradise
|
|
|
|
You can use `tools/docker/run` whenever you want to create and run a new game
|
|
server container.
|
|
|
|
## Development with Docker
|
|
|
|
Development with Docker is pretty easy. Just edit your code in the repository,
|
|
(any editor is fine; VS Code works well) and then run the build script again:
|
|
|
|
tools/docker/build
|
|
|
|
If the build is successful, you can start the server container and test your
|
|
changes:
|
|
|
|
tools/docker/run
|
|
|
|
Do this repeatedly when you develop fun new features for the Paradise server.
|
|
|
|
## Advanced Database Administration
|
|
|
|
This section covers some of the more advanced tools for working with your
|
|
database.
|
|
|
|
### Database Backups
|
|
|
|
Everybody knows that important data needs to be backed up. In fact, you should
|
|
make it a habit to create a backup when you begin work. That way, no matter how
|
|
many mistakes you make or how badly you break the database, you'll have a
|
|
backup to undo all the mistakes and get back to the way things were when you
|
|
got started.
|
|
|
|
To ask your database container to create a backup of your database, run the
|
|
following command:
|
|
|
|
tools/docker/backup-db
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ tools/docker/backup-db
|
|
Wrote backup: paradise_db.sql
|
|
|
|
Copy this `paradise_db.sql` file to a USB stick. Then, upload the
|
|
`paradise_db.sql` file to Google Drive, OneDrive, Dropbox, or some other cloud
|
|
service of your choice. If you do this, you'll have a 3-2-1 backup.
|
|
|
|
#### 3-2-1 Backups
|
|
|
|
The high-falutin' IT folks talk about 3-2-1 backups. You want at least THREE
|
|
(3) copies of your data, on at least TWO (2) different kinds of media, and at
|
|
least ONE (1) copy should be kept "off-site".
|
|
|
|
Here "off-site" means if the building where you regularly keep your data burns
|
|
down, you know that you will still have a copy of your data that didn't get
|
|
burned up in a fire.
|
|
|
|
When you generated the backup, you had two copies of your data; one in the
|
|
Docker volume, and one in the `paradise_db.sql` file. When you copied it to a
|
|
USB stick, you had three copies of your data, on two different kinds of media;
|
|
your hard drive and an external USB stick. When you uploaded to the cloud,
|
|
you had four copies, on three different kinds of media, and one is off-site;
|
|
on somebody else's machine somewhere out there in the internet tubes.
|
|
|
|
This is as good of a backup as anybody in the IT world can give you.
|
|
|
|
### Database Restores
|
|
|
|
Remember that a backup is only good if A) You still have the backup when you
|
|
need it, and B) You can restore the backup to create a working system!
|
|
|
|
We covered the making sure you still have a copy when you need it. In this
|
|
section, we'll cover restoring the backup to create a new database container.
|
|
|
|
#### The Easy Database Restore Scenario
|
|
|
|
Scenario: You've got a running setup and you've been working on some code that
|
|
requires database changes. After a bad run, you realize it messed up the data
|
|
in the database, and you need some rows back for further testing.
|
|
|
|
This is an easy scenario. Your database container is still running. Your
|
|
database volume is present and healthy. And you've got your backup file.
|
|
|
|
To restore our database from the backup file, just run this command:
|
|
|
|
tools/docker/restore-db
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ tools/docker/restore-db
|
|
Restored backup: paradise_db.sql
|
|
|
|
And that's it! Your database is restored back to when the backup was created.
|
|
That was easy, because this is the easy scenario.
|
|
|
|
#### The Hard Database Restore Scenario
|
|
|
|
Scenario: Your hard drive died. You had to replace the hard drive and download
|
|
all the stuff again. Fortunately you had a copy of `config.toml` and
|
|
`paradise_db.sql` up in the cloud. So you're ready to restore your system back
|
|
to working condition.
|
|
|
|
First, we follow the directions to create a new database container and volume:
|
|
|
|
tools/docker/init-db
|
|
|
|
Next, we realize, this is a *brand new* database volume, which means it will
|
|
have a *brand new* password. We need to see what that new password is:
|
|
|
|
cat secret/db-ss13-password.txt
|
|
|
|
Then we need to update `config/config.toml` and copy-pasta the new password
|
|
in to the `sql_password` field:
|
|
|
|
nano config/config.toml
|
|
|
|
And now that we've got a running database container and our configuration file
|
|
all straightened out, we'll restore from the backup:
|
|
|
|
tools/docker/restore-db
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ tools/docker/restore-db
|
|
Restored backup: paradise_db.sql
|
|
|
|
And that's it! Your database is restored back to when the backup was created.
|
|
That was harder, because that was the hard scenario where we needed to edit
|
|
the password in the configuration file, because we lost our old one.
|
|
|
|
### Database Queries
|
|
|
|
Once you get to advanced development, you may need to make changes to the
|
|
structure of the database. You may need to add or remove columns, or create
|
|
a brand new table. And you'll need to query to see if your changes are working
|
|
as you intended.
|
|
|
|
In order to get a shell into the database, run the following command:
|
|
|
|
tools/docker/debug-db
|
|
|
|
You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ tools/docker/debug-db
|
|
Reading table information for completion of table and column names
|
|
You can turn off this feature to get a quicker startup with -A
|
|
|
|
Welcome to the MariaDB monitor. Commands end with ; or \g.
|
|
Your MariaDB connection id is 4
|
|
Server version: 12.1.2-MariaDB-ubu2404 mariadb.org binary distribution
|
|
|
|
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
|
|
|
|
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
|
|
|
MariaDB [paradise_gamedb]>
|
|
|
|
Here you are in a MariaDB shell and can execute a query like:
|
|
|
|
SELECT count(*) AS num_rounds FROM round;
|
|
|
|
You should see something like:
|
|
|
|
MariaDB [paradise_gamedb]> SELECT count(*) AS num_rounds FROM round;
|
|
+------------+
|
|
| num_rounds |
|
|
+------------+
|
|
| 2 |
|
|
+------------+
|
|
1 row in set (0.001 sec)
|
|
|
|
Teaching the ins and outs of writing and executing SQL queries is beyond the
|
|
scope of this document. However, there are lots of resources online, and AI are
|
|
surprisingly good tutors if you have questions about SQL databases and queries.
|
|
|
|
### Custom Database Container Creation
|
|
|
|
Earlier, we mentioned that the MariaDB image will use some environment
|
|
variables to do special initialization when the database container is first
|
|
created. This is not the only magic trick embedded in that MariaDB image.
|
|
|
|
Another useful feature is mounting some directory from the repository at
|
|
`/docker-entrypoint-initdb.d` in the container. On the first run, when the
|
|
database container is being created, all the SQL scripts found in that
|
|
directory will be applied to the database in alphabetical order.
|
|
|
|
The script `tools/docker/init-db` mounts the `SQL` directory from the
|
|
repository into the database container at `/docker-entrypoint-initdb.d`.
|
|
By doing so, the SQL script that creates the Paradise database schema
|
|
`paradise_schema.sql` is automatically applied when the volume is first
|
|
created.
|
|
|
|
This is already incredibly useful, giving you a database with the correct
|
|
tables and columns straight away. However, it can also be used to populate
|
|
your database with extra data. Simply create a SQL script in the `SQL`
|
|
directory before you create the database:
|
|
|
|
nano SQL/zzz_001_my_cool_data.sql
|
|
|
|
And you can put whatever queries you want to be run against the database when
|
|
it is first created. For example, if you'd like to pre-populate your database
|
|
with your favorite characters, give yourself and your friends admin rights, and
|
|
that sort of thing; all of these are possible.
|
|
|
|
In order to leverage this, you will need to know how to write SQL queries, or
|
|
at least find a SQL script that you want to apply to your database.
|
|
|
|
## Advanced Game Server Image Building and Debugging
|
|
|
|
### Customizing Game Server Image Builds
|
|
|
|
One of the magic powers hidden in the `tools/docker/build` script, is that
|
|
additional arguments are supplied to the `docker build` command:
|
|
|
|
# build the docker image
|
|
docker build "$@" \
|
|
--build-arg "NODE_VERSION=${NODE_VERSION}" \
|
|
--build-arg "RUST_VERSION=${RUST_VERSION}" \
|
|
--build-arg "STABLE_BYOND_MAJOR=${STABLE_BYOND_MAJOR}" \
|
|
--build-arg "STABLE_BYOND_MINOR=${STABLE_BYOND_MINOR}" \
|
|
--tag "${SERVER_IMAGE}" \
|
|
.
|
|
|
|
That little `"$@"` doesn't look like it's doing much, but if means you can
|
|
supply any extra argument. Let's say you want Docker to skip it's internal
|
|
cache and rebuild everything from absolute scratch:
|
|
|
|
tools/docker/build --no-cache
|
|
|
|
The `--no-cache` flag [disables the build cache](https://docs.docker.com/build/building/best-practices/#use---no-cache-for-clean-builds).
|
|
You feed that flag to the utility script, and the `"$@"` passes it along to the
|
|
`docker build` command that gets executed to build the game server image.
|
|
|
|
Maybe you don't like how often the NanoMaps are being rendered? You could add
|
|
a flag `--build-arg "SKIP_NANOMAPS=TRUE"`. Now, if you modify the `Dockerfile`
|
|
in the right way:
|
|
|
|
# Render NanoMaps
|
|
FROM base AS nanomap-build
|
|
ARG SKIP_NANOMAPS
|
|
COPY _maps _maps
|
|
COPY code code
|
|
COPY icons icons
|
|
COPY tools/github-actions tools/github-actions
|
|
COPY paradise.dme paradise.dme
|
|
RUN bash -lc '[ -n "${SKIP_NANOMAPS:-}" ] || tools/github-actions/nanomap-renderer-invoker.sh'
|
|
|
|
Now you can build and force it to skip rendering the NanoMaps:
|
|
|
|
tools/docker/build --build-arg "SKIP_NANOMAPS=TRUE"
|
|
|
|
Doing things like this are left as an exercise for the Expert Level reader.
|
|
|
|
### Debugging Game Server Images
|
|
|
|
If you modify the `Dockerfile` at some point, you'll end up changing what
|
|
things end up in the final `paradise:latest` image. If things are missing, or
|
|
out of place, or not what you expect, it can lead to strange errors.
|
|
|
|
If you ever wonder, "What all is in this image anyway?" then the command you
|
|
want to run is:
|
|
|
|
tools/docker/debug-server
|
|
|
|
This will create a game server container. However, instead of running
|
|
DreamDaemon, it will run a bash shell. You should see something like:
|
|
|
|
tux@linuxbox:~/Paradise$ tools/docker/debug-server
|
|
root@28cac9c76c8a:/#
|
|
|
|
This is your opportunity to run shell commands like `ls -l` to see what the
|
|
DreamDaemon software running in the container will see. For example:
|
|
|
|
root@28cac9c76c8a:/# ls -l
|
|
total 184276
|
|
drwxr-xr-x 3 root root 4096 Jan 4 16:56 _maps
|
|
lrwxrwxrwx 1 root root 7 Sep 29 00:00 bin -> usr/bin
|
|
drwxr-xr-x 2 root root 4096 Aug 24 16:05 boot
|
|
drwxr-xr-x 2 root root 4096 Jan 17 07:47 config
|
|
drwxr-xr-x 2 root root 4096 Jan 17 07:47 data
|
|
drwxr-xr-x 5 root root 360 Jan 17 07:47 dev
|
|
drwxr-xr-x 1 root root 4096 Jan 17 07:47 etc
|
|
drwxr-xr-x 2 root root 4096 Aug 24 16:05 home
|
|
drwxr-xr-x 1 root root 4096 Jan 4 16:56 icons
|
|
lrwxrwxrwx 1 root root 7 Sep 29 00:00 lib -> usr/lib
|
|
lrwxrwxrwx 1 root root 9 Sep 29 00:00 lib64 -> usr/lib64
|
|
-rwxr-xr-x 1 root root 10426480 Jan 17 03:00 librustlibs.so
|
|
drwxr-xr-x 2 root root 4096 Sep 29 00:00 media
|
|
drwxr-xr-x 2 root root 4096 Sep 29 00:00 mnt
|
|
drwxr-xr-x 2 root root 4096 Sep 29 00:00 opt
|
|
-rw-r--r-- 1 root root 31268364 Jan 17 02:57 paradise.dmb
|
|
-rw-r--r-- 1 root root 146923054 Jan 17 06:02 paradise.rsc
|
|
dr-xr-xr-x 426 nobody nogroup 0 Jan 17 07:47 proc
|
|
drwx------ 2 root root 4096 Sep 29 00:00 root
|
|
drwxr-xr-x 3 root root 4096 Sep 29 00:00 run
|
|
lrwxrwxrwx 1 root root 8 Sep 29 00:00 sbin -> usr/sbin
|
|
drwxr-xr-x 2 root root 4096 Sep 29 00:00 srv
|
|
drwxr-xr-x 3 root root 4096 Jan 4 16:56 strings
|
|
dr-xr-xr-x 13 nobody nogroup 0 Jan 17 07:47 sys
|
|
drwxr-xr-x 3 root root 4096 Jan 17 06:03 tgui
|
|
drwxrwxrwt 2 root root 4096 Sep 29 00:00 tmp
|
|
drwxr-xr-x 1 root root 4096 Sep 29 00:00 usr
|
|
drwxr-xr-x 1 root root 4096 Sep 29 00:00 var
|
|
|
|
Wow! There's a whole Linux system in there, along with some Paradise stuff
|
|
like `librustlibs.so`, `paradise.dmb`, and `paradise.rsc`. Have fun exploring!
|
|
|
|
## Uninstall Docker Changes
|
|
|
|
And now we've reached the end of the line. The last script we can talk about
|
|
is `tools/docker/zzz-destroy-everything-zzz`. This script does what it says on
|
|
the tin. It will destroy EVERYTHING created by the other scripts.
|
|
|
|
#
|
|
# !!! This script will destroy everything !!!
|
|
#
|
|
# Your database and server containers will be stopped and deleted.
|
|
# The database volume containing all the data in your database will be deleted.
|
|
# The server image you last built will be deleted.
|
|
# The docker network the database container and server container used to talk to each other will be deleted.
|
|
# The entire secret/ directory, and the database credentials kept there, will be deleted.
|
|
# The backup file for your database will be deleted.
|
|
#
|
|
# NOTE: Destroys all of the things. !! EVERYTHING !! You have been warned!
|
|
#
|
|
|
|
It has an odd name `zzz-destroy-everything-zzz` and even refuses to run unless
|
|
you provide the secret password:
|
|
|
|
tux@linuxbox:~/Paradise$ zzz-destroy-everything-zzz
|
|
Error: If you *really* want to do this:
|
|
|
|
tools/docker/zzz-destroy-everything-zzz honk-honk-honk
|
|
|
|
There is NO way to UNDO this! If you do this, you destroy *everything*, PERMANENTLY!
|
|
|
|
Don't run it unless you're absolutely sure that you want that data to take a
|
|
one-way trip to the bit bucket.
|
|
|
|
tools/docker/zzz-destroy-everything-zzz honk-honk-honk
|
|
|
|
If you followed my instructions about the 3-2-1 Backup, you can probably
|
|
re-create it all in a few minutes. If you didn't save yourself a 3-2-1 Backup,
|
|
then you really did destroy everything. 仕方がない。
|
|
|
|
## Expert Level
|
|
|
|
You've learned about all the utility scripts that have been provided to you.
|
|
Note that all of the scripts follow the same basic pattern:
|
|
|
|
- Bind some bespoke names; `paradise_db`, `paradise:latest`, etc.
|
|
- Run some basic sanity checks
|
|
- Run a `docker $COMMAND` command, like `docker build` or `docker run`
|
|
|
|
The scripts use a common set of names between them, which is why they
|
|
interoperate together so well. That is, you can run `tools/docker/backup-db`
|
|
and later run `tools/docker/restore-db` because both scripts agree on what
|
|
the database container is called, what the backup file is called, etc.
|
|
|
|
If you want to call your game server image `paradise:20260117`, there is
|
|
nothing to stop you from editing the utilty script, or creating your own!
|
|
|
|
You will have to learn about bash shell script.
|
|
You will have to learn about Docker commands.
|
|
You might need to learn about SQL queries.
|
|
|
|
However, the utility scripts can guide you. Take a look at what docker command
|
|
they are running under the hood, and what flags and names they give to the
|
|
docker command.
|
|
|
|
You're a black belt now, so your real training can finally begin.
|
|
|
|
### First Lesson
|
|
|
|
The top of the `Dockerfile` (the blueprint for building a Docker image) has a
|
|
list of required build arguments:
|
|
|
|
# You MUST supply these to `docker build` with a `--build-arg` flag!
|
|
ARG NODE_VERSION=0
|
|
ARG RUST_VERSION=0
|
|
ARG STABLE_BYOND_MAJOR=0
|
|
ARG STABLE_BYOND_MINOR=0
|
|
|
|
Per the comment, you'll need to supply these values to the `docker build`
|
|
command with the `--build-arg` flag, similar to the way the tool script does.
|
|
|
|
# determine which versions to use in order to build everything
|
|
source _build_dependencies.sh
|
|
|
|
# build the docker image
|
|
docker build "$@" \
|
|
--build-arg "NODE_VERSION=${NODE_VERSION}" \
|
|
--build-arg "RUST_VERSION=${RUST_VERSION}" \
|
|
--build-arg "STABLE_BYOND_MAJOR=${STABLE_BYOND_MAJOR}" \
|
|
--build-arg "STABLE_BYOND_MINOR=${STABLE_BYOND_MINOR}" \
|
|
--tag "${SERVER_IMAGE}" \
|
|
.
|
|
|
|
Note that we `source _build_dependencies.sh` to pick up the recommended
|
|
version numbers for the software used to build Paradise.
|
|
|
|
Let's say that you want to check if TGUI still works with a more modern
|
|
version of Node.js. You modify `NODE_VERSION` in `_build_dependencies.sh` as
|
|
follows:
|
|
|
|
# For TGUI
|
|
export NODE_VERSION="24.13.0"
|
|
|
|
The tool script (`tools/docker/build`) will pick up that change, and build your
|
|
Docker image using that version of Node. Will it actually build? I don't know.
|
|
If not, you've got some software develoment work ahead of you. 頑張ってください!
|