This document covers running OSWatcher on a server and updating it afterwards. The same
production overlay (compose.prod.yml) runs locally or on a server; the difference is entirely
in .env. The committed .env selects the overlay for plain docker compose commands;
explicit -f commands also work with older .env files.
The Quickstart runs the same images with localhost defaults. To
expose an instance, edit .env:
| Variable | Server value |
|---|---|
DOMAIN |
your domain; Traefik routes DOMAIN, api.DOMAIN and storage.DOMAIN |
HTTP_SCHEME |
https |
BIND_ADDRESS |
the interface you intend to expose (applies to all published ports, database and storage included) |
MINIO_ROOT_USER / MINIO_ROOT_PASSWORD |
non-default credentials (the production overlay refuses to start with the default password) |
NEO4J_AUTH |
neo4j/<strong-password>, and set NEO4J_USER / NEO4J_PASSWORD to match |
NEO4J_HEAP_INITIAL_SIZE, NEO4J_HEAP_MAX_SIZE, NEO4J_PAGECACHE_SIZE |
size for your corpus; the committed values suit local evaluation only |
SEED_DB |
false if you will restore your own backup or build your own corpus; leave true to bootstrap the server from the published dump on first up -d |
Then:
- Point DNS for
DOMAIN,api.DOMAINandstorage.DOMAINat the server. - Provision a trusted TLS certificate. Certificate issuance is not automated by this repository; without one, Traefik serves its default self-signed certificate.
- Restrict the database and storage ports through your firewall.
BIND_ADDRESSalone is not a substitute when the proxy is public.
docker compose up -dIf an existing .env does not set COMPOSE_FILE, use the explicit equivalent:
docker compose -f compose.yml -f compose.prod.yml up -dBefore deploying an update, ensure:
- You have SSH access to your production server
- The deployment directory contains this repository (
oswatcher) with a configured.env - The API Docker image has been built and pushed to GHCR (via CI/CD)
ssh <your-server>cd ~/oswatcherdocker compose -f compose.yml -f compose.prod.yml up -d --force-recreate apiWhat this does:
compose.yml- Base configurationcompose.prod.yml- Production overridesup -d- Start containers in detached mode--force-recreate- Force recreation even if configuration hasn't changedapi- Target only the API service (leaves Neo4j running)
Note: The OSWatcher images on GHCR are public and can be pulled anonymously. If you are deploying images from a private registry, authenticate first with docker login ghcr.io using a PAT with read:packages scope.
# Check container status
docker compose ps
# View API logs
docker compose logs -f api
# Test API health endpoint (if available)
curl http://localhost:4000/healthThe frontend uses the public ghcr.io/oswatcher/frontend:latest image. Its entrypoint applies
VITE_OSWATCHER_API_URI at container start, using <HTTP_SCHEME>://api.<DOMAIN> from the production configuration (HTTPS if unset).
docker compose -f compose.yml -f compose.prod.yml up -d --pull always frontend--pull always fetches the latest published image before recreating the frontend.
If the deployment fails or introduces issues:
# View available image tags
docker images ghcr.io/oswatcher/graphql-api
# Rollback to previous version
docker compose -f compose.yml -f compose.prod.yml down api
# Edit compose.prod.yml to specify previous image tag
docker compose -f compose.yml -f compose.prod.yml up -d apiProblem: "Error response from daemon: pull access denied"
Solution:
- Verify the image exists on GitHub Container Registry
- Check image visibility (public vs private)
- For private images, ensure you're authenticated:
docker login ghcr.io
Problem: Container exits immediately after up
Solution:
# Check logs for error messages
docker compose logs api
# Common issues:
# - Database connection failure (check Neo4j is running)
# - Environment variable misconfiguration (check .env)
# - Port conflicts (check port 4000 availability)Problem: API can't connect to Neo4j
Solution:
# Verify Neo4j is running
docker compose ps neo4j
# Check Neo4j logs
docker compose logs neo4j
# Test Neo4j connectivity
docker compose exec api nc -zv neo4j 7687-
Always test in development first:
docker compose -f compose.yml -f compose.dev.yml up --build
-
Monitor logs during deployment:
docker compose logs -f api
-
Use specific image tags (not
latest):- Edit
compose.prod.ymlto pin versions - Example:
ghcr.io/oswatcher/graphql-api:v1.2.3
- Edit
-
Backup before major updates:
- See
scripts/neo4j-backup.shandscripts/minio-backup.sh
- See