docs/docs/en/get-started/installation/docker.mdx
:::tip Prerequisites
:::
# Create a folder named my-project (or any other name) to store the system files generated by NocoBase
mkdir my-project && cd my-project
# Create an empty docker-compose.yml file
vi docker-compose.yml
Choose a NocoBase version (Version Comparison) and database type, then copy the corresponding configuration into docker-compose.yml.
:::tip Configuration Notes
latest latest-full beta beta-full alpha alpha-full 1.7.14 1.7.14-full
nocobase/nocobase:latest-fullAPP_KEY: Please replace your-secret-key with a random string, which is used to encrypt sensitive information such as user tokens.DB_HOST to the database server address, and delete or comment out the database service configuration (e.g., postgres, mysql, mariadb services).:::
<Tabs> <Tab label="Latest version"> <Tabs> <Tab label="PostgreSQL">networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:latest-full
restart: always
networks:
- nocobase
depends_on:
- postgres
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=postgres
# Database host, can be replaced with an existing database server IP
- DB_HOST=postgres
# Database port
- DB_PORT=5432
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=nocobase
# Database password
- DB_PASSWORD=nocobase
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting postgres
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
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:latest-full
restart: always
networks:
- nocobase
depends_on:
- mysql
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mysql
# Database host, can be replaced with an existing database server IP
- DB_HOST=mysql
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mysql
mysql:
image: mysql:8
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mysql:/var/lib/mysql
networks:
- nocobase
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:latest-full
restart: always
networks:
- nocobase
depends_on:
- mariadb
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mariadb
# Database host, can be replaced with an existing database server IP
- DB_HOST=mariadb
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mariadb
mariadb:
image: mariadb:11
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mariadb:/var/lib/mysql
networks:
- nocobase
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:beta-full
restart: always
networks:
- nocobase
depends_on:
- postgres
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=postgres
# Database host, can be replaced with an existing database server IP
- DB_HOST=postgres
# Database port
- DB_PORT=5432
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=nocobase
# Database password
- DB_PASSWORD=nocobase
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting postgres
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
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:beta-full
restart: always
networks:
- nocobase
depends_on:
- mysql
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mysql
# Database host, can be replaced with an existing database server IP
- DB_HOST=mysql
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mysql
mysql:
image: mysql:8
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mysql:/var/lib/mysql
networks:
- nocobase
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:beta-full
restart: always
networks:
- nocobase
depends_on:
- mariadb
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mariadb
# Database host, can be replaced with an existing database server IP
- DB_HOST=mariadb
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mariadb
mariadb:
image: mariadb:11
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mariadb:/var/lib/mysql
networks:
- nocobase
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:alpha-full
restart: always
networks:
- nocobase
depends_on:
- postgres
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=postgres
# Database host, can be replaced with an existing database server IP
- DB_HOST=postgres
# Database port
- DB_PORT=5432
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=nocobase
# Database password
- DB_PASSWORD=nocobase
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting postgres
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
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:alpha-full
restart: always
networks:
- nocobase
depends_on:
- mysql
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mysql
# Database host, can be replaced with an existing database server IP
- DB_HOST=mysql
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mysql
mysql:
image: mysql:8
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mysql:/var/lib/mysql
networks:
- nocobase
networks:
nocobase:
driver: bridge
services:
app:
image: nocobase/nocobase:alpha-full
restart: always
networks:
- nocobase
depends_on:
- mariadb
environment:
# Application key, used to generate user tokens, etc.
# If APP_KEY is changed, old tokens will become invalid
# Can be any random string, and ensure it is not leaked
- APP_KEY=your-secret-key
# Database type, supports postgres, mysql, mariadb
- DB_DIALECT=mariadb
# Database host, can be replaced with an existing database server IP
- DB_HOST=mariadb
# Database port
- DB_PORT=3306
# Database name
- DB_DATABASE=nocobase
# Database user
- DB_USER=root
# Database password
- DB_PASSWORD=nocobase
# Whether to convert table and field names to snake case
- DB_UNDERSCORED=true
# Timezone, please change it to your local timezone, e.g., America/New_York
- TZ=Etc/UTC
volumes:
- ./storage:/app/nocobase/storage
ports:
- '13000:80'
# init: true
# If you use an existing database service, you can skip starting mariadb
mariadb:
image: mariadb:11
environment:
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: nocobase
MYSQL_ROOT_PASSWORD: nocobase
restart: always
volumes:
- ./storage/db/mariadb:/var/lib/mysql
networks:
- nocobase
# Pull the latest image
docker compose pull
# Run in the background (installation will run automatically on the first run)
docker compose up -d
# View installation and running logs
docker compose logs -f app
app-postgres-app-1 | nginx started
app-postgres-app-1 | yarn run v1.22.15
app-postgres-app-1 | $ cross-env DOTENV_CONFIG_PATH=.env node -r dotenv/config packages/app/server/lib/index.js install -s
app-postgres-app-1 | Done in 2.72s.
app-postgres-app-1 | yarn run v1.22.15
app-postgres-app-1 | $ pm2-runtime start --node-args="-r dotenv/config" packages/app/server/lib/index.js -- start
app-postgres-app-1 | 2022-04-28T15:45:38: PM2 log: Launching in no daemon mode
app-postgres-app-1 | 2022-04-28T15:45:38: PM2 log: App [index:0] starting in -fork mode-
app-postgres-app-1 | 2022-04-28T15:45:38: PM2 log: App [index:0] online
app-postgres-app-1 | 🚀 NocoBase server running at: http://localhost:13000/
Open http://localhost:13000 in your browser. The initial account and password are [email protected] and admin123.
:::warning Account Security Notice
After logging in for the first time, please change the default password promptly to ensure system security.
:::
If you use the built-in Nginx image, it is usually better not to expose 13000 directly to the public internet. A more common setup is to keep the container port available only on the host and let the host Nginx handle the domain, HTTPS, and reverse proxy.
The following config proxies domain requests to http://127.0.0.1:13000/:
server {
listen 80;
server_name your_domain.com; # Replace your_domain.com with your domain
location / {
proxy_pass http://127.0.0.1:13000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
proxy_set_header Host $final_host;
proxy_set_header Referer $http_referer;
proxy_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store" always;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_buffering off;
}
}
If you also want to enable HTTPS, configure 443 and the certificate on the host Nginx. The NocoBase container does not need to handle certificates separately.
If you want to deploy the app under a subpath, such as https://your_domain.com/nocobase/, configure the APP_PUBLIC_PATH environment variable first:
services:
app:
image: nocobase/nocobase:latest
environment:
+ - APP_PUBLIC_PATH=/nocobase/
Keep the leading and trailing / in the path. After this is configured, the app URL becomes http://127.0.0.1:13000/nocobase/.
Then configure the host Nginx with the same subpath proxy:
server {
listen 80;
server_name your_domain.com; # Replace your_domain.com with your domain
location /nocobase/ {
proxy_pass http://127.0.0.1:13000/nocobase/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
proxy_set_header Host $final_host;
proxy_set_header Referer $http_referer;
proxy_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store" always;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_buffering off;
}
}
The key point is that APP_PUBLIC_PATH and the path in proxy_pass must stay consistent. If either side misses /nocobase/, static assets and routing will usually not work correctly.
If you do not want to use the built-in Nginx, you can also use one of these separate proxy setups: