docs/docs/en/get-started/installation/docker-nginx.mdx
In this setup, the NocoBase app container and the Nginx container run separately. You can start with Docker Installation (Built-in Nginx) and then switch the entry service to an external Nginx container.
If you need the full image, replace latest-no-nginx with latest-full-no-nginx.
The 13000:80 mapping is only for convenient local testing, so it does not occupy the standard host ports directly. In production, you usually do not keep using 13000:80; instead, let the external Nginx container map directly to the host 80 and 443 ports.
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:latest-no-nginx
restart: always
depends_on:
- postgres
networks:
- nocobase
environment:
- APP_KEY=your-secret-key
- DB_DIALECT=postgres
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=nocobase
- DB_USER=nocobase
- DB_PASSWORD=nocobase
- TZ=Etc/UTC
- NOCOBASE_EXTRACT_CLIENT_ASSETS=true
- NOCOBASE_PROXY_PROVIDER=nginx
- NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage
- NOCOBASE_PROXY_UPSTREAM_HOST=app
volumes:
- ./storage:/app/nocobase/storage
nginx:
image: nginx:latest
restart: always
depends_on:
- app
networks:
- nocobase
volumes:
- ./storage:/app/nocobase/storage
command: >
/bin/sh -c '
while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do
echo "waiting for nocobase.conf..."
sleep 1
done
rm -f /etc/nginx/conf.d/default.conf
ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf
nginx -g "daemon off;"
'
ports:
# This is only a local testing example.
- "13000:80"
# In production, usually change it to:
# - "80:80"
# - "443:443"
postgres:
image: postgres:16
restart: always
command: postgres -c wal_level=logical
environment:
POSTGRES_USER: nocobase
POSTGRES_DB: nocobase
POSTGRES_PASSWORD: nocobase
volumes:
- ./storage/db/postgres:/var/lib/postgresql/data
networks:
- nocobase
NOCOBASE_EXTRACT_CLIENT_ASSETS=true extracts client assets and generates proxy configNOCOBASE_PROXY_PROVIDER=nginx tells the app to generate Nginx configNOCOBASE_PROXY_UPSTREAM_HOST=app lets the Nginx container reach the app service through the Compose network./storage must be mounted into both the app and nginx containers so they can share proxy config, static assets, and uploaded filesnginx container should wait until nocobase.conf is generated, then link it to /etc/nginx/conf.d/default.conf with ln -sfnginx container handle the host port mapping. For testing, you can start with 13000:80; in production, you usually expose the host 80 and 443 ports directly, while the app service does not need to expose its port to the hostIf your Nginx is installed directly on the host instead of running in a Docker container, it is better to use a separate docker-compose.yml. In this setup, the app service must expose a host port directly, and the proxy-related environment variables should use host-side values.
You can use a docker-compose.yml like this:
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:latest-no-nginx
restart: always
depends_on:
- postgres
networks:
- nocobase
environment:
- APP_KEY=your-secret-key
- DB_DIALECT=postgres
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=nocobase
- DB_USER=nocobase
- DB_PASSWORD=nocobase
- TZ=Etc/UTC
- NOCOBASE_EXTRACT_CLIENT_ASSETS=true
- NOCOBASE_PROXY_PROVIDER=nginx
- NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage
- NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1
- NOCOBASE_PROXY_UPSTREAM_PORT=13000
volumes:
- ./storage:/app/nocobase/storage
ports:
- "13000:13000"
postgres:
image: postgres:16
restart: always
command: postgres -c wal_level=logical
environment:
POSTGRES_USER: nocobase
POSTGRES_DB: nocobase
POSTGRES_PASSWORD: nocobase
volumes:
- ./storage/db/postgres:/var/lib/postgresql/data
networks:
- nocobase
In this variant:
NOCOBASE_PROXY_STORAGE_PATH should be the absolute host path of your storage directoryNOCOBASE_PROXY_UPSTREAM_HOST should be 127.0.0.1app service must keep ports, so the local Nginx can reach the app through 127.0.0.1:13000After the app container starts, wait for the config file to be generated, then link it into the local Nginx config directory:
while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do
echo "waiting for nocobase.conf..."
sleep 1
done
sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf
sudo nginx -t
sudo systemctl reload nginx
If your host Nginx does not use the conf.d directory, replace the link target with your own config path. Usually it is safer to keep nocobase.conf as a file included from the http {} context instead of copying its content manually.