Self-Hosting
heaper can be self-hosted, giving you complete control over your data and infrastructure.
Prerequisites
- Docker
- Domain (recommended for TLS via a reverse proxy like Caddy or nginx)
Platform Architecture
The heaper image is built for x64 (amd64) only. On ARM devices (Raspberry Pi, Apple Silicon, etc.) you must add the platform flag to run via emulation:
Docker Compose — add platform: linux/amd64 to the service:
services:
heaper:
image: ghcr.io/janlunge/heaper:latest
platform: linux/amd64 # Required on ARM devices
container_name: heaper
# ... rest of config
Docker run — add --platform linux/amd64:
docker run -d --name heaper-selfhost --platform linux/amd64 \
-p 3010:80 \
# ... other options
ghcr.io/janlunge/heaper:latest
Note: Running amd64 on ARM uses QEMU emulation and may be slower. Ensure Docker's binfmt support is available (Docker Desktop handles this automatically).
Quick Start
Create a docker-compose.yml:
services:
heaper:
image: ghcr.io/janlunge/heaper:latest
platform: linux/amd64 # Required on ARM (Raspberry Pi, Apple Silicon)
container_name: heaper
restart: unless-stopped
mem_limit: 4g
memswap_limit: 4g
ports:
- "3010:80"
# - "5432:5432" # Uncomment to expose PostgreSQL externally
environment:
- HOSTNAME=localhost
- POSTGRES_USER=heaper
- POSTGRES_PASSWORD=change-me-please
- POSTGRES_DB=heaper
- ENABLE_INTERNAL_POSTGRES=true
volumes:
- ./heaper-data/postgres:/var/lib/postgresql/data
- ./heaper-data/data:/usr/src/app/data
- ./heaper-data/config:/usr/src/app/config
- ./heaper-data/thumbnails:/mnt/thumbnails
- ./heaper-data/storage:/mnt/storage
- ./heaper-data/backups:/mnt/backups
Change POSTGRES_PASSWORD to a secure password, then:
docker-compose up -d
Access: http://localhost:3010
For more details (docker run, environment variables, volumes) see the All-in-one setup guide.
Looking for a setup with a separate PostgreSQL container? See the Separate containers guide.
Updating
docker-compose pull
docker-compose up -d
Docker run: Pull the new image, remove the old container, then run your original docker run command again.
Backup & Restore
Automated Backups
Heaper supports automated daily database backups. Backups run automatically when the /mnt/backups volume is mounted.
| Variable | Default | Description |
|---|---|---|
BACKUP_ENCRYPTION_KEY | (optional) | Passphrase for AES-256-GCM encryption |
BACKUP_RETENTION_DAYS | 7 | Number of days to keep backups |
BACKUP_HOUR | 3 | Hour (UTC) to run daily backup (0-23) |
Docker Compose: The compose file already mounts ./heaper-data/backups:/mnt/backups. Add to the service environment to enable encrypted backups:
- BACKUP_ENCRYPTION_KEY=your-secure-passphrase
Docker run — enable automated backups:
docker run -d --name heaper-selfhost \
--volume /path/to/heaper/backups:/mnt/backups \
# ... other options
ghcr.io/janlunge/heaper:latest
Docker run — encrypted backups (recommended):
docker run -d --name heaper-selfhost \
-e BACKUP_ENCRYPTION_KEY=your-secure-passphrase \
--volume /path/to/heaper/backups:/mnt/backups \
# ... other options
ghcr.io/janlunge/heaper:latest
Backup filenames:
- Unencrypted:
heaper_backup_20240115_030000.sql - Encrypted:
heaper_backup_20240115_030000.sql.enc
Manual Database Backup
All-in-one setup (container name heaper with compose, heaper-selfhost with docker run):
docker exec heaper pg_dump -U heaper heaper > backup.sql
Separate containers setup:
docker exec heaper-selfhost-postgres pg_dump -U heaper heaper > backup.sql
Restore Database
All-in-one setup:
docker exec -i heaper psql -U heaper heaper < backup.sql
Separate containers setup:
docker exec -i heaper-selfhost-postgres psql -U heaper heaper < backup.sql
Decrypt Backup (for encrypted backups)
Encrypted backups (.sql.enc) use AES-256-GCM with the nonce prepended. To restore:
- Unencrypted backups can be restored directly with
psql - Encrypted backups must be decrypted first (key derived via SHA-256 from passphrase)
File Backup
Back up your mounted volumes regularly:
/var/lib/postgresql/data— Database files/usr/src/app/config— Configuration/mnt/thumbnails— Thumbnails/mnt/storage— User files/mnt/backups— Encrypted database backups
Troubleshooting
Check Service Health
# Check container health (use heaper for compose, heaper-selfhost for docker run)
docker inspect --format='{{.State.Health.Status}}' heaper
# Backend API health (use 3010 for compose default)
curl http://localhost:3010/api
# Sync server health
curl http://localhost:3010/sync/health
# PostgreSQL health (single container / compose)
docker exec heaper pg_isready -h localhost -U heaper
View Logs
# All logs (container name: heaper with compose, heaper-selfhost with docker run)
docker logs -f heaper
# Follow specific service logs (via supervisor)
docker exec heaper tail -f /var/log/supervisor/*.log
Connect to PostgreSQL
With Docker Compose, PostgreSQL is not exposed by default. Uncomment - "5432:5432" in the compose file to expose it. Then:
# Using psql
psql -h localhost -p 5432 -U heaper -d heaper
# Using a GUI tool (TablePlus, pgAdmin, etc.)
# Host: localhost (or your server IP)
# Port: 5432
# User: heaper
# Password: your-secure-password
# Database: heaper
Connecting to Your Server
To use your self-hosted instance in the heaper app, first login to your cloud account then add a new server via Settings → Heaps → Pull Heap and enter the IP or hostname of your server.
Note: For TLS encryption, use a reverse proxy (e.g. Caddy, nginx) in front of heaper with a valid domain and certificate.