deployment
Production with Docker
Deploy Glyph using pre-built images from GitHub Container Registry.
The recommended way to run Glyph in production is with docker-compose.prod.yml - it pulls multi-architecture images from Docker Hub instead of building from source.
The published images are:
A mirror is also published to GitHub Container Registry (ghcr.io/r-seize/glyph-backend and ghcr.io/r-seize/glyph-frontend) if you prefer it.
Why prod is different from dev
docker-compose.yml (dev) | docker-compose.prod.yml (prod) | |
|---|---|---|
| Source code on host | Required | Not needed |
| Image source | Built locally on the host | Pulled from Docker Hub |
| Build time | 2-5 minutes | None (just pull) |
| Disk usage | Source tree + build artifacts | Just the image |
| Update method | git pull && docker compose build | docker compose pull |
Multi-architecture support
Images are built for linux/amd64 and linux/arm64. Docker automatically pulls the right one based on your host's architecture, so the same compose file works on:
- Linux on Intel / AMD servers
- macOS on Apple Silicon
- Raspberry Pi 4 / 5
- AWS Graviton, Oracle ARM instances
Server requirements
| Minimum | Recommended | |
|---|---|---|
| CPU | 1 core | 2+ cores |
| RAM | 2 GB | 4 GB+ |
| Disk | 5 GB | 20 GB+ (depends on imported repos) |
| OS | Linux with Docker Engine 24+ | Ubuntu 22.04 / Debian 12 |
Step-by-step deployment
1. Install Docker
On the server:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp dockerVerify:
docker compose version2. Create the deployment directory
mkdir -p /opt/glyph && cd /opt/glyph3. Download the compose file and template env
curl -O https://raw.githubusercontent.com/r-seize/Glyph/main/docker-compose.prod.yml
curl -O https://raw.githubusercontent.com/r-seize/Glyph/main/.env.example
cp .env.example .env4. Configure .env
Edit .env and set production values. At minimum:
MYSQL_ROOT_PASSWORD=<strong random>
MYSQL_PASSWORD=<strong random>
SECRET_KEY=<output of `openssl rand -hex 32`>
MEILISEARCH_KEY=<strong random>
# Adjust to your public URLs (after setting up HTTPS, see Reverse Proxy doc)
FRONTEND_URL=https://glyph.example.com
NEXT_PUBLIC_API_URL=https://api.glyph.example.com
APP_URL=https://api.glyph.example.com
CORS_ORIGINS=https://glyph.example.com5. Pull and start
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -dThe first start runs migrations automatically. Allow 1-2 minutes for everything to become healthy.
6. Verify
docker compose -f docker-compose.prod.yml psAll four containers should show healthy. Open the frontend in a browser at port 3000 (or your public URL if reverse-proxied).
Health checks
Each container has a built-in healthcheck:
| Container | Check |
|---|---|
db | mysqladmin ping every 10s |
meilisearch | HTTP /health every 10s |
backend | HTTP /health every 15s |
frontend | (no healthcheck - the depends_on is enough) |
The backend depends_on: db, meilisearch with condition: service_healthy ensures correct startup order.
Logs
docker compose -f docker-compose.prod.yml logs -f
docker compose -f docker-compose.prod.yml logs -f backend # one serviceStopping
docker compose -f docker-compose.prod.yml down # stop containers
docker compose -f docker-compose.prod.yml down -v # also remove volumes (DESTRUCTIVE)Next
- Reverse Proxy & SSL - put Glyph behind nginx or Caddy with HTTPS
- Backups - automate database and volume backups
- Updating - pull the latest image and restart