GGlyphDocs

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 hostRequiredNot needed
Image sourceBuilt locally on the hostPulled from Docker Hub
Build time2-5 minutesNone (just pull)
Disk usageSource tree + build artifactsJust the image
Update methodgit pull && docker compose builddocker 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

MinimumRecommended
CPU1 core2+ cores
RAM2 GB4 GB+
Disk5 GB20 GB+ (depends on imported repos)
OSLinux 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 docker

Verify:

docker compose version

2. Create the deployment directory

mkdir -p /opt/glyph && cd /opt/glyph

3. 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 .env

4. 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.com

5. Pull and start

docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

The first start runs migrations automatically. Allow 1-2 minutes for everything to become healthy.

6. Verify

docker compose -f docker-compose.prod.yml ps

All 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:

ContainerCheck
dbmysqladmin ping every 10s
meilisearchHTTP /health every 10s
backendHTTP /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 service

Stopping

docker compose -f docker-compose.prod.yml down       # stop containers
docker compose -f docker-compose.prod.yml down -v    # also remove volumes (DESTRUCTIVE)

Next