Deploy Backend¶
Run the MIP backend (NestJS + Redis + MongoDB) on your server using Docker Compose.
The primary tool is the MIP Control Panel — it manages the remote stack directly from your dev machine via DOCKER_HOST over SSH, so you never need to manually SCP files or SSH in just to restart a container.
Prerequisites¶
- Server has Docker installed
- You can SSH into the server (key-based auth, e.g.
ssh ubuntu@SERVER_IP) - The KUBE credentials (
KUBE_SERVER,KUBE_TOKEN,KUBE_CA) are filled in the backend env file — run Script 03 from the Kubes setup if not done yet
Overview¶
The backend stack runs three containers:
flowchart LR
C[Game Clients] -- "REST + Socket.IO\nport 3000" --> BE[mip-be\nNestJS Backend]
GS[Game Servers\nK8s Pods] -- "Socket.IO\nport 3000" --> BE
BE -- "port 6379" --> R[Redis]
BE -- "port 27017" --> M[MongoDB]
R --- V1[Session Store\nPub/Sub\nRedlock]
M --- V2[Player Data\nPersistence]
The compose file and env file both live on your dev machine. The Control Panel sends compose commands to the remote Docker daemon over SSH — no file transfer needed.
1 — Prepare the Env File¶
Edit the env file for your mode on your dev machine:
| Mode | Env file |
|---|---|
| Testing | mip-be/scripts/test/.env.test |
| Shipping | mip-be/scripts/shipping/.env.shipping |
Required values to fill in¶
| Variable | What to set |
|---|---|
REDIS_PASSWORD |
Strong password for Redis — must match between the redis container and backend |
JWT_SECRET |
Strong secret for HS256 tokens (WebSocket auth, server SIO, user login) |
MONGO_INITDB_ROOT_PASSWORD |
MongoDB admin password — must match the password in MONGO_DB_URL |
MONGO_DB_URL |
Keep db:27017 (Docker service name). Update username/password to match the two fields above. Include ?authSource=admin |
KUBE_SERVER |
K3s API endpoint — see step 03. Use https://127.0.0.1:6443 if backend and K3s are on the same server |
KUBE_TOKEN |
Service account token — from script 03 |
KUBE_CA |
Cluster CA certificate (base64) — from script 03 |
JWT_PLAYER_RS256_PRIVATE_KEY_PEM |
RS256 private key — generate with the Gen RS256 Keys button (see below) |
JWT_PLAYER_RS256_PUBLIC_KEY_PEM |
RS256 public key — generated alongside the private key |
Warning
Change REDIS_PASSWORD, JWT_SECRET, and MONGO_INITDB_ROOT_PASSWORD to strong, unique values before deploying. Never use the example defaults in production.
Backend on the same server as K3s?
Set KUBE_SERVER=https://127.0.0.1:6443 instead of the Tailscale/external IP. See Deploy Master Node — Script 03 for the full explanation including the required network_mode: host change in docker-compose.
Variables that usually stay unchanged¶
| Variable | Value | Notes |
|---|---|---|
REDIS_ENDPOINT |
redis |
Docker service name |
REDIS_PORT |
6379 |
|
ALLOCATE_SERVER_PATH |
yamls/allocate-server.yaml |
Path inside the container |
CREATE_FLEET_PATH |
yamls/create-fleet.yaml |
Path inside the container |
CREATE_FLEET_AUTO_SCALE |
yamls/auto-scale.yaml |
Path inside the container |
2 — Generate RS256 Keys¶
The backend uses RS256 key pairs for player join/travel JWTs. Both JWT_PLAYER_RS256_PRIVATE_KEY_PEM and JWT_PLAYER_RS256_PUBLIC_KEY_PEM must be set before starting the stack.
In the Control Panel, go to the Backend tab → BUILD section → click Gen RS256 Keys (scripts/test/.env.test).
This will:
- Run
openssl genrsato generate a 2048-bit RSA key pair - Save
jwt_player_private.pemandjwt_player_public.pemintomip-be/scripts/test/ - Write the
\n-escaped PEM values directly intoscripts/test/.env.test
Note
Requires openssl on PATH on your dev machine. Install with choco install openssl -y if missing (then open a new terminal).
Tip
If the RS256 keys are missing or empty when you click Up, the Control Panel will show an error and block the start — click Gen RS256 Keys first.
3 — Deploy via the Control Panel¶
Open the MIP Control Panel and switch the mode (top-right dropdown) to Testing or Shipping.
Go to the Backend tab → REMOTE DEPLOY section.
Set the server connection¶
| Field | What to enter |
|---|---|
| Server IP | Tailscale hostname or IP of the server (e.g. mip-server or 100.x.x.x) |
| Username | SSH user on the server (default: ubuntu) |
The Control Panel connects via DOCKER_HOST=ssh://ubuntu@SERVER_IP, which forwards all docker compose commands to the remote Docker daemon over SSH. Your local compose and env files are used directly — nothing is copied to the server.
The four deploy buttons¶
| Button | What it does | Equivalent command |
|---|---|---|
| Pull | Pull the latest backend image from the registry | docker compose pull |
| Up | Start all containers in detached mode | docker compose up -d |
| Down | Stop and remove all containers | docker compose down |
| Logs | Stream live container logs | docker compose logs -f --tail=100 |
First deploy:
- Click Pull — pulls
mip-be-registry:latestfrom the GitLab registry - Click Up — starts Redis, MongoDB, and the backend
Updating to a new version:
- Click Pull — fetches the new image
- Click Down — stops the running stack
- Click Up — starts with the new image
Output from every command streams into the Backend console pane at the bottom of the Control Panel.
Which files does the Control Panel use?¶
The Control Panel reads BE_COMPOSE_FILE and BE_ENV_FILE from MIPScripts/env/<mode>.env:
| Mode | Compose file | Env file |
|---|---|---|
| Testing | scripts/test/docker-compose-test.yml |
scripts/test/.env.test |
| Shipping | scripts/shipping/docker-compose-shipping.yml |
scripts/shipping/.env.shipping |
Both paths are relative to BE_LOCAL_PATH (the backend repo root on your dev machine). To change them, edit MIPScripts/env/test.env or MIPScripts/env/shipping.env.
4 — UFW Rules¶
Run these once on the server:
Note
Game server UDP ports (7000:8000/udp) are opened during Setup Server.
Managing the Stack (Manual CLI Reference)¶
If you need to manage the stack directly on the server (useful for debugging):
| Action | Command |
|---|---|
| Start | docker compose -f /path/to/docker-compose-test.yml --env-file /path/to/.env.test up -d |
| Stop | docker compose -f ... down |
| Pull latest | docker compose -f ... pull |
| View backend logs | docker logs -f mip_backend_test |
| All logs | docker compose -f ... logs -f |
Tip
The Control Panel does all of the above remotely — you only need the manual commands for advanced debugging.
Data Persistence¶
MongoDB data is stored in a Docker volume (mip_db_data_test / mip_db_data_shipping). The volume persists across container restarts and docker compose down. To fully reset the database:
Warning
Removing the volume deletes all player data permanently. Only do this for a clean start.