Evennia releases [docker images](https://hub.docker.com/r/evennia/evennia/) as part of regular commits and releases. This makes running an Evennia-based game in a Docker container easy.
First, install the `docker` program so you can run the Evennia container. You can get it freely from [docker.com](https://www.docker.com/). Linux users can likely also get it through their normal package manager.
This is a normal shell prompt. We are in the `/usr/src/game` location inside the docker container. If you had anything in the folder you started from, you should see it here (with `ls`) since we mounted the current directory to `usr/src/game` (with `-v` above). You have the `evennia` command available and can now proceed to create a new game as per the normal [game setup](./Installation.md) instructions (no virtualenv needed).
> The game folder or any new files that you created from inside the container will appear as owned by `root`. If you want to edit the files outside of the container you should change the ownership. On Linux/Mac you do this with `sudo chown myname:myname -R mygame`, where you replace `myname` with your username and `mygame` with whatever your game folder is named.
-`docker run ... evennia/evennia` tells us that we want to run a new container based on the `evennia/evennia` docker image. Everything in between are options for this. The `evennia/evennia` is the name of our [official docker image on the dockerhub repository](https://hub.docker.com/r/evennia/evennia/). If you didn't do `docker pull evennia/evennia` first, the image will be downloaded when running this, otherwise your already downloaded version will be used. It contains everything needed to run Evennia.
-`-p 4000:4000 -p 4001:4001 -p 4002:4002` means that we *map* ports `4000`, `4001` and `4002` from inside the docker container to same-numbered ports on our host machine. These are ports for telnet, webserver and websockets. This is what allows your Evennia server to be accessed from outside the container (such as by your MUD client)!
-`-v $PWD:/usr/src/game` mounts the current directory (*outside* the container) to the path `/usr/src/game`*inside* the container. This means that when you edit that path in the container you will actually be modifying the "real" place on your hard drive. If you didn't do this, any changes would only exist inside the container and be gone if we create a new one. Note that in linux a shortcut for the current directory is `$PWD`. If you don't have this for your OS, you can replace it with the full path to the current on-disk directory (like `C:/Development/evennia/game` or wherever you want your evennia files to appear).
-`--user $UID:$GID` ensures the container's modifications to `$PWD` are done with you user and group IDs instead of root's IDs (root is the user running evennia inside the container). This avoids having stale `.pid` files in your filesystem between container reboots which you have to force delete with `sudo rm server/*.pid` before each boot.
If you run the `docker` command given in the previous section from your game dir you can then easily start Evennia and have a running server without any further fuss.
But apart from ease of install, the primary benefit to running an Evennia-based game in a container is to simplify its deployment into a public production environment. Most cloud-based hosting
or updating your game as simple as building a new container image locally, pushing it to your Docker Hub account, and then pulling from Docker Hub into your AWS/Azure/other docker-enabled hosting account. The container eliminates the need to install Python, set up a virtualenv, or run pip to install dependencies.
For remote or automated deployment you may want to start Evennia immediately as soon as the docker container comes up. If you already have a game folder with a database set up you can also start the docker container and pass commands directly to it. The command you pass will be the main process to run in the container. From your game dir, run for example this command:
These steps assume that you have created or otherwise obtained a game directory already. First, `cd` to your game dir and create a new empty text file named `Dockerfile`. Save the following two lines into it:
(don't forget the period at the end, it will use the `Dockerfile` from the current location). Here `mydhaccount` is the name of your `dockerhub` account. If you don't have a dockerhub account you can build the image locally only (name the container whatever you like in that case, like just `mygame`).
Docker images are stored centrally on your computer. You can see which ones you have available locally with `docker images`. Once built, you have a couple of options to run your game.
Your game will be downloaded from your docker-hub account and a new container will be built using the image and started on the server! If your server environment forces you to use different ports, you can just map the normal ports differently in the command above.
The `evennia/evennia` docker image holds the evennia library and all of its dependencies. It also has an `ONBUILD` directive which is triggered during builds of images derived from it. This `ONBUILD` directive handles setting up a volume and copying your game directory code into the proper location within the container.
In most cases, the Dockerfile for an Evennia-based game will only need the `FROM evennia/evennia:latest` directive, and optionally a `MAINTAINER` directive if you plan to publish your image on Docker Hub and would like to provide contact info.
A new `evennia/evennia` image is built automatically whenever there is a new commit to the `main` branch of Evennia. It is possible to create your own custom evennia base docker image based on any arbitrary commit.
Note: From this point, you can also use the `docker tag` command to set a specific tag on your image and/or upload it into Docker Hub under your account.
The Docker ecosystem includes a tool called `docker-compose`, which can orchestrate complex multi- container applications, or in our case, store the default port and terminal parameters that we want specified every time we run our container. A sample `docker-compose.yml` file to run a containerized Evennia game in development might look like this:
> Note that with this setup you lose the `--user $UID` option. The problem is that the variable `UID` is not available inside the configuration file `docker-compose.yml`. A workaround is to hardcode your user and group id. In a terminal run `echo $UID:$GID` and if for example you get `1000:1000` you can add to `docker-compose.yml` a line `user: 1000:1000` just below the `image: ...` line.