射击训练系统 Docker 部署方案(OpenCloudOS 9.4)

1. 环境要求

项目 要求
操作系统 OpenCloudOS 9.4
内存 最低 2GB,推荐 4GB+
磁盘 最低 20GB 可用空间
网络 可访问外网(拉取镜像)或配置私有镜像仓库
用户 root 或具有 sudo 权限的用户

2. Docker 安装

2.1 卸载旧版本

bash 复制代码
sudo yum remove -y docker docker-client docker-client-latest \
    docker-common docker-latest docker-latest-logrotate \
    docker-logrotate docker-engine podman runc

2.2 安装依赖

bash 复制代码
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

2.3 添加 Docker 仓库

bash 复制代码
# 使用阿里云镜像源(国内服务器推荐)
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 替换仓库中的下载地址为阿里云加速(OpenCloudOS 兼容 CentOS 9 仓库)
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

2.4 安装 Docker

bash 复制代码
sudo yum makecache
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

2.5 启动并设置开机自启

bash 复制代码
sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl enable containerd

2.6 验证安装

bash 复制代码
docker --version
docker compose version
docker run --rm hello-world

2.7 配置 Docker 镜像加速

bash 复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": [
    "https://docker.mirror.example.com"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

2.8 配置用户权限(可选)

bash 复制代码
# 将当前用户加入 docker 组,免 sudo 执行 docker 命令
sudo usermod -aG docker $USER

# 使组变更立即生效
newgrp docker

2.9 防火墙配置

bash 复制代码
# 开放所需端口
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=5003/tcp
sudo firewall-cmd --reload

# 查看已开放端口
sudo firewall-cmd --list-ports

3. 项目目录结构

部署时在服务器上创建如下目录结构:

复制代码
/home/shoot.example.tech/
├── docker-compose.yml          # 编排文件
├── api/                        # 后端 API 服务
│   ├── Dockerfile
│   ├── shooting                # 可执行文件
│   ├── appsettings.json
│   └── wwwroot/
├── manage/                     # 管理后台前端
│   └── dist/                   # 构建产物
├── debugpage/                  # 调试页面
│   └── dist/
├── nginx/                      # Nginx 配置
│   └── nginx.conf
├── do.sh                       # 容器/镜像清理脚本
└── logs/                       # 日志目录
    └── api/

4. Docker Compose 编排

创建 docker-compose.yml 文件:

yaml 复制代码
version: "3.8"

services:
  # ==================== API 服务 ====================
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    container_name: shooting-api
    restart: always
    ports:
      - "5003:5003"
    volumes:
      - ./api/wwwroot:/app/wwwroot
      - ./logs/api:/app/logs
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://+:5003
    networks:
      - shooting-net

  # ==================== Nginx 反向代理 ====================
  nginx:
    image: nginx:1.24
    container_name: shooting-nginx
    restart: always
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./manage/dist:/home/manage:ro
      - ./debugpage/dist:/home/debugpage:ro
    depends_on:
      - api
    networks:
      - shooting-net

networks:
  shooting-net:
    driver: bridge

注意 :TTS(5005)、串口(5004)、摄像头(5006)等服务如需容器化部署,可参照 api 服务格式在 docker-compose.yml 中追加服务定义。

5. Dockerfile 说明

项目 API 的 Dockerfile(位于 src/api/Dockerfile):

dockerfile 复制代码
# 基于 ASP.NET 8.0 运行时镜像
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app

# 暴露端口 5003
EXPOSE 5003

# 设置环境变量
ENV ASPNETCORE_URLS=http://+:5003
ENV ASPNETCORE_ENVIRONMENT=Production

# 复制已发布的应用程序文件
COPY . .

# 创建日志和静态资源目录
RUN mkdir -p /app/logs /app/wwwroot

# 给可执行文件添加执行权限
RUN chmod +x ./shooting

# 确保目录权限
RUN chmod -R 755 /app

# 设置入口点
ENTRYPOINT ["./shooting"]

发布与构建

bash 复制代码
# 1. 在开发机上发布 API 项目
dotnet publish src/api/shooting.csproj -c Release -o publish/api

# 2. 将 Dockerfile 复制到发布目录
cp src/api/Dockerfile publish/api/

# 3. 上传到服务器后构建镜像
cd /home/shoot.example.tech
docker build -t shooting-api:latest ./api

6. 部署操作

6.1 首次部署

bash 复制代码
# 上传项目文件到服务器后执行
cd /home/shoot.example.tech

# 构建并启动所有服务
docker compose up -d --build

# 查看运行状态
docker compose ps

# 查看日志
docker compose logs -f api
docker compose logs -f nginx

6.2 更新部署

bash 复制代码
cd /home/shoot.example.tech

# 方式一:仅更新 API 服务
docker compose build api
docker compose up -d api

# 方式二:使用清理脚本后重新部署
bash do.sh shooting-api
docker compose up -d --build api

# 方式三:全量更新
docker compose down
docker compose up -d --build

6.3 停止服务

bash 复制代码
# 停止所有服务
docker compose down

# 停止单个服务
docker compose stop api

7. 数据库连接配置

API 服务在 Docker 容器中运行时,数据库和 Redis 连接地址需使用 host.docker.internal 替代 localhost,以访问宿主机服务:

json 复制代码
{
  "ConnectionStrings": {
    "DbContext": "server=host.docker.internal;port=3306;user id=root;password=xxx;database=dbshoot;",
    "Redis": "host.docker.internal,password=xxx,defaultDatabase=2,poolsize=50,ssl=false,writeBuffer=10240,prefix="
  }
}

Linux 系统注意host.docker.internal 在 Linux 上需在 docker-compose.yml 中显式添加:

yaml 复制代码
extra_hosts:
  - "host.docker.internal:host-gateway"

8. Nginx 反向代理配置

Nginx 负责统一入口,将请求转发到各后端服务:

路径 目标服务 说明
/ 静态文件 /home/manage 管理后台前端
/debug/ 静态文件 /home/debugpage 调试页面
/interface/ http://api:5003/ API 服务
/tts/ http://127.0.0.1:5005/ 文本转语音服务
/serial/ http://127.0.0.1:5004/ 串口服务
/camera/ http://127.0.0.1:5006/ 摄像头服务

容器化后,127.0.0.1 应改为 Docker 服务名,如 http://api:5003/

9. 常用运维命令

bash 复制代码
# 查看所有容器状态
docker compose ps

# 查看容器日志
docker compose logs -f --tail 100 api

# 进入容器调试
docker compose exec api /bin/bash

# 重启单个服务
docker compose restart api

# 查看资源占用
docker stats

# 清理无用镜像和容器
docker system prune -a

# 查看镜像列表
docker images

# 查看容器详情
docker inspect shooting-api

10. 常见问题

Q1: 容器内无法连接宿主机数据库

确认 appsettings.json 中数据库地址使用 host.docker.internal,并在 docker-compose.yml 的 api 服务中添加:

yaml 复制代码
extra_hosts:
  - "host.docker.internal:host-gateway"

Q2: 端口被占用

bash 复制代码
# 查看端口占用
netstat -tlnp | grep 5003

# 修改 docker-compose.yml 中的端口映射
ports:
  - "5004:5003"   # 将宿主机 5004 映射到容器 5003

Q3: 镜像拉取失败

检查 Docker 镜像加速配置,确保 daemon.json 中的镜像源可用,然后重启 Docker:

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

Q4: 容器启动后立即退出

bash 复制代码
# 查看退出日志
docker compose logs api

# 常见原因:
# - appsettings.json 配置错误
# - 可执行文件缺少执行权限
# - 端口冲突

Q5: Nginx 502 Bad Gateway

确认 API 容器正常运行,且 nginx.conf 中的代理地址与 Docker 网络中的服务名一致:

nginx 复制代码
# 容器化部署时使用服务名
proxy_pass http://api:5003/;
相关推荐
NCU_wander1 小时前
LB HA(high avaliablity)和nginx
运维·nginx
徐子元竟然被占了!!1 小时前
Linux磁盘扩容
linux·运维·服务器
徐子元竟然被占了!!1 小时前
Linux的lsblk
linux·运维·服务器
“码”力全开1 小时前
解耦安防黑盒:基于 Docker 容器化与 GB28181/RTSP 双协议架构的 AI 边缘计算视频平台(全源码交付)
人工智能·docker·架构
Plastic garden1 小时前
K8s(12)RuoYi on K8s 全流程 · 全思路 · 全排错 · 全配置
云原生·容器·kubernetes
专注API从业者1 小时前
告别手动翻页!基于淘宝商品接口 + Open Claw 实现自动化选品与实时监控(附完整 Python 代码)
大数据·运维·数据库·自动化
拦路雨g1 小时前
VMware centos磁盘容量扩容
linux·运维·centos
休息一下…2 小时前
能用的Docker镜像
运维·docker·容器
AI服务老曹2 小时前
解耦安防黑盒:基于 Docker 的国标 GB28181 与 RTSP 统一接入 AI 视频管理平台架构设计(附源码交付与边缘计算实践)
人工智能·docker·音视频