feat: add Docker deployment support

- Multi-stage Dockerfile (Node build + Go build + Alpine runtime)
- docker-compose.yml with named volume for data persistence
- In-container Nginx reverse proxy (static files + API)
- Entrypoint script for graceful process management
- .dockerignore for optimized build context
- Updated README (zh/en) with Docker quick start and deployment docs

Closes #14
This commit is contained in:
Awuqing
2026-03-30 07:56:15 +08:00
parent 2ccea28e34
commit 8cf97e439e
7 changed files with 262 additions and 2 deletions

26
.dockerignore Normal file
View File

@@ -0,0 +1,26 @@
# Dependencies
web/node_modules/
# Build artifacts
server/bin/
web/dist/
# Data & logs
data/
*.db
*.log
# IDE & OS
.idea/
.vscode/
*.swp
*.swo
.DS_Store
# Git
.git/
.github/
# Docker
Dockerfile
docker-compose*.yml

62
Dockerfile Normal file
View File

@@ -0,0 +1,62 @@
# ---- Stage 1: Build frontend ----
FROM node:20-alpine AS web-builder
WORKDIR /build/web
COPY web/package.json web/package-lock.json ./
RUN npm ci
COPY web/ ./
RUN npm run build
# ---- Stage 2: Build backend ----
FROM golang:1.25-alpine AS server-builder
WORKDIR /build/server
COPY server/go.mod server/go.sum ./
RUN go mod download
COPY server/ ./
RUN go build -trimpath -ldflags="-s -w" -o backupx ./cmd/backupx
# ---- Stage 3: Production image ----
FROM alpine:3.21
RUN apk add --no-cache \
nginx \
tzdata \
ca-certificates \
# Required by mysql/postgresql backup tasks
mysql-client \
postgresql16-client \
&& rm -rf /var/cache/apk/*
# Create app user
RUN addgroup -S backupx && adduser -S -G backupx -h /app backupx
# Copy backend binary
COPY --from=server-builder /build/server/backupx /app/bin/backupx
# Copy frontend static files
COPY --from=web-builder /build/web/dist /app/web
# Copy nginx config
COPY deploy/docker/nginx.conf /etc/nginx/http.d/default.conf
# Copy entrypoint
COPY deploy/docker/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
# Create data directories
RUN mkdir -p /app/data /tmp/backupx && \
chown -R backupx:backupx /app /tmp/backupx
# Nginx needs to write to these dirs
RUN mkdir -p /var/lib/nginx/tmp /var/log/nginx && \
chown -R backupx:backupx /var/lib/nginx /var/log/nginx /run/nginx
WORKDIR /app
EXPOSE 8340
VOLUME ["/app/data"]
ENTRYPOINT ["/app/entrypoint.sh"]

View File

@@ -112,10 +112,30 @@ BackupX 是一个面向 **Linux / macOS 服务器**的自托管备份管理平
### 🌐 其他 ### 🌐 其他
- 中英文国际化 (i18n) - 中英文国际化 (i18n)
- 零外部依赖(内嵌 SQLite单二进制部署 - 零外部依赖(内嵌 SQLite单二进制部署
- Docker / Docker Compose 一键部署
- systemd 服务支持 - systemd 服务支持
## Quick Start ## Quick Start
### Docker 部署 (推荐)
```bash
# 克隆项目
git clone https://github.com/Awuqing/BackupX.git
cd BackupX
# 一键启动
docker compose up -d
```
如需备份宿主机上的目录,在 `docker-compose.yml` 中挂载对应路径:
```yaml
volumes:
- backupx-data:/app/data
- /path/to/backup/source:/mnt/source:ro
```
### 从源码构建 ### 从源码构建
```bash ```bash
@@ -302,11 +322,16 @@ BackupX/
├── deploy/ # 部署配置 ├── deploy/ # 部署配置
│ ├── nginx.conf # Nginx 参考配置 │ ├── nginx.conf # Nginx 参考配置
│ ├── backupx.service # systemd 服务单元 │ ├── backupx.service # systemd 服务单元
── install.sh # 一键安装脚本 ── install.sh # 一键安装脚本
│ └── docker/ # Docker 部署配置
│ ├── nginx.conf # 容器内 Nginx 配置
│ └── entrypoint.sh # 容器启动脚本
├── .github/ # GitHub 配置 ├── .github/ # GitHub 配置
│ ├── workflows/ci.yml # CI 工作流 │ ├── workflows/ci.yml # CI 工作流
│ ├── workflows/release.yml # Release 工作流 │ ├── workflows/release.yml # Release 工作流
│ └── ISSUE_TEMPLATE/ # Issue 模板 │ └── ISSUE_TEMPLATE/ # Issue 模板
├── Dockerfile # Docker 多阶段构建
├── docker-compose.yml # Docker Compose 配置
└── Makefile # 构建命令 └── Makefile # 构建命令
``` ```
@@ -371,6 +396,29 @@ sudo ./deploy/install.sh
5. 注册并启动 systemd 服务 5. 注册并启动 systemd 服务
6. 配置 Nginx 反向代理(如已安装) 6. 配置 Nginx 反向代理(如已安装)
### Docker 部署
```bash
# 使用 docker compose
docker compose up -d
# 或手动构建镜像
docker build -t backupx .
docker run -d --name backupx -p 8340:8340 -v backupx-data:/app/data backupx
```
通过环境变量覆盖配置:
```bash
docker run -d --name backupx \
-p 8340:8340 \
-v backupx-data:/app/data \
-e TZ=Asia/Shanghai \
-e BACKUPX_LOG_LEVEL=debug \
-e BACKUPX_BACKUP_MAX_CONCURRENT=4 \
backupx
```
### 手动部署 ### 手动部署
```bash ```bash

View File

@@ -112,10 +112,30 @@ Supports **multi-node cluster management** for unified control of backup tasks a
### 🌐 Other ### 🌐 Other
- Chinese & English i18n - Chinese & English i18n
- Zero external dependencies (embedded SQLite, single binary deployment) - Zero external dependencies (embedded SQLite, single binary deployment)
- Docker / Docker Compose one-click deployment
- systemd service support - systemd service support
## Quick Start ## Quick Start
### Docker Deployment (Recommended)
```bash
# Clone the project
git clone https://github.com/Awuqing/BackupX.git
cd BackupX
# Start with one command
docker compose up -d
```
To back up host directories, mount them in `docker-compose.yml`:
```yaml
volumes:
- backupx-data:/app/data
- /path/to/backup/source:/mnt/source:ro
```
### Build from Source ### Build from Source
```bash ```bash
@@ -303,11 +323,16 @@ BackupX/
├── deploy/ # Deployment configs ├── deploy/ # Deployment configs
│ ├── nginx.conf # Nginx reference config │ ├── nginx.conf # Nginx reference config
│ ├── backupx.service # systemd service unit │ ├── backupx.service # systemd service unit
── install.sh # One-click install script ── install.sh # One-click install script
│ └── docker/ # Docker deployment configs
│ ├── nginx.conf # In-container Nginx config
│ └── entrypoint.sh # Container entrypoint script
├── .github/ # GitHub configuration ├── .github/ # GitHub configuration
│ ├── workflows/ci.yml # CI workflow │ ├── workflows/ci.yml # CI workflow
│ ├── workflows/release.yml # Release workflow │ ├── workflows/release.yml # Release workflow
│ └── ISSUE_TEMPLATE/ # Issue templates │ └── ISSUE_TEMPLATE/ # Issue templates
├── Dockerfile # Docker multi-stage build
├── docker-compose.yml # Docker Compose config
└── Makefile # Build commands └── Makefile # Build commands
``` ```
@@ -372,6 +397,29 @@ The install script will automatically:
5. Register and start the systemd service 5. Register and start the systemd service
6. Configure Nginx reverse proxy (if installed) 6. Configure Nginx reverse proxy (if installed)
### Docker Deployment
```bash
# Using docker compose
docker compose up -d
# Or build and run manually
docker build -t backupx .
docker run -d --name backupx -p 8340:8340 -v backupx-data:/app/data backupx
```
Override configuration via environment variables:
```bash
docker run -d --name backupx \
-p 8340:8340 \
-v backupx-data:/app/data \
-e TZ=Asia/Shanghai \
-e BACKUPX_LOG_LEVEL=debug \
-e BACKUPX_BACKUP_MAX_CONCURRENT=4 \
backupx
```
### Manual Deployment ### Manual Deployment
```bash ```bash

View File

@@ -0,0 +1,23 @@
#!/bin/sh
set -e
# Backend listens on internal port 8341, Nginx exposes 8340
export BACKUPX_SERVER_PORT="${BACKUPX_SERVER_PORT_INTERNAL:-8341}"
# Start Nginx in background
nginx -g "daemon off;" &
NGINX_PID=$!
# Start BackupX backend
/app/bin/backupx &
APP_PID=$!
# Trap signals for graceful shutdown
trap 'kill $APP_PID $NGINX_PID 2>/dev/null; wait $APP_PID $NGINX_PID 2>/dev/null' SIGTERM SIGINT
echo "BackupX started — Nginx :8340 -> Backend :8341"
# Wait for either process to exit
wait -n $APP_PID $NGINX_PID 2>/dev/null || true
kill $APP_PID $NGINX_PID 2>/dev/null || true
wait $APP_PID $NGINX_PID 2>/dev/null || true

32
deploy/docker/nginx.conf Normal file
View File

@@ -0,0 +1,32 @@
server {
listen 8340;
server_name _;
root /app/web;
index index.html;
# API reverse proxy to backend
location /api/ {
proxy_pass http://127.0.0.1:8341/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
}
# SPA fallback
location / {
try_files $uri $uri/ /index.html;
}
# Static assets cache
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}

21
docker-compose.yml Normal file
View File

@@ -0,0 +1,21 @@
services:
backupx:
build: .
image: backupx:latest
container_name: backupx
restart: unless-stopped
ports:
- "8340:8340"
volumes:
- backupx-data:/app/data
# Mount host directories that need to be backed up (example):
# - /path/to/backup/source:/mnt/source:ro
environment:
- TZ=Asia/Shanghai
# Override any config via BACKUPX_ prefixed env vars:
# - BACKUPX_SERVER_PORT=8340
# - BACKUPX_LOG_LEVEL=info
# - BACKUPX_BACKUP_MAX_CONCURRENT=2
volumes:
backupx-data: