Skip to content

Docker ​

The server image is ghcr.io/moinchat/moin-server, for linux/amd64 and linux/arm64. It works with every setup; this page starts with coordinator only.

1. Write the configuration ​

Create moin-server.toml:

toml
data_dir = "/data"
name = "Game Night"
rooms = "managed"

[access]
bootstrap_secret = "correct-horse-battery-staple"

Keep data_dir = "/data" in every configuration you use with the image. The bootstrap secret lets you claim the community from the app.

2. Start the server ​

sh
docker run -d --name moin-server --restart unless-stopped --stop-timeout 60 \
  -v moin-data:/data \
  -v "$(pwd)/moin-server.toml:/config/moin-server.toml:ro" \
  ghcr.io/moinchat/moin-server:latest

Or with Docker Compose, in a compose.yaml next to the configuration:

yaml
services:
  moin-server:
    image: ghcr.io/moinchat/moin-server:latest
    restart: unless-stopped
    stop_grace_period: 60s
    volumes:
      - moin-data:/data
      - ./moin-server.toml:/config/moin-server.toml:ro

volumes:
  moin-data:
sh
docker compose up -d

3. Claim the community ​

Print the server ID:

sh
docker exec moin-server moin-server admin --config /config/moin-server.toml status

With Compose, use docker compose exec moin-server instead of docker exec moin-server. Every other admin command runs the same way.

Then carry on from the coordinator-only guide: claim the community in the app, create rooms and invite people.

Volumes ​

PathContents
/dataThe server's data directory. Back it up; see the data directory.
/config/moin-server.tomlThe configuration.

The server runs as UID and GID 10001. A named volume works as is; a bind-mounted /data must be writable by that user.

Without a mounted configuration, the image starts a coordinator-only community called "Moin Community" with no bootstrap secret. Make yourself administrator with roles set.

Other setups ​

Write the configuration from the setup's guide, add data_dir = "/data", and publish its ports.

Behind a reverse proxy: set http_bind to 0.0.0.0:8080 so the proxy can reach it, then publish the HTTP port to the host only and the UDP port to everyone:

sh
-p 127.0.0.1:8080:8080 -p 7443:7443/udp

If the proxy runs in a container on the same Docker network, skip the HTTP port and point the proxy at moin-server:8080.

Self-contained: the guide's configuration works as is:

sh
-p 443:443/tcp -p 443:443/udp -p 7842:7842/udp

Logs ​

sh
docker logs -f moin-server

See Logs.

Upgrading ​

latest is the newest release. A version tag such as 2026.1 never changes; use one to choose when you upgrade.

sh
docker pull ghcr.io/moinchat/moin-server:latest
docker rm -f moin-server

Then start it again with the same docker run command. With Compose: docker compose pull && docker compose up -d. The data volume carries over.