Self-hosted Dify deployment on Hetzner using Docker Compose.
This repo contains everything you need to deploy Dify on a Hetzner VPS. It uses the official Dify Docker Compose setup with an nginx reverse proxy and optional SSL via Certbot.
- Hetzner VPS: CX22 or larger (2 vCPU, 4 GB RAM minimum — 4 GB RAM / 8 GB recommended for production)
-
- Ubuntu 22.04 or 24.04
-
-
A domain pointed at your server's IP (for SSL)
-
Create a CX22 (or larger) server in the Hetzner Cloud Console with Ubuntu 22.04. Add your SSH key during creation.
-
ssh root@YOUR_SERVER_IP bash <(curl -fsSL https://raw.githubusercontent.com/pxdogbo/opennode/main/setup.sh)This installs Docker, Docker Compose, clones this repo to
/opt/opennode, and sets everything up.cd /opt/opennode cp .env.example .env nano .env # fill in your domain, secret keys, etc.
Key variables to set:
Variable Description DOMAINYour domain name (e.g. dify.example.com)SECRET_KEYRandom secret — run openssl rand -hex 32DB_PASSWORDStrong password for PostgreSQL REDIS_PASSWORDStrong password for Redis docker compose up -d
# Certbot is included in the compose file docker compose run --rm certbot certonly --webroot \ --webroot-path /var/www/certbot \ -d YOUR_DOMAIN --email YOUR_EMAIL --agree-tosThen uncomment the HTTPS server block in
nginx/conf.d/default.confand restart nginx:docker compose restart nginx
cd /opt/opennode git pull docker compose pull docker compose up -d # Optional: sync new .env variables bash dify-env-sync.sh
opennode/ ├── docker-compose.yml # Main compose file ├── .env.example # All configurable variables ├── .env # Your local config (gitignored) ├── nginx/ │ └── conf.d/ │ └── default.conf # nginx reverse proxy config ├── dify-env-sync.sh # Helper to sync .env with upstream └── setup.sh # Server bootstrap scriptUse Case Server RAM Cost Personal / testing CX22 4 GB ~€4/mo Small team CX32 8 GB ~€8/mo Production CX42 16 GB ~€17/mo All persistent data lives in Docker named volumes. To back up:
# Backup Postgres docker compose exec db pg_dump -U postgres dify > dify_backup_$(date +%Y%m%d).sql # Backup all volumes (more thorough) docker run --rm -v opennode_db_data:/data -v $(pwd):/backup \ ubuntu tar czf /backup/db_data_$(date +%Y%m%d).tar.gz /data
- Containers not starting: check logs with
docker compose logs -f -
- Out of memory: upgrade your Hetzner server or disable unused vector DB services in
.env -
- SSL not working: make sure ports 80 and 443 are open in Hetzner Firewall rules
- Out of memory: upgrade your Hetzner server or disable unused vector DB services in
- Containers not starting: check logs with
-