This guide explains how to deploy DM Hero using Docker and GitHub Container Registry (GHCR).
- GitHub Actions builds the Docker image on every push to
main - Image is pushed to GitHub Container Registry:
ghcr.io/USERNAME/dm-hero:latest - Your server pulls the latest image periodically (e.g., every 10 minutes via cron)
- If a new image is available, the container is automatically restarted
- Docker & Docker Compose installed
- GitHub Personal Access Token (PAT) with
read:packagesscope - Port 4444 available (or configure different port)
Create a Personal Access Token:
- Go to: https://github.com/settings/tokens/new
- Scope:
read:packages - Save the token
Login on your server:
echo "YOUR_GITHUB_PAT" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdinmkdir -p /path/to/dm-hero/{data,uploads,logs}
cd /path/to/dm-heroservices:
dm-hero:
image: ghcr.io/YOUR_GITHUB_USERNAME/dm-hero:latest
container_name: dm-hero
restart: unless-stopped
ports:
- '4444:3000'
volumes:
- ./data:/app/data
- ./uploads:/app/.output/public/uploads
environment:
NODE_ENV: production
NITRO_PORT: 3000
NITRO_HOST: 0.0.0.0
healthcheck:
test: ['CMD', 'node', '-e', "require('http').get('http://localhost:3000/', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"]
interval: 30s
timeout: 10s
start_period: 40s
retries: 3docker-compose pull
docker-compose up -dCreate an update script update-app.sh:
#!/bin/bash
set -e
IMAGE="ghcr.io/YOUR_GITHUB_USERNAME/dm-hero:latest"
CONTAINER_NAME="dm-hero"
echo "[$(date)] Checking for updates..."
# Pull latest image
if docker pull "$IMAGE" 2>&1 | grep -q "Image is up to date"; then
echo "[$(date)] Already up-to-date"
exit 0
fi
echo "[$(date)] New image found, restarting..."
# Restart container
docker stop "$CONTAINER_NAME"
docker rm "$CONTAINER_NAME"
docker-compose up -d
echo "[$(date)] Update completed"Make it executable and add to crontab:
chmod +x update-app.sh
# Run every 10 minutes
crontab -e
# Add: */10 * * * * /path/to/dm-hero/update-app.sh >> /path/to/dm-hero/logs/update.log 2>&1- Database: Stored in
./data/dm-hero.db(volume-mounted) - Uploads: Stored in
./uploads/(volume-mounted) - Logs: Container logs via
docker logs dm-hero
# View logs
docker logs -f dm-hero
# Restart container
docker-compose restart
# Force update (pull latest image)
docker-compose pull && docker-compose up -d --force-recreate
# Cleanup old images
docker image prune -aThe workflow (.github/workflows/docker-build.yml) automatically:
- Builds the Docker image on push to
mainor tags - Pushes to GHCR with tags:
latest(main branch)v1.0.0(git tags)main-abc1234(commit SHA)
You can manually trigger a build via GitHub Actions UI:
- Go to Actions tab
- Select "Build and Push Docker Image"
- Click "Run workflow"
Cannot pull image:
- Check GHCR login:
docker login ghcr.io - Verify PAT has
read:packagesscope
Container won't start:
- Check logs:
docker logs dm-hero - Verify port 4444 is available
Database errors after update:
- Migrations run automatically on startup
- Check logs for migration errors
Port already in use:
- Change port in
docker-compose.yml:'ANOTHER_PORT:3000'