Docker Compose 部署新版独角数卡 Dujiao-Next

Dujiao-Next 是一套开源的数字商品销售系统,采用前后端分离架构,目标是帮助开发者和团队快速搭建可运营、可扩展、可私有部署的销售平台。

它的前身为开源项目“独角数卡” https://github.com/assimon/dujiaoka

Dujiao-Next 项目地址:https://github.com/dujiao-next

此教程适合于个人在生产环境兼具轻量化部署及设置,有其他需求的请查看 Dujiao-Next 官方文档

安装 Docker 和 Docker Compose

curl -fsSL https://get.docker.com | sh

curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

准备部署目录

mkdir -p /srv/html/dujiao-next/{config,data/db,data/uploads,data/logs,data/redis,data/postgres}
cd /srv/html/dujiao-next

# 关键:避免日志/数据库目录权限不足(api 容器默认非 root 用户)
chmod -R 0777 ./data/logs ./data/db ./data/uploads ./data/redis ./data/postgres

命令解释:在/srv/html/dujiao-next/创建对应目录和文件夹,以供后续使用;根据自己实际地址修改

准备 API 配置文件

API 容器默认读取 /app/config.yml,先下载模板:

curl -L https://raw.githubusercontent.com/dujiao-next/dujiao-next/main/config.yml.example -o ./config/config.yml

需要在 ./config/config.yml 里按方案修改数据库与 Redis 配置。

生成 随机密钥字符串命令:后面需要

openssl rand -base64 32

PostgreSQL + Redis(推荐生产)

# D&J Studio 配置文件

server:
  host: 0.0.0.0
  port: 8080
  mode: release  # debug 或 release

log:
  dir: ""  # 为空时使用当前运行目录/logs
  filename: app.log
  max_size_mb: 1
  max_backups: 7
  max_age_days: 7
  compress: true

database:
  driver: postgres  # sqlite / postgres
  dsn: host=dujiaonext-postgres port=5432 user=dujiao password=dujiao_pass dbname=dujiao_next sslmode=disable TimeZone=Asia/Shanghai
  pool:
    max_open_conns: 20
    max_idle_conns: 5
    conn_max_lifetime_seconds: 1200  # 0 表示不限制
    conn_max_idle_time_seconds: 300  # 0 表示不限制

jwt:
  secret: LoSJTcRehAK1uN/UgXX+eSkRTJHIOqYeRQRlrOs697A=
  expire_hours: 24  # Token 有效期(小时)

user_jwt:
  secret: DAS4xyThmniDUi8VWRVPhvuOldhpuCGlswD945CkXgU=
  expire_hours: 24  # 用户 Token 有效期(小时)
  remember_me_expire_hours: 168  # 记住我 Token 有效期(小时)

bootstrap:
  default_admin_username: ""  # 首次初始化管理员用户名(可选)
  default_admin_password: ""  # 首次初始化管理员密码(建议生产配置)

telegram_auth:
  enabled: false
  bot_username: ""  # Telegram Bot 用户名(不含 @)
  bot_token: ""     # Telegram Bot Token(敏感)
  login_expire_seconds: 300
  replay_ttl_seconds: 300

redis:
  enabled: true
  host: dujiaonext-redis
  port: 6379
  password: "PUbUy1K63h61vcl6Xg+6m9TOYMfH0IghG4WOuJhHbjI="
  db: 0
  prefix: "dj"

queue:
  enabled: true
  host: dujiaonext-redis
  port: 6379
  password: "PUbUy1K63h61vcl6Xg+6m9TOYMfH0IghG4WOuJhHbjI="
  db: 1
  concurrency: 10
  queues:
    default: 10
    critical: 5

upload:
  max_size: 10485760  # 最大上传文件大小(字节,默认 10MB)
  allowed_types:
    - image/jpeg
    - image/png
    - image/gif
    - image/webp
  allowed_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .webp
  max_width: 4096
  max_height: 4096

cors:
  allowed_origins:
    - "https://example.com"
  allowed_methods:
    - GET
    - POST
    - PUT
    - PATCH
    - DELETE
    - OPTIONS
  allowed_headers:
    - Content-Type
    - Content-Length
    - Accept-Encoding
    - Authorization
    - Cache-Control
    - X-Requested-With
    - X-CSRF-Token
  allow_credentials: true
  max_age: 600

security:
  login_rate_limit:
    window_seconds: 300
    max_attempts: 5
    block_seconds: 900
  password_policy:
    min_length: 8
    require_upper: true
    require_lower: true
    require_number: true
    require_special: false

email:
  enabled: true
  host: smtp.xxx.com
  port: 465
  username: your-username
  password: your-password
  from: your-email
  from_name: your-name
  use_tls: false
  use_ssl: true
  verify_code:
    expire_minutes: 10
    send_interval_seconds: 60
    max_attempts: 5
    length: 6

order:
  payment_expire_minutes: 15

以上文件是我在用的,可以根据官方模板和文档自己适当修改某些参数

database 的sqlite设置为 postgresdsn: host=设置为postgres的实际容器名

jwtuser_jwt 中的secret替换成 生成的随机密钥字符串;⚠️ 重要安全提醒:上线前必须修改 JWT 密钥

bootstrap 中设置的管理员默认用户名是 admin,后期不好更改,在这个时候可以修改。默认密码是 admin123

redisqueue中的 host: 127.0.0.1 修改为容器名:host: dujiaonext-redis ;密码password: "" 填写生成的随机字符,redisqueue两个密码需要一致

cors 里面的 allowed_origins:- "*" 意思是 允许 所有网站域名访问你的 API;如果你只想允许自己的站点,可以替换成自己域名,这样更安全

telegram_authemail 可以在部署好以后,在后台修改,这里就保持默认

编写 .env 文件

在 /dujiao-next/ 下新建 .env 文件

TAG=latest
TZ=Asia/Shanghai

API_PORT=8080
USER_PORT=8081
ADMIN_PORT=8082
REDIS_PORT=6379
POSTGRES_PORT=5432

# 默认管理员(仅首次初始化时生效)
DJ_DEFAULT_ADMIN_USERNAME=admin
DJ_DEFAULT_ADMIN_PASSWORD=admin123

# Redis
REDIS_PASSWORD=PUbUy1K63h61vcl6Xg+6m9TOYMfH0IghG4WOuJhHbjI=

# PostgreSQL(PostgreSQL 方案需要)
POSTGRES_DB=dujiao_next
POSTGRES_USER=dujiao
POSTGRES_PASSWORD=dujiao_pass

端口根据需要修改,REDIS_PASSWORD需要跟上面./config/config.yml文件中设置redis密码一致

数据库信息根据需要修改

编写 Compose 文件

PostgreSQL + Redis 生产环境

services:
  redis:
    image: redis:7-alpine
    container_name: dujiaonext-redis
    restart: unless-stopped
    environment:
      REDIS_PASSWORD: ${REDIS_PASSWORD}
    command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"]
    ports:
      - "${REDIS_PORT}:6379"
    volumes:
      - ./data/redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 3s
      retries: 10
    networks:
      - dujiao-net

  postgres:
    image: postgres:16-alpine
    container_name: dujiaonext-postgres
    restart: unless-stopped
    environment:
      TZ: ${TZ}
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    ports:
      - "${POSTGRES_PORT}:5432"
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - dujiao-net

  api:
    image: dujiaonext/api:${TAG}
    container_name: dujiaonext-api
    restart: unless-stopped
    environment:
      TZ: ${TZ}
      DJ_DEFAULT_ADMIN_USERNAME: ${DJ_DEFAULT_ADMIN_USERNAME}
      DJ_DEFAULT_ADMIN_PASSWORD: ${DJ_DEFAULT_ADMIN_PASSWORD}
    ports:
      - "${API_PORT}:8080"
    volumes:
      - ./config/config.yml:/app/config.yml:ro
      - ./data/uploads:/app/uploads
      - ./data/logs:/app/logs
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/health"]
      interval: 10s
      timeout: 3s
      retries: 10
    networks:
      - dujiao-net

  user:
    image: dujiaonext/user:${TAG}
    container_name: dujiaonext-user
    restart: unless-stopped
    environment:
      TZ: ${TZ}
    ports:
      - "${USER_PORT}:80"
    depends_on:
      api:
        condition: service_healthy
    networks:
      - dujiao-net

  admin:
    image: dujiaonext/admin:${TAG}
    container_name: dujiaonext-admin
    restart: unless-stopped
    environment:
      TZ: ${TZ}
    ports:
      - "${ADMIN_PORT}:80"
    depends_on:
      api:
        condition: service_healthy
    networks:
      - dujiao-net

networks:
  dujiao-net:
    driver: bridge

新建一个docker compose.yml文件,不用修改什么信息,直接粘贴使用

Nginx 反向代理

分域名部署(生产环境)

# 前台 User
server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}
    
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/nginx/certs/example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/example.com.privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:8081;
        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;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:8080/api/;
        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;
    }

    location /uploads/ {
        proxy_pass http://127.0.0.1:8080/uploads/;
        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;
    }
}

# 后台 Admin
server {
    listen 80;
    server_name admin.example.com;
    return 301 https://admin.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name admin.example.com;

    ssl_certificate /etc/nginx/certs/example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/example.com.privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:8082;
        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;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:8080/api/;
        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;
    }

    location /uploads/ {
        proxy_pass http://127.0.0.1:8080/uploads/;
        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;
    }
}

官方模板没有SSL证书设置,上面粘贴的是我自用的版本

需要准备两个域名:前台:example.com 和 后台管理:admin.example.com

将上面文件中的前台、后台域名替换成自己的

因为我用的其他服务器做的反代,所以还需要把http://127.0.0.1都修改为程序运行的服务器IP

启动 Docker Compose

docker compose --env-file .env -f docker-compose.yml up -d
图片[1]-Docker Compose 部署新版独角数卡 Dujiao-Next - 我是怪兽-我是怪兽

当出现以上信息,就可以访问了

前台:https://example.com

后台:https://admin.example.com

© 版权声明
THE END
喜欢就支持一下吧!
点赞0发电
评论 抢沙发
头像
尊重知识,真诚评论!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容