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中显式添加:
yamlextra_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/;