2026-04-09 03:21:30 -04:00
# Docker
2026-05-13 07:22:31 -04:00
Run 9Router in a container. Published image: [`decolua/9router` ](https://hub.docker.com/r/decolua/9router ) — multi-platform `linux/amd64` + `linux/arm64` .
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
---
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
# 👤 For Users
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
## Quick start
2026-04-09 03:21:30 -04:00
```bash
2026-05-13 07:22:31 -04:00
docker run -d \
2026-04-09 03:21:30 -04:00
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
2026-04-09 23:14:34 -04:00
-e DATA_DIR=/app/data \
2026-04-09 03:21:30 -04:00
--name 9router \
2026-05-13 07:22:31 -04:00
decolua/9router:latest
2026-04-09 03:21:30 -04:00
```
2026-05-13 07:22:31 -04:00
App listens on port `20128` . Open: http://localhost:20128
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
## Manage container
2026-04-09 03:21:30 -04:00
```bash
2026-05-13 07:22:31 -04:00
docker logs -f 9router # view logs
docker stop 9router # stop
docker start 9router # start again
docker rm -f 9router # remove
2026-04-09 03:21:30 -04:00
```
2026-05-13 07:22:31 -04:00
## Data persistence
2026-04-09 23:14:34 -04:00
2026-05-13 07:22:31 -04:00
```bash
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data
2026-04-09 23:14:34 -04:00
```
2026-05-13 07:22:31 -04:00
Without `DATA_DIR` , the app falls back to `~/.9router/` (macOS/Linux) or `%APPDATA%\9router\` (Windows). In the container, `DATA_DIR=/app/data` makes the bind mount work.
Data layout under `$DATA_DIR/` :
2026-04-09 23:14:34 -04:00
```text
2026-05-13 07:22:31 -04:00
$DATA_DIR/
├── db/
│ ├── data.sqlite # main SQLite database
│ └── backups/ # auto backups
└── ... # certs, logs, runtime configs
2026-04-09 23:14:34 -04:00
```
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
Host path: `$HOME/.9router/db/data.sqlite`
Container path: `/app/data/db/data.sqlite`
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
## Optional env vars
2026-04-09 03:21:30 -04:00
```bash
docker run -d \
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
2026-04-09 23:14:34 -04:00
-e DATA_DIR=/app/data \
2026-05-13 07:22:31 -04:00
-e PORT=20128 \
-e HOSTNAME=0.0.0.0 \
-e DEBUG=true \
2026-04-09 03:21:30 -04:00
--name 9router \
2026-05-13 07:22:31 -04:00
decolua/9router:latest
2026-04-09 03:21:30 -04:00
```
2026-05-13 07:22:31 -04:00
## Update to latest
2026-04-09 03:21:30 -04:00
```bash
2026-05-13 07:22:31 -04:00
docker pull decolua/9router:latest
docker rm -f 9router
# re-run the quick start command
2026-04-09 03:21:30 -04:00
```
2026-05-13 07:22:31 -04:00
---
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
# 🛠 For Developers
2026-04-09 03:21:30 -04:00
2026-05-13 07:25:29 -04:00
## Build image locally (test)
2026-04-09 03:21:30 -04:00
2026-05-13 07:22:31 -04:00
```bash
cd app & & docker build -t 9router .
docker run --rm -p 20128:20128 \
2026-04-09 03:21:30 -04:00
-v "$HOME/.9router:/app/data" \
2026-04-09 23:14:34 -04:00
-e DATA_DIR=/app/data \
2026-04-09 03:21:30 -04:00
9router
```
2026-05-13 07:25:29 -04:00
## Publish (automatic via CI)
2026-05-13 07:22:31 -04:00
2026-05-13 07:25:29 -04:00
Push a git tag `v*` → GitHub Actions builds multi-platform (amd64+arm64) and pushes to:
- `ghcr.io/decolua/9router:v{version}` + `:latest`
- `decolua/9router:v{version}` + `:latest`
2026-04-09 03:21:30 -04:00
```bash
2026-05-13 07:25:29 -04:00
# Use scripts/release.js (recommended)
node scripts/release.js "Release title" "Notes"
2026-05-13 07:22:31 -04:00
2026-05-13 07:25:29 -04:00
# Or manually
git tag v0.4.x & & git push origin v0.4.x
2026-04-09 03:21:30 -04:00
```
2026-05-13 07:25:29 -04:00
Workflow: `app/.github/workflows/docker-publish.yml`