跳到主要内容

Docker部署

精简发布文件

如果需要精简发布后的文件,也就是删除不必要的文件夹,可以编辑 Web 项目的 .csproj 并添加 <SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>,如:

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>
</PropertyGroup>

若无需生成 .pdb 文件,可以继续添加:

<PropertyGroup>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>

一、Docker部署概述

1.1 部署方式

Docker 中部署 ThingsGateway 有两种方式:

  • 发布后构建:此方式是先发布网站后再构建镜像,这样可以减少不必要的构建层,而且还能缩减镜像大小。(推荐)
  • 编译+构建+发布:也就是说在 Dockerfile 中配置网站从构建到发布的完整过程,此方式会速度慢,而且会产生冗余层,增加镜像大小。

1.2 优势

使用 Docker 部署 ThingsGateway 具有以下优势:

  • 环境一致性:确保开发、测试和生产环境的一致性
  • 快速部署:通过镜像快速部署新实例
  • 易于扩展:支持水平扩展和负载均衡
  • 资源隔离:容器化隔离,提高系统安全性
  • 便于维护:统一的管理和监控方式

二、发布后构建方式

2.1 编写 Dockerfile

创建 Dockerfile 文件,内容如下:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
COPY . /app
WORKDIR /app
EXPOSE 80
#linux安装
RUN echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ sid main contrib non-free" > /etc/apt/sources.list
RUN apt-get update && apt-get -y install libfontconfig1
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll","--urls","http://*:7200"]

2.2 Dockerfile 参数说明

参数说明
FROM指定基础镜像,使用 .NET 8.0 ASP.NET 运行时
COPY将发布文件复制到容器中的 /app 目录
WORKDIR设置工作目录为 /app
EXPOSE暴露容器端口 80
RUN安装必要的系统依赖(字体配置库)
ENTRYPOINT设置容器启动时执行的命令
提示

git仓库中已经包含 Dockerfile 文件

2.3 拷贝 Dockerfile

将编写好的 Dockerfile 文件(注意 D 大写)拷贝到发布网站的根目录下。

2.4 构建 Docker 镜像

在网站发布后的路径根目录下(必须含 Dockerfile)打开 CMD/PowerShell 执行构建命令:

docker build -t thingsgateway:1.0 .
特别注意

命令末尾的 . 不能省略,表示使用当前目录作为构建上下文

2.5 启动容器

docker run --name thingsgateway -p 5000:80 --restart=always -d thingsgateway:1.0

参数说明

参数说明
--name容器名称
-p端口映射,格式:主机端口:容器端口
--restart重启策略,always 表示自动重启
-d后台运行
thingsgateway:1.0镜像名称和版本
.NET880 端口问题

在使用 .NET8,默认的端口由原来的 80 端口变成了 8080查看相关说明

三、Docker Compose 部署

3.1 Docker Compose 简介

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 YAML 文件配置应用程序的服务,然后使用一个命令创建和启动所有服务。

3.2 编写 docker-compose.yml

创建 docker-compose.yml 文件,内容如下:

version: '3.8'

services:
thingsgateway:
image: thingsgateway:1.0
container_name: thingsgateway
ports:
- "5000:80"
volumes:
- ./data:/app/Data
- ./logs:/app/Logs
- ./plugins:/app/Plugins
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
restart: always
networks:
- thingsgateway-network

networks:
thingsgateway-network:
driver: bridge

3.3 docker-compose.yml 参数说明

参数说明
versionCompose 文件版本
services定义服务列表
image使用的镜像
ports端口映射
volumes数据卷挂载,实现数据持久化
environment环境变量配置
restart重启策略
networks网络配置

3.4 启动服务

docker-compose up -d

3.5 停止服务

docker-compose down

3.6 查看日志

docker-compose logs -f thingsgateway

四、数据持久化配置

4.1 数据卷挂载

为了确保容器重启后数据不丢失,需要挂载数据卷:

docker run --name thingsgateway \
-p 5000:80 \
-v /path/to/data:/app/Data \
-v /path/to/logs:/app/Logs \
-v /path/to/plugins:/app/Plugins \
--restart=always \
-d thingsgateway:1.0

4.2 挂载目录说明

目录说明
/app/Data数据库和配置文件目录
/app/Logs日志文件目录
/app/Plugins插件目录

4.3 权限配置

在 Linux 系统中,需要确保挂载目录的权限正确:

# 创建目录
mkdir -p /path/to/data /path/to/logs /path/to/plugins

# 设置权限
chmod -R 777 /path/to/data /path/to/logs /path/to/plugins

五、网络配置

5.1 自定义网络

创建自定义网络,便于容器间通信:

docker network create thingsgateway-network

5.2 连接到网络

docker run --name thingsgateway \
--network thingsgateway-network \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0

5.3 网络模式

网络模式说明
bridge桥接模式(默认)
host主机模式,容器使用主机网络
none无网络模式

六、日志管理

6.1 查看容器日志

docker logs -f thingsgateway

6.2 日志配置

docker-compose.yml 中配置日志驱动:

services:
thingsgateway:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

6.3 日志轮转

配置日志文件大小和数量,避免日志文件过大:

参数说明
max-size单个日志文件最大大小
max-file保留的日志文件数量

七、性能优化

7.1 资源限制

限制容器使用的资源,避免资源耗尽:

docker run --name thingsgateway \
--memory="2g" \
--cpus="2.0" \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0

7.2 资源参数说明

参数说明
--memory限制内存使用
--cpus限制CPU使用

7.3 镜像优化

使用多阶段构建

# 构建阶段
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish

# 运行阶段
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll"]

使用 Alpine 镜像

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS base
COPY . /app
WORKDIR /app
EXPOSE 80
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll"]
Alpine 镜像

Alpine 镜像体积更小,但可能存在兼容性问题,建议先测试

八、安全配置

8.1 非 root 用户运行

创建非 root 用户运行容器:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
RUN groupadd -r thingsgateway && useradd -r -g thingsgateway thingsgateway
COPY . /app
WORKDIR /app
RUN chown -R thingsgateway:thingsgateway /app
USER thingsgateway
EXPOSE 80
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll"]

8.2 只读文件系统

将容器文件系统设置为只读,提高安全性:

docker run --name thingsgateway \
--read-only \
--tmpfs /tmp \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0

8.3 安全扫描

使用 Docker 安全扫描工具检查镜像漏洞:

docker scan thingsgateway:1.0

九、常见问题排查

9.1 容器无法启动

现象:容器启动后立即退出

可能原因

  • 端口被占用
  • 配置文件错误
  • 权限不足

排查步骤

  1. 查看容器日志:docker logs thingsgateway
  2. 检查端口占用:netstat -ano | findstr 5000
  3. 检查配置文件语法
  4. 检查文件权限

9.2 数据丢失

现象:容器重启后数据丢失

可能原因

  • 未挂载数据卷
  • 数据卷路径错误

解决方案

  1. 确保正确挂载数据卷
  2. 检查数据卷路径是否正确
  3. 使用 docker volume 命令管理数据卷

9.3 性能问题

现象:容器运行缓慢

可能原因

  • 资源限制过低
  • 网络延迟高
  • 数据库性能问题

优化建议

  1. 增加内存和CPU限制
  2. 优化网络配置
  3. 优化数据库查询
  4. 使用缓存机制

9.4 网络连接问题

现象:容器无法访问外部网络

可能原因

  • DNS 配置错误
  • 防火墙阻止
  • 网络模式配置错误

排查步骤

  1. 检查 DNS 配置
  2. 检查防火墙规则
  3. 尝试 ping 外部地址
  4. 检查网络模式配置

十、备份与恢复

10.1 数据备份

# 备份数据卷
docker run --rm -v thingsgateway-data:/data -v $(pwd):/backup alpine tar czf /backup/thingsgateway-backup.tar.gz /data

10.2 数据恢复

# 恢复数据卷
docker run --rm -v thingsgateway-data:/data -v $(pwd):/backup alpine tar xzf /backup/thingsgateway-backup.tar.gz -C /

10.3 镜像导出

# 导出镜像
docker save -o thingsgateway.tar thingsgateway:1.0

10.4 镜像导入

# 导入镜像
docker load -i thingsgateway.tar

十一、监控与维护

11.1 容器监控

# 查看容器状态
docker ps -a

# 查看容器资源使用
docker stats thingsgateway

# 查看容器详细信息
docker inspect thingsgateway

11.2 容器更新

# 停止旧容器
docker stop thingsgateway

# 删除旧容器
docker rm thingsgateway

# 拉取新镜像
docker pull thingsgateway:2.0

# 启动新容器
docker run --name thingsgateway -p 5000:80 --restart=always -d thingsgateway:2.0

11.3 定期维护

  • 定期清理未使用的镜像和容器
  • 定期备份数据
  • 定期检查日志文件大小
  • 定期更新镜像版本
# 清理未使用的镜像
docker image prune -a

# 清理未使用的容器
docker container prune

# 清理未使用的卷
docker volume prune

十二、最佳实践

12.1 镜像管理

  • 使用语义化版本号
  • 定期更新基础镜像
  • 使用多阶段构建减小镜像体积
  • 标记镜像版本,便于回滚

12.2 容器管理

  • 使用 Docker Compose 管理多容器应用
  • 配置合理的资源限制
  • 设置自动重启策略
  • 使用健康检查

12.3 数据管理

  • 使用数据卷实现数据持久化
  • 定期备份数据
  • 使用命名卷便于管理
  • 注意数据卷权限

12.4 安全管理

  • 使用非 root 用户运行容器
  • 定期扫描镜像漏洞
  • 限制容器权限
  • 使用只读文件系统

12.5 日志管理

  • 配置日志轮转
  • 集中收集日志
  • 定期清理日志
  • 监控日志大小

十三、常见问题

Q1: 如何修改容器端口映射?

A: 停止并删除现有容器,然后使用新的端口映射重新创建容器:

docker stop thingsgateway
docker rm thingsgateway
docker run --name thingsgateway -p 8080:80 --restart=always -d thingsgateway:1.0

Q2: 如何进入容器内部?

A: 使用 docker exec 命令:

docker exec -it thingsgateway /bin/bash

Q3: 如何查看容器日志?

A: 使用 docker logs 命令:

docker logs -f thingsgateway

Q4: 如何限制容器资源使用?

A: 在启动容器时指定资源限制:

docker run --name thingsgateway \
--memory="2g" \
--cpus="2.0" \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0

Q5: 如何实现容器自动重启?

A: 使用 --restart 参数:

docker run --name thingsgateway \
--restart=always \
-p 5000:80 \
-d thingsgateway:1.0

重启策略选项:

  • no:不自动重启(默认)
  • on-failure:容器异常退出时重启
  • always:总是重启
  • unless-stopped:除非手动停止,否则总是重启

Q6: 如何在容器中使用主机网络?

A: 使用 --network host 参数:

docker run --name thingsgateway \
--network host \
--restart=always \
-d thingsgateway:1.0

Q7: 如何查看容器资源使用情况?

A: 使用 docker stats 命令:

docker stats thingsgateway

Q8: 如何导出和导入镜像?

A: 使用 docker savedocker load 命令:

# 导出镜像
docker save -o thingsgateway.tar thingsgateway:1.0

# 导入镜像
docker load -i thingsgateway.tar

Q9: 如何清理未使用的 Docker 资源?

A: 使用 docker prune 命令:

# 清理未使用的镜像
docker image prune -a

# 清理未使用的容器
docker container prune

# 清理未使用的卷
docker volume prune

# 清理所有未使用的资源
docker system prune -a

Q10: 如何配置容器时区?

A: 使用环境变量或挂载时区文件:

docker run --name thingsgateway \
-e TZ=Asia/Shanghai \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0

docker run --name thingsgateway \
-v /etc/localtime:/etc/localtime:ro \
-p 5000:80 \
--restart=always \
-d thingsgateway:1.0