Skip to content

Server setup (Docker Compose)

The backend + filebrowser + nginx (with frontend) can be deployed with one docker-compose.yml.

Requirements

  • A Linux server with a public IP address
  • A domain name
  • Docker + Docker Compose plugin installed

Quickstart

  1. Download docker-compose.yml and .env.example from the repository.
bash
mkdir potato-launcher-backend
cd potato-launcher-backend
wget https://raw.githubusercontent.com/Petr1Furious/potato-launcher/refs/heads/master/docker-compose.yml
wget -O .env https://raw.githubusercontent.com/Petr1Furious/potato-launcher/refs/heads/master/.env.example
  1. Edit .env and set at least:
  • ADMIN_JWT_SECRET: JWT signing secret (generate with openssl rand -base64 48)
  • ADMIN_SECRET_TOKEN: admin “password” used to log in (pick a long random password)
  • DOWNLOAD_SERVER_BASE: public URL where your server will host generated instance files (usually https://<your-domain>/data)

Other useful variables from .env.example:

  • REPLACE_DOWNLOAD_URLS: if true, instance builds serve libraries and assets from your server instead of Mojang/upstream URLs. Can also be toggled later in the admin Settings page. Default: false
  • RESOURCES_URL_BASE: optional override for the assets base URL passed to the builder
  • VITE_GITHUB_URL: repository link shown on the public downloads page
  • PORT: host port nginx listens on. Default: 8000
  • PUID / PGID: user/group IDs for container file ownership. Default: 1000
  • CONTAINER_NAME_PREFIX: prefix for Docker container names. Default: potato-launcher
  1. Start the setup:
bash
docker compose up -d
  1. Setup a reverse proxy.
  • By default, nginx is exposed on port 8000 on the host (see docker-compose.yml). You can change PORT to any other value.
  • Choose any reverse proxy and setup TLS certificates. A couple of common options: Caddy, Traefik (both with automatic Let’s Encrypt) and nginx + Certbot (more manual approach).
  • Point the proxy at http://127.0.0.1:8000 (or whatever PORT you chose). The URLs below assume you access the site through the proxy on standard HTTPS, without the port in the URL.

What gets served where

When the setup is up:

  • Downloads page: https://<your-domain>/
  • Backend API: https://<your-domain>/api/v1/
  • API docs: https://<your-domain>/api/v1/docs
  • Generated instances & metadata: https://<your-domain>/data/
  • Admin panel: https://<your-domain>/admin/ (requires login)
  • Filebrowser (uploaded instance files): https://<your-domain>/filebrowser/ (requires login)

Logging in

Open https://<your-domain>/admin and log in using your ADMIN_SECRET_TOKEN.

Persistent data / backups

All persistent state lives under ./state/ by default:

  • state/internal: instances spec + uploaded instances storage
  • state/generated: generated output served under /data
  • state/workdir: builder working directory (can be thought of as a cache for the builder)
  • state/launcher: uploaded launcher artifacts
  • state/filebrowser-db: Filebrowser database

Back up the whole state/ directory.

WARNING

Do not share ADMIN_SECRET_TOKEN or ADMIN_JWT_SECRET. Anyone with the admin token can log in and upload/modify instances and launchers.