VoucherVault 1.30.3 Docker Compose 部署指南
用 Docker Compose 部署 VoucherVault v1.30.3 的完整实录:compose 文件解析、数据卷权限、启动日志取证(含自动生成的管理员密码)、HTTP 验证、Nginx 反代接入与排障。
VoucherVault 1.30.3 Docker Compose 部署指南
目标:用 Docker Compose 快速拉起 VoucherVault v1.30.3 的全功能栈(应用 + Redis),涵盖最小可用 SQLite 版 Compose 文件、目录权限修正、启动日志取证、功能验证与排障。已具备 Docker 环境的读者,优先使用本方案;裸机安装请见《Ubuntu 22.04 安装 VoucherVault 指南》。VoucherVault 介绍与选型请读《VoucherVault 介绍与选型指南》。
一、环境信息
| 项目 | 值 |
|---|---|
| 软件版本 | VoucherVault v1.30.3 |
| Docker Engine | 27.x+(测试环境 v27.3.1) |
| Docker Compose | v5.6.1 |
| 应用镜像 | l4rm4nd/vouchervault:1.30.x(约 1.26GB,内置 Python 3.12.13 + Django 5.2.18) |
| Redis 镜像 | redis:7-alpine(约 57.8MB) |
| 端口 | 宿主机 8130:8000(按需修改) |
| 自定义网络 | 10.89.61.0/24,隔离 Redis 与 App 通信 |
| 数据持久化 | ./volume-data/database → 容器内 /opt/app/database |
| 运行时用户 | www-data(UID 33,镜像内已预置) |
| 首次管理员密码 | 自动生成并打印到容器日志(实测见后文) |
二、目录结构与前置准备
创建工作目录并建立数据卷文件夹:
mkdir -p /opt/data/quzuo/tmp/vouchervault/compose/volume-data/database
⚠️ 关键:数据卷需要把属主设为容器内运行用户 UID 33,否则容器启动时会报权限不足并退出:
chown -R 33:33 /opt/data/quzuo/tmp/vouchervault/compose/volume-data/database
验证 UID 33 存在(Ubuntu/Debian 默认已有 www-data):
id -nu 33
www-data
三、Compose 文件
基于官方 docker-compose-sqlite.yml 改写:显式自定义网络、指定宿主机端口 8130,并把 DOMAIN 指向测试地址(按需改为生产域名)。文件存为 docker-compose.yml:
name: vouchervault-1.30.3-stack
services:
app:
image: l4rm4nd/vouchervault:1.30.x
container_name: vouchervault-app
restart: unless-stopped
environment:
- DOMAIN=127.0.0.1
- PORT=8130
- SECURE_COOKIES=False
- EXPIRY_THRESHOLD_DAYS=30
- TZ=Asia/Shanghai
ports:
- 8130:8000
volumes:
- ./volume-data/database:/opt/app/database
networks:
- vouchervault-net
redis:
image: redis:7-alpine
container_name: vouchervault-redis
restart: unless-stopped
expose:
- 6379
networks:
- vouchervault-net
networks:
vouchervault-net:
driver: bridge
ipam:
config:
- subnet: 10.89.61.0/24
要点说明:
name: vouchervault-1.30.3-stack:显式项目名,避免默认取目录名导致不同组件互相冲突;DOMAIN与PORT共同决定ALLOWED_HOSTS和CSRF_TRUSTED_ORIGINS,如果最终通过反向代理访问,需改成实际域名和443;expose只暴露给内部网络,不会映射到宿主机,减少攻击面;- Redis 无持久化卷要求(仅作 Celery 消息队列中间件),状态由 App 落 SQLite/PostgreSQL。
四、启动栈
拉取镜像并启动:
docker compose pull
docker compose up -d
Container vouchervault-redis Creating
Container vouchervault-app Creating
Container vouchervault-app Created
Container vouchervault-redis Created
Container vouchervault-app Starting
Container vouchervault-redis Starting
Container vouchervault-app Started
Container vouchervault-redis Started
检查容器状态:
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
vouchervault-app l4rm4nd/vouchervault:1.30.x "/opt/app/docker/ent…" app 10 seconds ago Up 8 seconds 0.0.0.0:8130->8000/tcp, [::]:8130->8000/tcp
vouchervault-redis redis:7-alpine "docker-entrypoint.s…" redis 10 seconds ago Up 8 seconds 6379/tcp
五、查看启动日志并获取管理员密码
首次启动(数据库不存在时),容器会自动执行数据库迁移、创建默认周期任务和 admin 超级用户,并把随机密码打印到日志。务必第一时间记录密码:
docker compose logs app
vouchervault-app | [TASK] Validating volume permissions
vouchervault-app | [DONE] Permissions ok. Container can read and write database.
vouchervault-app | [TASK] Migrating changes to the database
vouchervault-app | Applying contenttypes.0001_initial... OK
vouchervault-app | Applying auth.0001_initial... OK
vouchervault-app | Applying contenttypes.0002_remove_content_type_name... OK
vouchervault-app | Applying auth.0002_alter_permission_name_max_length... OK
vouchervault-app | Applying auth.0003_alter_user_email_max_length... OK
vouchervault-app | Applying auth.0004_alter_user_username_opts... OK
vouchervault-app | Applying auth.0005_alter_user_last_login_null... OK
vouchervault-app | Applying auth.0006_require_contenttypes_0002... OK
vouchervault-app | Applying auth.0007_alter_validators_add_error_messages... OK
vouchervault-app | Applying auth.0008_alter_user_username_max_length... OK
vouchervault-app | Applying auth.0009_alter_user_last_name_max_length... OK
...
vouchervault-app | [TASK] Creating superuser account
vouchervault-app | 18 objects imported automatically (use -v 2 for details).
vouchervault-app |
vouchervault-app | [>] username: admin
vouchervault-app | [>] password: yi1RaS95a3Lt581Ogr9E
vouchervault-app | -------------------------------------------------
vouchervault-app | [TASK] Starting Celery worker and beat
vouchervault-app | [TASK] Spawning the application server
vouchervault-app | [uWSGI] getting INI configuration from docker/docker_uwsgi.ini
vouchervault-app | [uwsgi-static] added mapping for /static => /opt/app/myapp/static/
vouchervault-app | *** Operational MODE: preforking+threaded ***
vouchervault-app | WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7b2030a15390 pid: 1 (default app)
vouchervault-app | *** uWSGI is running in multiple interpreter mode ***
vouchervault-app | spawned uWSGI master process (pid: 1)
vouchervault-app | spawned uWSGI worker 1 (pid: 26, cores: 2)
vouchervault-app | spawned uWSGI worker 2 (pid: 27, cores: 2)
- 默认超级用户名固定为
admin,密码是 20 位随机串(每栈初始化一次)。如需重置,进入容器用 Django shell 改; uWSGI进程 PID 为 1,说明在主容器进程位上,直接受 Docker 重启策略管理;- 若第二次启动时数据库已存在,日志会打印
[INFO] SQLite3 database found. Skipping initialization.,跳过初始化,不影响已有数据。
六、功能验证
从宿主机访问栈暴露的 8130 端口:
curl -s -o /dev/null -w 'GET / -> %{http_code} redirect=%{redirect_url}\n' http://127.0.0.1:8130/
GET / -> 302 redirect=http://127.0.0.1:8130/en/
登录页返回 200:
curl -s -o /dev/null -w 'GET /en/accounts/login/ -> %{http_code}\n' http://127.0.0.1:8130/en/accounts/login/
GET /en/accounts/login/ -> 200
使用日志中的密码模拟登录:
curl -s -c /tmp/cj http://127.0.0.1:8130/en/accounts/login/ \
| grep -o 'csrfmiddlewaretoken" value="[^"]*' \
| head -1 | cut -d'"' -f3 > /tmp/token
curl -s -b /tmp/cj -c /tmp/cj -o /dev/null -w 'POST login -> %{http_code} redirect=%{redirect_url}\n' \
--data-urlencode "csrfmiddlewaretoken=$(cat /tmp/token)" \
--data-urlencode "username=admin" \
--data-urlencode "password=yi1RaS95a3Lt581Ogr9E" \
http://127.0.0.1:8130/en/accounts/login/
POST login -> 302 redirect=http://127.0.0.1:8130/
302 到首页即登录成功,栈已可用。
七、网络与容器内通信
自定义桥接网络避免了容器间通过宿主机 IP 通信的问题:
docker network ls | grep vouchervault
docker network inspect vouchervault-1303-stack_vouchervault-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
10.89.61.0/24
注:项目名中的点号
.在 Compose 生成网络名时会被移除,因此实际网络名称为vouchervault-1303-stack_vouchervault-net,不影响功能。
容器内 App 通过服务名 redis 即可解析到 Redis:
docker compose exec app sh -c "nc -z redis 6379 && echo 'redis reachable'"
redis reachable
八、Nginx 反向代理(生产接入)
仅暴露容器端口到宿主机并不安全,生产环境建议用宿主机 Nginx 做 TLS 终止,再透传至容器。最小配置示例:
server {
listen 443 ssl http2;
server_name vouchervault.example.com;
ssl_certificate /etc/nginx/ssl/vouchervault.crt;
ssl_certificate_key /etc/nginx/ssl/vouchervault.key;
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:8130;
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 https;
}
}
同步修改 Compose 中的环境变量:
- DOMAIN=vouchervault.example.com
- SECURE_COOKIES=True
然后重刷栈:
docker compose down
docker compose up -d
九、常用运维操作
# 查看日志(实时)
docker compose logs -f app
# 进入容器执行 Django 命令
docker compose exec app python manage.py shell
# 停止栈(保留数据卷)
docker compose down
# 彻底清理(含数据卷,慎用)
docker compose down -v
# 重启应用
docker compose restart app
十、排障实录
1. 容器启动即退出,日志报 [FAIL] Insufficient permissions on bind mount volume
原因:宿主机数据目录属主不是 UID 33。解法:执行 chown -R 33:33 volume-data/database 后重新 up -d。
2. 首次启动后忘记管理员密码
进入容器重置:
docker compose exec app python manage.py shell -c \
"from django.contrib.auth.models import User; u=User.objects.get(username='admin'); u.set_password('q1w2e3r4'); u.save()"
3. 修改 DOMAIN 或环境变量后未生效
VoucherVault 在容器启动时把 .env 读入 Python 进程,修改 Compose 环境变量后需要 docker compose up -d --force-recreate app。
4. 周期任务不触发
Compose 内 Celery Beat 已在官方 entrypoint.sh 中自动启动,无需手动干预;如果 beat 未启动,检查 vouchervault-redis 是否已就绪,然后 docker compose restart app。
十一、参考链接
- 官方仓库:https://github.com/l4rm4nd/VoucherVault(查询日期 2026-10-25)
- Docker Hub 镜像:https://hub.docker.com/r/l4rm4nd/vouchervault(查询日期 2026-10-25)
- 站内:《VoucherVault 介绍与选型指南》
- 站内:《Ubuntu 22.04 安装 VoucherVault 指南》
- 站内:《VoucherVault 配置参数详解》(本专栏)
- 站内:《VoucherVault API 使用详解》(本专栏)