Merge branch 'pr-538'

This commit is contained in:
decolua
2026-04-13 10:29:41 +07:00
4 changed files with 110 additions and 37 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@
product
# production
/build
.idea/
# misc
.DS_Store

View File

@@ -29,32 +29,3 @@ tsconfig.json
.next/cache/
.next/standalone/data/

93
DOCKER.md Normal file
View File

@@ -0,0 +1,93 @@
# Docker
This project ships with a `Dockerfile` for building and running 9Router in a container.
## Build image
```bash
docker build -t 9router .
```
## Start container
```bash
docker run --rm \
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data \
--name 9router \
9router
```
The app listens on port `20128` in the container.
## What the volume does
```bash
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data
```
`9router` stores its database at `path.join(DATA_DIR, "db.json")`.
Without `DATA_DIR`, the app falls back to the current user's home directory (for example `~/.9router/db.json` on macOS/Linux). In the container, set `DATA_DIR=/app/data` so the bind mount is actually used.
With the example above, the database file is:
```text
/app/data/db.json
```
and it is persisted on the host at:
```text
$HOME/.9router/db.json
```
## Stop container
```bash
docker stop 9router
```
## Run in background
```bash
docker run -d \
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data \
--name 9router \
9router
```
## View logs
```bash
docker logs -f 9router
```
## Optional environment variables
You can override runtime env vars with `-e`.
Example:
```bash
docker run --rm \
-p 20128:20128 \
-v "$HOME/.9router:/app/data" \
-e DATA_DIR=/app/data \
-e PORT=20128 \
-e HOSTNAME=0.0.0.0 \
-e DEBUG=true \
--name 9router \
9router
```
## Rebuild after code changes
```bash
docker build -t 9router .
```
Then restart the container.

View File

@@ -1,14 +1,21 @@
FROM node:20-alpine AS builder
# syntax=docker/dockerfile:1.7
ARG BUN_IMAGE=oven/bun:1.3.2-alpine
FROM ${BUN_IMAGE} AS base
WORKDIR /app
COPY package*.json ./
RUN if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi
FROM base AS builder
RUN apk --no-cache upgrade && apk --no-cache add nodejs npm python3 make g++ linux-headers
COPY package.json ./
RUN --mount=type=cache,target=/root/.npm \
npm install
COPY . ./
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
FROM node:20-alpine AS runner
FROM ${BUN_IMAGE} AS runner
WORKDIR /app
LABEL org.opencontainers.image.title="9router"
@@ -27,13 +34,14 @@ COPY --from=builder /app/src/mitm ./src/mitm
# Standalone node_modules may omit deps only required by the MITM child process.
COPY --from=builder /app/node_modules/node-forge ./node_modules/node-forge
RUN mkdir -p /app/data
RUN mkdir -p /app/data && chown -R bun:bun /app
# Fix permissions at runtime (handles mounted volumes)
RUN printf '#!/bin/sh\nchown -R node:node /app/data 2>/dev/null; exec su-exec node "$@"\n' > /entrypoint.sh && chmod +x /entrypoint.sh
RUN apk add --no-cache su-exec
RUN apk --no-cache upgrade && apk --no-cache add su-exec && \
printf '#!/bin/sh\nchown -R bun:bun /app/data 2>/dev/null\nexec su-exec bun "$@"\n' > /entrypoint.sh && \
chmod +x /entrypoint.sh
EXPOSE 20128
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "server.js"]
CMD ["bun", "server.js"]