Deploy OpenCodeHub on NAS (Synology, TrueNAS, QNAP)
Difficulty: Intermediate | Time: 30-45 minutes | Method: Docker/Container Station
Deploy OpenCodeHub on your Network Attached Storage (NAS) device. This is perfect for small teams, personal use, or as a private Git server at home. Works on Synology DSM, TrueNAS SCALE, QNAP QTS, and any NAS supporting Docker.
Recommended: the repository ships
docker-compose.nas.yml, which is
the production-safe version of every snippet below. It runs the web app,
the SSH Git server, and the background worker as separate
containers, requires secrets instead of defaulting them, and binds every
data directory to one host path (OCH_DATA_DIR, default/mnt/och) —
perfect for a dedicated hard disk or NAS share:cp .env.example .env # then fill in ALL secrets OCH_DATA_DIR=/volume1/opencodehub docker compose -f docker-compose.nas.yml up -dThe inline YAML in this guide is a minimal reference. Note that the web
app container does not run SSH Git — if you use a snippet as-is, port
2222 will not serve SSH. Add thessh-gitservice (or usedocker-compose.nas.yml) for SSH access.
Prerequisites
| NAS Type | Minimum Requirements |
|---|---|
| Synology | DSM 7.0+, 4GB RAM (8GB recommended), x86_64 or ARM64 (better performance on x86_64) |
| TrueNAS SCALE | 8GB RAM, 2 CPU cores, 40GB free space |
| QNAP | QTS 5.0+, 4GB RAM, Container Station installed |
| Generic | Docker/Podman support, 4GB RAM, 2 CPU cores |
- A domain with DDNS (Dynamic DNS) configured (e.g.,
git.yourddns.net) OR local network access only - Port forwarding configured on your router (if accessing externally):
80→ NAS:80443→ NAS:4432222→ NAS:2222 (for SSH Git, optional)
Part 1: Synology DSM Deployment
Step 1.1: Install Container Manager
- Open Package Center
- Search for Container Manager (DSM 7.2+) or Docker (older DSM)
- Click Install
Step 1.2: Create Shared Folders
Open Control Panel → Shared Folder → Create
Create these folders:
opencodehub/repos— Git repositoriesopencodehub/storage— File uploadsopencodehub/ssh— SSH host keysopencodehub/cache— Application cacheopencodehub/postgres— PostgreSQL dataopencodehub/redis— Redis data
Set permissions:
- Right-click each folder → Edit → Permissions
- Grant Read/Write to your admin user and the
Dockersystem group
Step 1.3: Set Up PostgreSQL
Using Container Manager GUI:
Open Container Manager → Image → Add → Add from URL
Image name:
postgresTag:
16-alpineClick Add
Go to Container → Create
Select
postgres:16-alpineConfiguration:
- Container name:
opencodehub-postgres - Enable auto-restart: Yes
- Network: Use the same bridge network as other containers
- Environment variables:
POSTGRES_USER=opencodehub POSTGRES_PASSWORD=<generate-strong-password> POSTGRES_DB=opencodehub - Volume settings:
/volume1/opencodehub/postgres → /var/lib/postgresql/data - Port settings:
Local port: 5432 → Container port: 5432
- Container name:
Click Done
Using SSH (Alternative):
ssh admin@your-synology-ip
sudo -i
docker run -d \
--name opencodehub-postgres \
--restart unless-stopped \
-e POSTGRES_USER=opencodehub \
-e POSTGRES_PASSWORD=YOUR_PASSWORD \
-e POSTGRES_DB=opencodehub \
-v /volume1/opencodehub/postgres:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:16-alpine
Step 1.4: Set Up Redis
Using Container Manager:
- Pull
redis:7-alpine - Create container:
- Name:
opencodehub-redis - Environment:
REDIS_PASSWORD=<strong-password> - Command:
redis-server --appendonly yes --requirepass YOUR_PASSWORD - Volume:
/volume1/opencodehub/redis → /data - Port:
6379→6379
- Name:
Or via SSH:
docker run -d \
--name opencodehub-redis \
--restart unless-stopped \
-v /volume1/opencodehub/redis:/data \
-p 6379:6379 \
redis:7-alpine \
redis-server --appendonly yes --requirepass YOUR_PASSWORD
Step 1.5: Deploy OpenCodeHub
Option A: Pre-built Image (Fastest)
If using the published Docker image:
docker run -d \
--name opencodehub \
--restart unless-stopped \
--link opencodehub-postgres:postgres \
--link opencodehub-redis:redis \
-p 4321:4321 \
-e NODE_ENV=production \
-e DATABASE_URL=postgresql://opencodehub:[email protected]:5432/opencodehub \
-e REDIS_URL=redis://:[email protected]:6379 \
-e JWT_SECRET=$(openssl rand -hex 32) \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e INTERNAL_HOOK_SECRET=$(openssl rand -hex 32) \
-e CRON_SECRET=$(openssl rand -hex 32) \
-e RUNNER_SECRET=$(openssl rand -hex 32) \
-e WORKFLOW_SECRET_ENCRYPTION_KEY=$(openssl rand -hex 32) \
-e AI_CONFIG_ENCRYPTION_KEY=$(openssl rand -hex 32) \
-e SITE_URL=https://git.yourddns.net \
-e STORAGE_TYPE=local \
-e STORAGE_PATH=/data/storage \
-e GIT_REPOS_PATH=/data/repos \
-e GIT_SSH_HOST_KEY=/data/ssh/host_key \
-v /volume1/opencodehub/repos:/data/repos \
-v /volume1/opencodehub/storage:/data/storage \
-v /volume1/opencodehub/ssh:/data/ssh \
-v /volume1/opencodehub/cache:/data/cache \
opencodehub/opencodehub:latest
Note: On Synology,
host.docker.internalmay not work. Use your NAS IP address instead (e.g.,192.168.1.100).SSH Git: the app container serves the web UI only. For SSH access,
run a second container from the same image withPROCESS_TYPE=sshand
expose port 2222 (this is exactly whatdocker-compose.nas.ymldoes).
Option B: Build from Source
- In Container Manager → Project (Docker Compose):
version: '3.8'
services:
app:
build:
context: /volume1/docker/OpenCodeHub
dockerfile: Dockerfile
container_name: opencodehub
restart: unless-stopped
ports:
- "4321:4321"
environment:
- NODE_ENV=production
- PROCESS_TYPE=app
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- SESSION_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- CRON_SECRET=YOUR_SECRET
- RUNNER_SECRET=YOUR_SECRET
- WORKFLOW_SECRET_ENCRYPTION_KEY=YOUR_SECRET
- AI_CONFIG_ENCRYPTION_KEY=YOUR_SECRET
- SITE_URL=https://git.yourddns.net
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- /volume1/opencodehub/repos:/data/repos
- /volume1/opencodehub/storage:/data/storage
- /volume1/opencodehub/ssh:/data/ssh
- /volume1/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
ssh-git:
build:
context: /volume1/docker/OpenCodeHub
dockerfile: Dockerfile
container_name: opencodehub-ssh
restart: unless-stopped
ports:
- "2222:2222"
environment:
- NODE_ENV=production
- PROCESS_TYPE=ssh
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- /volume1/opencodehub/repos:/data/repos
- /volume1/opencodehub/storage:/data/storage
- /volume1/opencodehub/ssh:/data/ssh
- /volume1/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
worker:
build:
context: /volume1/docker/OpenCodeHub
dockerfile: Dockerfile
container_name: opencodehub-worker
restart: unless-stopped
environment:
- NODE_ENV=production
- PROCESS_TYPE=worker
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
volumes:
- /volume1/opencodehub/repos:/data/repos
- /volume1/opencodehub/storage:/data/storage
- /volume1/opencodehub/ssh:/data/ssh
- /volume1/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
postgres:
image: postgres:16-alpine
container_name: opencodehub-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=opencodehub
- POSTGRES_PASSWORD=YOUR_PASS
- POSTGRES_DB=opencodehub
volumes:
- /volume1/opencodehub/postgres:/var/lib/postgresql/data
networks:
- och-net
redis:
image: redis:7-alpine
container_name: opencodehub-redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass YOUR_PASS
volumes:
- /volume1/opencodehub/redis:/data
networks:
- och-net
networks:
och-net:
driver: bridge
- Save this as
docker-compose.ymlin/volume1/docker/OpenCodeHub/ - Clone the repo to that folder first:
cd /volume1/docker git clone https://github.com/swadhinbiswas/OpencodeHub.git - In Container Manager → Project → Create
- Select the path
/volume1/docker/OpenCodeHub - Click Create
Step 1.6: Configure Reverse Proxy (Synology)
- Control Panel → Login Portal → Advanced → Reverse Proxy
- Click Create
- General:
- Source:
- Protocol: HTTPS
- Hostname:
git.yourddns.net - Port: 443
- Destination:
- Protocol: HTTP
- Hostname:
localhost - Port: 4321
- Source:
- Custom Header → Create → WebSocket
- Header name:
Upgrade - Value:
$http_upgrade - Header name:
Connection - Value:
upgrade
- Header name:
- Click Save
Step 1.7: SSL Certificate (Let's Encrypt)
Control Panel → Security → Certificate
Click Add → Add a new certificate
Select Get a certificate from Let's Encrypt
Domain name:
git.yourddns.netEmail: [email protected]
Click Apply
After issuance, go to Configure and assign the certificate to:
git.yourddns.net:443(your reverse proxy)
Part 2: TrueNAS SCALE Deployment
TrueNAS SCALE has native Kubernetes support with Helm charts, but Docker is easier via Apps (Docker Compose).
Step 2.1: Create Datasets
- Go to Storage → Pools → Your pool → Add Dataset
- Create a parent dataset:
opencodehub - Under it, create:
reposstoragesshcachepostgresredis
Step 2.2: Deploy via Custom App (Docker Compose)
- Go to Apps → Discover Apps → Custom App
- Enable Advanced Mode
- Enter this Docker Compose:
version: '3.8'
services:
app:
image: opencodehub/opencodehub:latest
container_name: opencodehub
restart: unless-stopped
ports:
- "4321:4321"
environment:
- NODE_ENV=production
- PROCESS_TYPE=app
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- SESSION_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- CRON_SECRET=YOUR_SECRET
- RUNNER_SECRET=YOUR_SECRET
- WORKFLOW_SECRET_ENCRYPTION_KEY=YOUR_SECRET
- AI_CONFIG_ENCRYPTION_KEY=YOUR_SECRET
- SITE_URL=https://git.yourdomain.com
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- /mnt/YOURPOOL/opencodehub/repos:/data/repos
- /mnt/YOURPOOL/opencodehub/storage:/data/storage
- /mnt/YOURPOOL/opencodehub/ssh:/data/ssh
- /mnt/YOURPOOL/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
ssh-git:
image: opencodehub/opencodehub:latest
container_name: opencodehub-ssh
restart: unless-stopped
ports:
- "2222:2222"
environment:
- NODE_ENV=production
- PROCESS_TYPE=ssh
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- /mnt/YOURPOOL/opencodehub/repos:/data/repos
- /mnt/YOURPOOL/opencodehub/storage:/data/storage
- /mnt/YOURPOOL/opencodehub/ssh:/data/ssh
- /mnt/YOURPOOL/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
worker:
image: opencodehub/opencodehub:latest
container_name: opencodehub-worker
restart: unless-stopped
environment:
- NODE_ENV=production
- PROCESS_TYPE=worker
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
volumes:
- /mnt/YOURPOOL/opencodehub/repos:/data/repos
- /mnt/YOURPOOL/opencodehub/storage:/data/storage
- /mnt/YOURPOOL/opencodehub/ssh:/data/ssh
- /mnt/YOURPOOL/opencodehub/cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
postgres:
image: postgres:16-alpine
container_name: opencodehub-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=opencodehub
- POSTGRES_PASSWORD=YOUR_PASS
- POSTGRES_DB=opencodehub
volumes:
- /mnt/YOURPOOL/opencodehub/postgres:/var/lib/postgresql/data
networks:
- och-net
redis:
image: redis:7-alpine
container_name: opencodehub-redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass YOUR_PASS
volumes:
- /mnt/YOURPOOL/opencodehub/redis:/data
networks:
- och-net
networks:
och-net:
driver: bridge
Replace
YOURPOOLwith your actual pool name andYOUR_PASS/YOUR_SECRETwith your values.
- Click Save
- TrueNAS will deploy all containers
Step 2.3: Configure TrueNAS Certificate
- System → General → GUI SSL Certificate
- Or use Apps → Certificates for app-specific SSL
- For external access, use TrueNAS's built-in ACME (Let's Encrypt) or upload your own certificate
Step 2.4: Reverse Proxy with Nginx Proxy Manager (Recommended)
Install Nginx Proxy Manager from the TrueNAS Apps catalog:
- Apps → Discover Apps → Search "Nginx Proxy Manager"
- Install with default settings
- Access Nginx Proxy Manager at
your-nas-ip:81 - Add Proxy Host:
- Domain Names:
git.yourdomain.com - Forward Hostname/IP:
opencodehub - Forward Port:
4321 - Enable Block Common Exploits
- SSL: Request a new SSL certificate from Let's Encrypt
- Enable Force SSL and HTTP/2 Support
- Domain Names:
Part 3: QNAP QTS Deployment
Step 3.1: Install Container Station
- Open App Center
- Search for Container Station
- Click Install
Step 3.2: Create Folders
- Open File Station
- Create folder:
opencodehub - Inside it create:
repos,storage,ssh,cache,postgres,redis
Step 3.3: Deploy via Container Station
Create Network:
- Container Station → Networks → Create
- Name:
opencodehub-network - Driver: Bridge
Create PostgreSQL:
- Create → Search Docker Hub →
postgres:16-alpine - Click Install
- Configuration:
- Name:
opencodehub-postgres - Network:
opencodehub-network - Environment:
POSTGRES_USER=opencodehub POSTGRES_PASSWORD=<password> POSTGRES_DB=opencodehub - Shared Folders:
/share/Container/opencodehub/postgres → /var/lib/postgresql/data - Port:
5432
- Name:
Create Redis:
- Search and install
redis:7-alpine - Name:
opencodehub-redis - Network:
opencodehub-network - Command:
redis-server --appendonly yes --requirepass YOUR_PASS - Shared Folders:
/share/Container/opencodehub/redis → /data
Create OpenCodeHub:
- Search and install
opencodehub/opencodehub:latest - Name:
opencodehub - Network:
opencodehub-network - Environment variables (same as Synology example)
- Shared Folders:
/share/Container/opencodehub/repos → /data/repos /share/Container/opencodehub/storage → /data/storage /share/Container/opencodehub/ssh → /data/ssh /share/Container/opencodehub/cache → /data/cache - Ports:
4321,2222
Step 3.4: QNAP Reverse Proxy
- Control Panel → System → Reverse Proxy
- Click Create
- Rule:
- Name:
OpenCodeHub - Source Protocol: HTTPS
- Source URL:
git.yourdomain.com - Port: 443
- Destination Protocol: HTTP
- Destination URL:
localhost - Port: 4321
- Name:
- Enable HSTS
Step 3.5: SSL Certificate
- Control Panel → Security → Certificate & Private Key
- Click Replace Certificate
- Choose Get from Let's Encrypt
- Enter your domain and email
- Click Apply
Part 4: Generic NAS / Any Docker Host
If your NAS supports Docker (via Portainer, Podman, or CLI):
Using Docker Compose:
# Create directories
mkdir -p ~/opencodehub/{repos,storage,ssh,cache,postgres,redis}
# Create docker-compose.yml
cat > ~/opencodehub/docker-compose.yml << 'EOF'
version: '3.8'
services:
app:
image: opencodehub/opencodehub:latest
container_name: opencodehub
restart: unless-stopped
ports:
- "4321:4321"
environment:
- NODE_ENV=production
- PROCESS_TYPE=app
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- SESSION_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- CRON_SECRET=YOUR_SECRET
- RUNNER_SECRET=YOUR_SECRET
- WORKFLOW_SECRET_ENCRYPTION_KEY=YOUR_SECRET
- AI_CONFIG_ENCRYPTION_KEY=YOUR_SECRET
- SITE_URL=https://git.yourdomain.com
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- ./repos:/data/repos
- ./storage:/data/storage
- ./ssh:/data/ssh
- ./cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
ssh-git:
image: opencodehub/opencodehub:latest
container_name: opencodehub-ssh
restart: unless-stopped
ports:
- "2222:2222"
environment:
- NODE_ENV=production
- PROCESS_TYPE=ssh
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- GIT_SSH_HOST_KEY=/data/ssh/host_key
- GIT_SSH_PORT=2222
volumes:
- ./repos:/data/repos
- ./storage:/data/storage
- ./ssh:/data/ssh
- ./cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
worker:
image: opencodehub/opencodehub:latest
container_name: opencodehub-worker
restart: unless-stopped
environment:
- NODE_ENV=production
- PROCESS_TYPE=worker
- DATABASE_URL=postgresql://opencodehub:YOUR_PASS@postgres:5432/opencodehub
- REDIS_URL=redis://:YOUR_PASS@redis:6379
- JWT_SECRET=YOUR_SECRET
- INTERNAL_HOOK_SECRET=YOUR_SECRET
- GIT_REPOS_PATH=/data/repos
- REPOS_PATH=/data/repos
- STORAGE_TYPE=local
- STORAGE_PATH=/data/storage
volumes:
- ./repos:/data/repos
- ./storage:/data/storage
- ./ssh:/data/ssh
- ./cache:/data/cache
depends_on:
- postgres
- redis
networks:
- och-net
postgres:
image: postgres:16-alpine
container_name: opencodehub-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=opencodehub
- POSTGRES_PASSWORD=YOUR_PASS
- POSTGRES_DB=opencodehub
volumes:
- ./postgres:/var/lib/postgresql/data
networks:
- och-net
redis:
image: redis:7-alpine
container_name: opencodehub-redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass YOUR_PASS
volumes:
- ./redis:/data
networks:
- och-net
networks:
och-net:
driver: bridge
EOF
# Deploy
cd ~/opencodehub
docker-compose up -d
Step 5: Router Port Forwarding
For external access, forward these ports on your router:
| External Port | Internal IP | Internal Port | Purpose |
|---|---|---|---|
| 80 | Your NAS IP | 80 | HTTP (for Let's Encrypt/redirect) |
| 443 | Your NAS IP | 443 | HTTPS (OpenCodeHub web) |
| 2222 | Your NAS IP | 2222 | SSH Git (optional) |
Security Note: If using a reverse proxy, you only need to forward 80 and 443. Port 4321 should NOT be exposed externally.
Step 6: Dynamic DNS (DDNS)
If you don't have a static IP:
Synology:
- Control Panel → External Access → DDNS
- Click Add
- Service Provider: Synology, No-IP, DuckDNS, etc.
- Enter hostname:
git.yourddns.net - Click Test Connection → OK
TrueNAS:
- Network → Global Configuration → Nameservers
- Use Cloudflare or your DNS provider's API for dynamic updates
- Or install a DDNS client as a custom app
QNAP:
- Control Panel → Network & File Services → DDNS
- Click Add
- Select provider and configure
Router DDNS:
Most routers (UniFi, ASUS, TP-Link) have built-in DDNS. Configure it to update git.yourddns.net automatically.
Step 7: Create Admin User
# Synology/QNAP/Generic
ssh admin@your-nas-ip
docker exec -it opencodehub bun run scripts/seed-admin.ts
# TrueNAS
kubectl exec -it deployment/opencodehub -- bun run scripts/seed-admin.ts
Enter username, email, and password.
Step 8: Initial Setup & Verification
- Visit
https://git.yourddns.net(or your domain) - Log in with admin credentials
- Create your first organization
- Test Git over HTTPS:
git clone https://git.yourddns.net/admin/test-repo.git
Maintenance
Update OpenCodeHub
cd ~/opencodehub # or /volume1/docker/OpenCodeHub, etc.
docker-compose pull
docker-compose up -d
Backup Strategy
Automated Backup (Synology):
- Hyper Backup → Create → Local/Remote
- Select
opencodehubshared folder - Schedule: Daily at 2 AM
- Retention: Keep last 7 versions
Manual Backup:
# Backup script
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/path/to/backups"
# Database
docker exec opencodehub-postgres pg_dump -U opencodehub opencodehub | gzip > $BACKUP_DIR/och-db-$DATE.sql.gz
# Files
tar czf $BACKUP_DIR/och-files-$DATE.tar.gz /path/to/opencodehub/repos /path/to/opencodehub/storage
# Keep only last 7 days
find $BACKUP_DIR -name "och-*" -mtime +7 -delete
Monitor Resources
| NAS | Monitoring Tool |
|---|---|
| Synology | Resource Monitor widget |
| TrueNAS | Reporting → CPU/Memory/Disk |
| QNAP | Resource Monitor in Dashboard |
OpenCodeHub on NAS typically uses:
- RAM: 1-2GB idle, 2-4GB under load
- CPU: 10-30% during normal use
- Disk: Grows with repos and uploads
Troubleshooting
| Problem | Solution |
|---|---|
| Container won't start | Check logs: docker logs opencodehub. Often a database connection issue. |
| "host.docker.internal" not found | Use your NAS's LAN IP (e.g., 192.168.1.100) instead of host.docker.internal. |
| Permission denied on volumes | Ensure the Docker user has read/write access to the shared folders. On Synology, set permissions for the Docker group. |
| Slow performance | NAS devices often have slow CPUs. Ensure you have at least 4GB RAM. Consider using SSD for the postgres volume. |
| SSL certificate errors | Ensure your domain resolves correctly. Check DDNS is updating your IP. |
| Git SSH not connecting | Port 2222 must be forwarded on router. Some ISPs block port 22/2222. Try a different high port (e.g., 8022). |
| Database corruption after power loss | PostgreSQL with default settings can corrupt on unclean shutdown. Use a UPS. For extra safety, add fsync=on to PostgreSQL config. |
| Out of memory | Synology/QNAP with 2GB RAM will struggle. Close unused packages. Add a swap file if needed. |
NAS-Specific Tips
Synology
- Enable Snapshot Replication for instant recovery
- Use SSO Client if you want to integrate with existing domain auth
- Consider Virtual Machine Manager if you need more isolation
TrueNAS SCALE
- Use Apps instead of VMs for better resource efficiency
- Enable Automatic container updates in TrueNAS settings
- Consider TrueCharts catalog for additional apps
QNAP
- Use QuTS hero (ZFS) for better data integrity
- Enable ** snapshots** for the opencodehub dataset
- QVPN can secure remote access without exposing ports
Next Steps
- Configure Email (SMTP)
- Set up Offsite Storage (S3/R2) — highly recommended for NAS (protects against drive failure)
- Enable Branch Protection
- Set up your First Stack