Docker Compose

Run the panel, PostgreSQL and Prometheus together with the shipped compose file.

Last updated Aug 14, 2026View as Markdown

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_KEY and ADMIN_PASSWORD_HASH generated, as covered in Installation.
  • Port 9761 reachable, or a different value ready for APP_PORT.

Steps

  1. 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
  2. Edit .env and set at minimum ADMIN_USERNAME, ADMIN_PASSWORD_HASH, JWT_SECRET_KEY, APP_BASE_URL and DB_PASSWORD.

  3. Start the stack and watch it come up.

    docker compose up -d
    docker compose logs -f app
  4. When the app container reports healthy, open your APP_BASE_URL and sign in. Compose health-checks the app against http://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).