Docker Compose
Run the panel, PostgreSQL and Prometheus together with the shipped compose file.
Overview
The repository ships a docker-compose.yml that brings up three services: the
app (nasnet_panel_backend), PostgreSQL 16 (nasnet_panel_db) and
Prometheus (nasnet_panel_prometheus). This is the recommended path when you
already have Docker on the host and prefer to edit the configuration yourself
rather than answer a wizard.
Before you start
- Docker Engine and the Docker Compose plugin installed.
- Your
JWT_SECRET_KEYandADMIN_PASSWORD_HASHgenerated, as covered in Installation. - Port
9761reachable, or a different value ready forAPP_PORT.
Steps
-
Clone the repository and create your config file.
git clone https://github.com/nasnet-community/nasnet-panel-linux.git cd nasnet-panel-linux cp .env.example .env -
Edit
.envand set at minimumADMIN_USERNAME,ADMIN_PASSWORD_HASH,JWT_SECRET_KEY,APP_BASE_URLandDB_PASSWORD. -
Start the stack and watch it come up.
docker compose up -d docker compose logs -f app -
When the
appcontainer reports healthy, open yourAPP_BASE_URLand sign in. Compose health-checks the app againsthttp://localhost:${APP_PORT}/health/ready.
Using SQLite instead of PostgreSQL
For a small single-server setup you can drop the database container. Set this in
.env:
DB_DRIVER=sqlite
DB_PATH=/app/data/nasnet_panel.db
Then start with the override file, which removes the PostgreSQL dependency and mounts a SQLite volume:
docker compose -f docker-compose.yml -f docker-compose.sqlite.yml up -d
Publishing proxy ports
The compose file publishes only ${APP_PORT:-9761} by default. Add the ports
your Xray inbounds listen on to the app service’s ports list, because the file
carries a commented example for 443.
Reference
| Item | Value |
|---|---|
| App container | nasnet_panel_backend |
| Database container | nasnet_panel_db (postgres:16-alpine) |
| Prometheus container | nasnet_panel_prometheus (prom/prometheus:v3.2.1) |
| Panel port | ${APP_PORT:-9761} |
| Prometheus port | ${PROMETHEUS_PORT:-9090} |
| Health check | /health/ready |
| Named volumes | postgres_data, acme_data, prometheus_data, xray_config, backups_data |
The app service also gets NET_ADMIN and NET_BIND_SERVICE capabilities so
Xray can bind privileged ports and manage interfaces.
Troubleshooting
The app container restarts before Postgres is ready. Compose already gates
app on the database’s pg_isready health check, so a loop here usually means
DB_PASSWORD in .env does not match what the Postgres container was first
initialised with. The password is baked into postgres_data on first start, so
either restore the original password or remove the volume (destructive).