Debian 生产环境 Docker 部署实战:安装、数据盘规划、日志限制与安全配置全流程
Debian Docker部署教程|生产环境实测
在实际生产环境中,Docker 已经成为后端服务部署、微服务架构落地、持续集成与持续交付的重要基础设施。相比传统的“直接在服务器上安装运行环境”的方式,Docker 能够将应用、依赖、配置以镜像形式统一管理,减少环境差异带来的问题,提高部署效率和可维护性。
本文以 Debian 系统 为基础,结合生产环境常见需求,完整讲解 Docker 的安装、配置、镜像加速、数据目录规划、容器部署、防火墙处理、日志管理、开机自启以及常见问题排查。本文内容偏实战,适合用于云服务器、物理机、内网服务器等生产环境部署参考。
一、环境说明
本文演示环境如下:
| 项目 | 说明 |
|---|---|
| 操作系统 | Debian 11 / Debian 12 |
| 用户权限 | root 或具备 sudo 权限的用户 |
| CPU 架构 | x86_64 / amd64 |
| 网络环境 | 可访问外网,或已配置代理 / 内网源 |
| Docker 版本 | Docker CE 最新稳定版 |
查看系统版本:
cat /etc/os-release
查看内核版本:
uname -r
一般来说,Debian 11、Debian 12 均可稳定运行 Docker。生产环境建议使用较新的内核版本,避免因内核过旧导致 overlay2、cgroup、iptables 等功能异常。
二、部署前准备
在安装 Docker 之前,建议先对服务器进行基础检查和初始化,尤其是生产环境,不建议拿到服务器后直接安装运行。
1. 更新系统软件包
sudo apt update
sudo apt upgrade -y
如果是新服务器,可以先升级基础软件包,避免后续依赖版本过旧。
2. 安装必要工具
sudo apt install -y ca-certificates curl gnupg lsb-release apt-transport-https
这些工具主要用于添加 Docker 官方软件源、导入 GPG 密钥以及通过 HTTPS 安装软件包。
3. 检查磁盘空间
Docker 镜像、容器层、日志、数据卷都会占用磁盘空间。生产环境中,如果 Docker 默认安装在系统盘,时间久了很容易导致 /var/lib/docker 占满根分区。
查看磁盘:
df -h
查看目录占用:
du -sh /var/lib/docker 2>/dev/null
如果业务容器较多,建议提前规划 Docker 数据目录,例如挂载到独立数据盘:
/data/docker
三、卸载旧版本 Docker
如果服务器上曾经安装过旧版本 Docker,建议先卸载,避免版本冲突。
sudo apt remove -y docker docker-engine docker.io containerd runc
注意:这一步只会卸载软件包,一般不会删除 /var/lib/docker 下的数据。如果是生产环境已有业务容器,务必先确认数据和容器状态,不要盲目操作。
四、安装 Docker 官方源
Docker 官方源比 Debian 默认源更新,生产环境更推荐使用 Docker 官方仓库安装 Docker CE。
1. 创建密钥目录
sudo install -m 0755 -d /etc/apt/keyrings
2. 添加 Docker GPG 密钥
curl -fsSL https://download.docker.com/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
设置权限:
sudo chmod a+r /etc/apt/keyrings/docker.gpg
3. 添加 Docker 软件源
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
更新软件包索引:
sudo apt update
如果此处出现无法访问 Docker 官方源的问题,通常是网络、DNS、代理或机房出口限制导致,可以考虑配置代理或使用可信的国内镜像源。
五、安装 Docker Engine
执行以下命令安装 Docker:
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后,查看 Docker 版本:
docker version
查看服务状态:
sudo systemctl status docker
如果 Docker 没有自动启动,可以执行:
sudo systemctl enable docker
sudo systemctl start docker
测试运行:
sudo docker run hello-world
如果看到类似以下信息,说明 Docker 已成功安装:
Hello from Docker!
This message shows that your installation appears to be working correctly.
六、配置普通用户执行 Docker
默认情况下,Docker 命令需要 root 权限。如果希望普通用户无需每次输入 sudo,可以将用户加入 docker 用户组。
sudo usermod -aG docker $USER
然后退出当前 SSH 会话,重新登录。
验证:
docker ps
如果没有权限错误,说明配置成功。
注意:加入 docker 组的用户几乎等同于拥有 root 权限。生产环境中不建议随意给普通账号添加 docker 权限,应遵循最小权限原则。
七、配置 Docker 数据目录
生产环境非常建议将 Docker 数据目录放到独立数据盘,避免系统盘被镜像、容器日志、volume 数据撑满。
Docker 默认数据目录是:
/var/lib/docker
假设我们希望修改为:
/data/docker
1. 停止 Docker 服务
sudo systemctl stop docker
sudo systemctl stop containerd
2. 创建新目录
sudo mkdir -p /data/docker
3. 迁移旧数据
如果已经有容器和镜像,需要迁移:
sudo rsync -avx /var/lib/docker/ /data/docker/
如果是全新环境,这一步可以跳过。
4. 修改 Docker daemon 配置
创建或编辑:
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
写入:
{
"data-root": "/data/docker",
"storage-driver": "overlay2"
}
5. 启动 Docker
sudo systemctl start containerd
sudo systemctl start docker
确认配置是否生效:
docker info | grep "Docker Root Dir"
如果输出为:
Docker Root Dir: /data/docker
说明配置成功。
确认无误后,可以根据情况清理旧目录:
sudo mv /var/lib/docker /var/lib/docker.bak
观察一段时间业务正常后再删除备份。
八、配置镜像加速与日志限制
在生产环境中,Docker 的 daemon.json 非常重要。它不仅可以配置数据目录,也可以配置日志大小、镜像加速、cgroup 驱动等。
推荐配置示例:
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"exec-opts": ["native.cgroupdriver=systemd"]
}
说明:
data-root:Docker 数据目录。storage-driver:推荐使用overlay2。log-driver:默认 json-file,简单稳定。max-size:单个容器日志文件最大 100MB。max-file:最多保留 3 个日志文件。native.cgroupdriver=systemd:生产环境中更适合与 systemd 管理方式配合。
修改配置后重启 Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
查看是否生效:
docker info
关于镜像加速
如果服务器访问 Docker Hub 较慢,可以配置镜像加速。不同地区可用的加速地址会变化,建议使用自己云厂商提供的镜像服务,例如阿里云、腾讯云、华为云等。
示例:
{
"registry-mirrors": [
"https://your-mirror.example.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
注意:生产环境不建议随意使用来源不明的镜像加速地址,尤其是涉及基础镜像和安全合规的场景。
九、使用 Docker Compose 部署服务
现在 Docker Compose 已经作为 Docker 插件安装,命令为:
docker compose version
注意是:
docker compose
而不是旧版的:
docker-compose
虽然旧版命令仍然有人使用,但新环境更推荐使用 Docker Compose Plugin。
下面以部署 Nginx 为例。
1. 创建项目目录
sudo mkdir -p /opt/apps/nginx
cd /opt/apps/nginx
2. 编写 docker-compose.yml
services:
nginx:
image: nginx:1.25-alpine
container_name: nginx-prod
restart: always
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
- ./conf:/etc/nginx/conf.d:ro
- ./logs:/var/log/nginx
networks:
- webnet
networks:
webnet:
driver: bridge
创建测试页面:
mkdir -p html conf logs
echo "Debian Docker production test" > html/index.html
如果暂时不需要自定义 Nginx 配置,可以先创建一个默认配置:
cat > conf/default.conf <<'EOF'
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
EOF
3. 启动服务
docker compose up -d
查看容器:
docker ps
查看日志:
docker logs nginx-prod
访问:
curl http://127.0.0.1
如果返回:
Debian Docker production test
说明 Nginx 容器已经正常运行。
十、生产环境部署目录建议
很多团队刚开始使用 Docker 时,会将 compose 文件、配置文件、日志文件到处乱放,后期维护非常困难。生产环境建议统一目录结构。
推荐:
/opt/apps/
├── nginx/
│ ├── docker-compose.yml
│ ├── conf/
│ ├── html/
│ └── logs/
├── mysql/
│ ├── docker-compose.yml
│ ├── data/
│ ├── conf/
│ └── logs/
└── redis/
├── docker-compose.yml
├── data/
└── conf/
如果是业务项目,可以这样:
/opt/apps/myapp/
├── docker-compose.yml
├── .env
├── nginx/
├── app/
├── logs/
└── data/
这种方式的优点:
- 每个服务独立目录,方便迁移。
- 配置、数据、日志清晰分离。
- 方便使用 Git 管理 compose 文件和配置模板。
- 便于备份和故障恢复。
十一、防火墙与端口开放
Docker 会自动操作 iptables 规则,这一点在生产环境中非常重要。很多时候你会发现系统防火墙明明限制了端口,但 Docker 映射端口后仍可能被外部访问。
如果使用云服务器,通常需要同时关注两层:
- 云厂商安全组;
- 服务器本机防火墙。
查看监听端口:
ss -tulnp
查看 Docker 映射端口:
docker ps
如果使用 UFW,需要特别注意 Docker 与 UFW 的兼容问题。Debian 上如果启用了 UFW,Docker 可能绕过 UFW 规则直接开放端口。
生产环境中建议:
- 不要随意使用
0.0.0.0:端口暴露数据库。 - MySQL、Redis、PostgreSQL 等只允许内网访问。
- 能不映射到宿主机的服务就不要映射。
- 使用自定义 Docker 网络进行容器间通信。
- 对公网入口统一使用 Nginx、Traefik 或网关服务。
例如 Redis 不建议这样:
ports:
- "6379:6379"
如果只是内部容器访问,可以不写 ports,使用 networks 即可。
十二、部署 MySQL 示例
下面给出一个相对基础的 MySQL Compose 示例,适合测试和简单生产场景。正式生产环境还需考虑主从、备份、监控、慢查询、参数优化等。
services:
mysql:
image: mysql:8.0
container_name: mysql-prod
restart: always
environment:
MYSQL_ROOT_PASSWORD: "请替换为强密码"
MYSQL_DATABASE: "appdb"
MYSQL_USER: "appuser"
MYSQL_PASSWORD: "请替换为强密码"
TZ: "Asia/Shanghai"
ports:
- "127.0.0.1:3306:3306"
volumes:
- ./data:/var/lib/mysql
- ./conf:/etc/mysql/conf.d
- ./logs:/var/log/mysql
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
networks:
- appnet
networks:
appnet:
driver: bridge
这里的端口绑定为:
127.0.0.1:3306:3306
表示只允许宿主机本机访问,不直接暴露到公网。这比直接写 3306:3306 更安全。
启动:
docker compose up -d
查看日志:
docker logs mysql-prod
进入容器:
docker exec -it mysql-prod mysql -uroot -p
十三、容器开机自启策略
Docker Compose 中常见的重启策略包括:
restart: always
或:
restart: unless-stopped
两者区别:
always:无论容器因为什么原因退出,Docker 启动后都会自动拉起。unless-stopped:除非手动停止,否则 Docker 启动后会自动拉起。
生产环境中常用:
restart: always
确保 Docker 服务本身开机启动:
sudo systemctl enable docker
sudo systemctl enable containerd
查看:
systemctl is-enabled docker
十四、日志查看与清理
查看容器日志:
docker logs 容器名
实时查看:
docker logs -f 容器名
查看最近 100 行:
docker logs --tail=100 容器名
如果没有配置日志限制,容器日志可能无限增长。查看 Docker 容器日志文件:
docker inspect 容器名 | grep LogPath
通常位于:
/data/docker/containers/容器ID/容器ID-json.log
生产环境建议一定要配置前文提到的:
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
如果某个容器日志已经很大,可以清空日志:
sudo truncate -s 0 /path/to/container-json.log
但这只是临时处理,根本方案仍然是配置日志轮转和业务日志规范。
十五、镜像与容器清理
随着使用时间增加,服务器上会留下很多无用镜像、停止的容器、构建缓存等。
查看磁盘占用:
docker system df
清理停止的容器:
docker container prune
清理无用镜像:
docker image prune
清理未使用的网络:
docker network prune
清理构建缓存:
docker builder prune
谨慎执行以下命令:
docker system prune -a
它会删除所有未被容器使用的镜像,可能导致下次启动或部署时需要重新拉取镜像。生产环境执行前应确认影响范围。
十六、备份与恢复建议
Docker 部署并不等于数据安全。容器可以随时重建,但数据卷、数据库文件、配置文件必须做好备份。
建议备份内容:
/opt/apps下的 compose 文件和配置文件;- 数据库数据目录;
- Nginx 配置和证书;
- 业务上传文件;
.env环境变量文件;- 重要镜像版本记录。
例如备份某个应用目录:
tar -czf myapp-backup-$(date +%F).tar.gz /opt/apps/myapp
如果是数据库,不能只简单打包 data 目录,尤其是服务正在运行时。更推荐使用数据库自身工具,例如 MySQL:
docker exec mysql-prod mysqldump -uroot -p appdb > appdb.sql
恢复时:
docker exec -i mysql-prod mysql -uroot -p appdb < appdb.sql
生产环境建议将备份上传到异地存储,例如对象存储、备份服务器或内网 NAS,并定期做恢复演练。
十七、安全加固建议
Docker 部署生产服务时,安全问题不能忽视。
1. 不要使用 latest 标签
不推荐:
image: nginx:latest
推荐:
image: nginx:1.25-alpine
原因是 latest 不代表稳定,也不代表最新安全版本。它可能在不经意间发生变化,导致部署结果不可控。
2. 最小化端口暴露
数据库、缓存、消息队列等服务不要直接暴露公网。尽量使用内网访问,或通过 VPN、堡垒机访问。
3. 使用强密码和环境变量文件
可以将敏感配置放入 .env 文件:
MYSQL_ROOT_PASSWORD=StrongPasswordExample
MYSQL_DATABASE=appdb
Compose 中引用:
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
但 .env 文件也需要妥善保护,权限建议:
chmod 600 .env
4. 限制容器权限
不要轻易使用:
privileged: true
除非你明确知道这样做的风险。privileged 会让容器拥有非常高的宿主机访问能力,生产环境应尽量避免。
5. 定期更新镜像
定期检查基础镜像安全漏洞,及时更新:
docker compose pull
docker compose up -d
更新前建议先在测试环境验证,避免线上服务因版本变化出现兼容问题。
十八、常见问题排查
1. Docker 服务启动失败
查看状态:
systemctl status docker
查看日志:
journalctl -u docker -xe
常见原因包括:
daemon.json格式错误;- 数据目录权限异常;
- iptables 配置冲突;
- containerd 未正常运行;
- 磁盘空间不足。
验证 JSON 格式:
python3 -m json.tool /etc/docker/daemon.json
2. 拉取镜像失败
可能原因:
- DNS 解析失败;
- Docker Hub 网络不可达;
- 镜像名称错误;
- 架构不匹配;
- 私有仓库未登录。
测试 DNS:
ping registry-1.docker.io
登录私有仓库:
docker login registry.example.com
3. 容器启动后立即退出
查看日志:
docker logs 容器名
查看退出状态:
docker ps -a
常见原因:
- 配置文件错误;
- 端口冲突;
- 数据目录权限不对;
- 环境变量缺失;
- 镜像启动命令不符合预期。
4. 端口无法访问
排查顺序:
docker ps
ss -tulnp
curl http://127.0.0.1:端口
然后检查:
- 容器是否正常运行;
- 端口是否映射;
- 服务是否监听
0.0.0.0; - 云安全组是否放行;
- 本机防火墙是否拦截;
- Nginx 或网关配置是否正确。
十九、生产环境实测总结
在 Debian 上部署 Docker 整体非常稳定,尤其是 Debian 11 和 Debian 12,配合 Docker 官方源、overlay2 存储驱动以及 systemd 管理方式,可以满足大多数生产场景需求。
从实际生产经验来看,Docker 部署最容易出问题的并不是安装过程,而是后续运维细节,例如:
- Docker 数据目录没有规划,导致系统盘被占满;
- 容器日志没有限制,几天内产生几十 GB 日志;
- 数据库端口直接暴露公网,存在安全风险;
- 使用
latest镜像导致版本不可控; - Compose 文件缺少统一目录规范,后期维护困难;
- 没有备份策略,容器重建后数据丢失;
- 防火墙与 Docker iptables 规则理解不足,导致端口暴露异常。
因此,生产环境部署 Docker 时,建议重点做好以下几点:
- 使用官方源安装 Docker CE;
- 将 Docker 数据目录放到独立数据盘;
- 配置容器日志大小限制;
- 使用 Docker Compose 管理服务;
- 明确区分配置、数据、日志目录;
- 不随意暴露数据库、缓存等敏感端口;
- 使用固定版本镜像,不使用
latest; - 做好备份、监控和定期更新;
- 上线前在测试环境验证 compose 文件;
- 建立统一的部署和回滚流程。
二十、完整推荐配置示例
最后给出一份较通用的 /etc/docker/daemon.json 生产环境参考配置:
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true
}
配置说明:
data-root:避免 Docker 数据占满系统盘;storage-driver:overlay2 是 Linux 下常用稳定选择;log-opts:限制容器日志无限增长;exec-opts:使用 systemd cgroup 驱动;live-restore:Docker daemon 重启时尽量保持容器运行。
修改后重启:
sudo systemctl daemon-reload
sudo systemctl restart docker
查看最终状态:
docker info
docker ps
docker system df
结语
Debian 是一个非常适合生产环境的 Linux 发行版,稳定、简洁、社区成熟。Docker 则为应用部署提供了标准化、可迁移、易维护的运行方式。二者结合后,可以显著提升部署效率和服务管理能力。
但需要注意的是,Docker 并不是“安装好就万事大吉”。真正稳定的生产环境,依赖合理的目录规划、严格的权限控制、可靠的备份机制、完善的日志管理和清晰的上线流程。只要这些基础工作做到位,在 Debian 上使用 Docker 部署 Web 服务、数据库、中间件或业务系统,都可以获得非常稳定的运行效果。