Docker部署全攻略:从核心概念到生产环境配置与优化
1. 项目概述:为什么Docker部署值得你花时间?
如果你是一名开发者、运维工程师,或者只是对技术部署感兴趣,那么“Docker安装部署”这个标题对你来说,绝不仅仅是一串命令的集合。它背后代表的是现代应用交付和运维方式的一次根本性变革。几年前,我们部署一个应用,可能需要先准备一台干净的服务器,然后手动安装操作系统、配置环境变量、解决各种库依赖冲突,整个过程繁琐且极易出错,更别提在不同环境(开发、测试、生产)之间保持一致性有多困难了。
Docker的出现,就像给软件世界引入了“集装箱”。它把应用程序及其所有依赖项(代码、运行时、系统工具、系统库)打包成一个标准化的、轻量级的、可移植的“镜像”。这个镜像可以在任何安装了Docker引擎的计算机上,以完全一致的方式运行起来,形成一个独立的“容器”。这意味着,你再也不用说“在我机器上好好的,怎么到你那儿就不行了”。从开发到上线,整个流程的确定性和效率得到了质的提升。
所以,这篇“详细版”部署指南,目标就是带你从零开始,不仅把Docker装好,更要理解每一步操作背后的逻辑,掌握在生产环境中稳定、安全运行Docker的核心要点。无论你是想在个人电脑上搭建学习环境,还是为团队项目构建标准化的部署基础,这篇文章都会提供一条清晰、可复现的路径。我会基于最常见的Linux发行版(以Ubuntu为例)进行讲解,但原理和思路是通用的,你可以轻松迁移到CentOS、Debian等其他系统。
2. 核心概念与准备工作:理解容器与虚拟机的本质区别
在动手安装之前,花几分钟搞清楚Docker的核心思想至关重要,这能帮你避免后续很多概念上的混淆。很多人会把Docker容器和虚拟机(VM)搞混,虽然它们都能实现环境隔离,但底层机制和资源消耗天差地别。
2.1 容器 vs. 虚拟机:轻量与厚重的哲学
想象一下你要运货。虚拟机就像雇了一整艘货轮,你不仅需要货物(你的应用),还需要为这艘船配备全套的船员(Guest OS操作系统内核)、发动机(虚拟硬件驱动)和大量生活空间(完整的操作系统用户空间)。每艘货轮都是完全独立的,但启动慢、占用资源多(通常需要GB级别的内存和磁盘)。
而Docker容器,则像是标准化的集装箱。所有的集装箱都共用一艘大货轮(Host OS宿主机操作系统)的发动机(Linux内核)和驾驶舱(系统调用接口)。每个集装箱里只装你的货物(应用)和它直接需要的包装、托盘(应用的依赖库和运行时)。集装箱启动极快(秒级),资源占用极小(通常只比应用本身多一点点开销),并且因为共享内核,密度可以非常高。
关键区别总结:
- 虚拟化层级 :VM虚拟化的是硬件,需要在物理硬件上先虚拟出一套完整的硬件环境,再安装完整的操作系统。容器虚拟化的是操作系统,多个容器共享宿主机的内核。
- 性能与开销 :容器直接运行在宿主机内核上,几乎没有性能损耗,启动速度极快。VM需要通过Hypervisor层翻译,有额外的性能开销,启动较慢。
- 隔离性 :VM提供了完全硬件的隔离,安全性理论上更强。容器是进程级的隔离,通过Namespace和Cgroups实现,虽然足够应对大多数场景,但在多租户等强安全需求下需要额外配置。
- 镜像大小 :一个完整的VM镜像可能达到GB甚至数十GB。一个Docker镜像通常只有MB级别,比如一个精简的Alpine Linux基础镜像只有5MB左右。
理解这一点后,你就明白为什么Docker能如此流行:它用“够用”的隔离,换来了极致的轻量、快速和高效,完美契合了微服务、持续集成和弹性伸缩的现代架构需求。
2.2 安装前的系统环境检查
“工欲善其事,必先利其器”。在安装Docker之前,我们需要确保宿主机系统满足基本要求,并做好一些准备工作。这里我们以 Ubuntu 22.04 LTS 这个长期支持版为例,因为它社区支持完善,是很多人的首选。
1. 系统要求:
- 操作系统 :64位Linux发行版。Windows和macOS也有Docker Desktop,但本文聚焦于更常见的Linux服务器部署。
-
内核版本
:建议3.10或更高。你可以通过
uname -r命令查看。 -
存储驱动
:Docker支持
overlay2,aufs,devicemapper等。overlay2是目前推荐且性能较好的驱动,现代Linux内核通常都支持。
2. 清理旧版本(如果是升级或重装):
为了避免冲突,如果系统上有老旧的Docker版本(可能叫
docker
,
docker.io
, 或
docker-engine
),最好先卸载它们。
sudo apt-get remove docker docker-engine docker.io containerd runc
注意,这条命令执行后,
/var/lib/docker/
目录下的镜像、容器、卷和网络配置
默认会被保留
。如果你需要全新安装,可以手动删除这个目录(
sudo rm -rf /var/lib/docker
),但请务必确认其中没有你需要的数据。
3. 更新系统包索引: 这是一个好习惯,确保我们接下来安装的软件来自最新的软件源。
sudo apt-get update
4. 安装必要的依赖包:
这些工具让
apt
可以通过HTTPS协议使用软件仓库。
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
注意:生产环境考量 :如果你是在公司的生产服务器上操作,需要确认服务器的网络策略是否允许访问外部的Docker软件源(
download.docker.com)。如果不允许,可能需要配置内部镜像源或离线安装,这会在后续章节详细说明。
3. Docker安装全流程详解:三种主流方法对比与实践
安装Docker有多种途径,不同的方法在便捷性、稳定性和可控性上各有优劣。我将详细介绍最常用的三种方法,并解释在什么场景下该选择哪一种。
3.1 方法一:使用官方脚本快速安装(最便捷,适合测试/学习)
Docker官方提供了一个便捷的安装脚本,它能自动检测你的系统版本,并配置好软件源、安装最新稳定版的Docker Engine。
操作步骤:
-
下载安装脚本:
curl -fsSL https://get.docker.com -o get-docker.sh-
-f(--fail): 让curl在服务器错误时静默失败。 -
-s(--silent): 静默模式,不显示进度或错误信息。 -
-S(--show-error): 与-s配合,在失败时显示错误。 -
-L(--location): 如果地址有重定向,则跟随重定向。 -
-o: 将输出写入文件,这里保存为get-docker.sh。
-
-
执行安装脚本:
sudo sh get-docker.sh脚本运行后,你会看到它自动执行了一系列操作:添加Docker的GPG密钥和APT软件源,然后安装
docker-ce(社区版)、docker-ce-cli、containerd.io等包。
优点:
- 极其简单 :一条命令解决所有问题,适合快速搭建实验环境。
- 自动适配 :脚本会识别你的Linux发行版并采用对应的安装策略。
缺点与风险:
- “黑盒”操作 :你无法精确控制它安装的版本和具体的配置步骤。脚本内容可能变更,存在潜在的安全风险(虽然官方脚本是可信的,但在生产环境仍需谨慎)。
- 不适合生产 :生产环境通常要求版本固定、过程可控,因此不推荐此方法。
实操心得 :这个方法是我在本地虚拟机或云服务器上做快速概念验证时的首选。但在执行任何从网络下载的脚本前, 强烈建议 你先用
cat get-docker.sh或者less get-docker.sh快速浏览一下脚本内容,了解它将要做什么,这是一个基本的安全习惯。
3.2 方法二:通过APT仓库安装(推荐,适合生产与通用环境)
这是最经典、最可控的安装方式,也是Docker官方文档推荐的方法。我们手动添加Docker的官方APT仓库,然后像安装其他系统软件一样安装Docker。
操作步骤:
-
添加Docker的官方GPG密钥 : 密钥用于验证从Docker仓库下载的软件包的完整性,确保它们没有被篡改。
sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg这条管道命令:下载GPG密钥 -> 通过
gpg --dearmor解码 -> 保存到/etc/apt/keyrings/docker.gpg。 -
设置稳定的APT仓库 :
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null-
[arch=$(dpkg --print-architecture):自动获取当前系统的架构(如amd64, arm64)。 -
signed-by=:指定验证软件包签名的密钥环文件。 -
$(lsb_release -cs):自动获取当前Ubuntu的代号(如jammy for 22.04)。 -
sudo tee ...:将echo的内容写入到/etc/apt/sources.list.d/docker.list文件。
-
-
更新APT包索引 : 添加新仓库后,必须更新本地软件包列表。
sudo apt-get update -
安装Docker Engine及相关组件 :
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin-
docker-ce: Docker社区版引擎。 -
docker-ce-cli: Docker命令行工具。 -
containerd.io: 行业标准的容器运行时,Docker Engine底层使用它来管理容器生命周期。 -
docker-compose-plugin: Docker Compose V2,作为插件安装,用于定义和运行多容器应用。
-
安装特定版本: 生产环境为了稳定性,通常需要锁定某个特定版本,而不是永远使用最新版。
-
列出仓库中可用的版本:
apt-cache madison docker-ce | head -10你会看到类似
docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages的输出。5:20.10.17~3-0~ubuntu-jammy就是完整的版本字符串。 -
安装指定版本(例如
5:20.10.17~3-0~ubuntu-jammy):sudo apt-get install docker-ce=5:20.10.17~3-0~ubuntu-jammy docker-ce-cli=5:20.10.17~3-0~ubuntu-jammy containerd.io docker-compose-plugin
优点:
- 完全可控 :清楚每一步在做什么,可以固定版本,符合生产环境部署规范。
-
便于管理
:可以通过
apt进行后续的升级、降级或卸载,与系统包管理无缝集成。 - 官方支持 :这是Docker官方维护的安装方式,兼容性和稳定性最有保障。
缺点:
- 步骤稍多 :需要手动执行几条命令。
注意事项 :在执行
sudo apt-get update时,如果遇到GPG error,提示密钥不可用,通常是因为密钥环文件的权限问题。可以尝试运行sudo chmod a+r /etc/apt/keyrings/docker.gpg来修正权限,然后再次更新。
3.3 方法三:离线安装包部署(应对无外网或严格内网环境)
在某些安全要求极高的生产环境或完全无外网访问的“离线”环境中,你需要事先下载好所有依赖的
.deb
安装包,然后拷贝到目标服务器进行安装。
操作步骤:
-
在一台有网络的同构机器上准备离线包 : 假设你的生产服务器是 Ubuntu 22.04 amd64,你找一台同样系统的机器(可以是虚拟机)。
# 创建一个目录存放所有包 mkdir -p /tmp/docker-offline cd /tmp/docker-offline # 使用 apt-get download 下载指定包及其所有依赖 # 你需要先添加好Docker仓库(参考方法二的前两步) sudo apt-get update apt-get download docker-ce docker-ce-cli containerd.io docker-compose-plugin # 下载依赖管理工具,用于在离线机处理依赖 apt-get download dpkg-dev # 将整个目录打包 cd .. tar -czf docker-offline-pkgs.tar.gz docker-offline/ -
将打包文件传输到目标服务器 : 使用U盘、内部文件服务器或任何允许的传输方式,将
docker-offline-pkgs.tar.gz放到目标服务器上,例如/tmp。 -
在目标服务器上安装 :
# 解压 cd /tmp tar -xzf docker-offline-pkgs.tar.gz cd docker-offline # 安装所有.deb包。dpkg -i 不会自动解决依赖,所以需要按正确顺序或使用以下命令 # 先安装 containerd.io,因为它通常是基础依赖 sudo dpkg -i containerd.io*.deb # 然后安装 docker-ce-cli 和 docker-ce sudo dpkg -i docker-ce-cli*.deb sudo dpkg -i docker-ce*.deb # 最后安装 docker-compose-plugin sudo dpkg -i docker-compose-plugin*.deb # 如果安装过程中报告缺少依赖,可以使用以下命令尝试自动修复(前提是这些依赖包也在当前目录) sudo apt-get install -f .
优点:
- 无需外网 :彻底解决网络隔离环境下的安装问题。
- 版本固化 :离线包一旦准备好,可以批量部署到多台环境一致的服务器上。
缺点:
- 准备工作繁琐 :需要提前准备完全匹配的安装包和依赖。
- 升级麻烦 :每次升级都需要重新准备完整的离线包。
常见问题 :离线安装时最常见的错误就是依赖缺失。
dpkg -i会明确告诉你缺少哪个包。你需要在有网的机器上,用apt-cache depends <package-name>命令仔细查看依赖树,并确保所有依赖包都下载到了离线目录中。一个更稳妥的方法是使用apt-offline或dpkg-repack等工具来生成更完整的离线包集合。
4. 安装后的关键配置与验证
安装完成只是第一步,合理的配置才能让Docker安全、高效地运行。特别是直接使用
sudo
来运行Docker命令是非常不便且不安全的,我们需要进行一些基本配置。
4.1 管理用户组配置:告别烦人的
sudo
默认情况下,Docker守护进程绑定在Unix socket上,而该socket属于
root
用户。普通用户必须通过
sudo
才能访问它。将当前用户加入
docker
用户组,可以使其获得直接访问Docker的权限。
操作步骤:
-
创建
docker用户组(通常安装时已自动创建):sudo groupadd docker -
将当前用户添加到
docker组:sudo usermod -aG docker $USER-
-aG:-a表示追加,-G指定组。这样不会覆盖用户已有的其他组。
-
-
生效组权限 : 用户组信息在用户登录时加载。要使更改立即生效,你需要 完全注销并重新登录 ,或者启动一个新的shell会话(例如新开一个终端窗口,或使用
newgrp docker命令)。这是最容易忽略的一步!
验证是否生效:
重新登录后,运行
id
命令,查看输出中是否包含
docker
组。然后直接运行:
docker run hello-world
如果这个命令能成功运行并输出欢迎信息,而不需要
sudo
,说明配置成功。
安全警告 :
docker组权限等同于root!因为Docker可以挂载宿主机的目录、操作网络,甚至可以在容器内获得宿主机的root权限。因此, 只将你信任的用户加入docker组 。在生产服务器上,更严格的作法可能是禁止使用docker组,而是通过sudoers文件精细控制哪些命令可以以root权限运行。
4.2 服务管理与开机自启
Docker安装后,其守护进程(
dockerd
)是作为一个系统服务运行的。我们需要知道如何管理它。
-
启动Docker服务 (安装后通常已自动启动):
sudo systemctl start docker -
设置Docker服务开机自启 (非常重要,确保服务器重启后容器能自动恢复):
sudo systemctl enable docker这个命令会创建符号链接,告诉系统在启动时自动运行Docker服务。
-
查看Docker服务状态 :
sudo systemctl status docker你可以看到服务是活跃的(
active (running)),并且下面有最近的日志输出。 -
重启/停止Docker服务 :
sudo systemctl restart docker # 重启 sudo systemctl stop docker # 停止
4.3 验证安装与基本命令测试
让我们运行几个经典命令,全方位验证Docker是否工作正常。
-
运行测试容器 : 我们已经用过了
docker run hello-world。这个命令会从Docker Hub拉取一个极小的测试镜像并运行它,输出一段说明文字后退出。这是最经典的“冒烟测试”。 -
查看Docker系统信息 :
docker info这个命令会输出一长串信息,包括:
- Containers和Images的数量(刚安装完应该是0)。
-
Docker根目录位置(通常是
/var/lib/docker)。 -
使用的存储驱动(如
overlay2)。 - 操作系统、内核版本、CPU/内存总量等。 仔细查看这些信息,确保没有明显的错误警告。
-
查看Docker版本 :
docker version这会分别显示 Client (客户端,即Docker CLI)和 Server (服务端,即Docker Engine)的版本信息。确保两者都已安装且版本匹配。
-
拉取并运行一个实用的容器 : 让我们跑一个持续运行的容器,比如Nginx。
docker run -d -p 8080:80 --name my-nginx nginx-
-d: 后台运行(detached mode)。 -
-p 8080:80: 端口映射,将宿主机的8080端口映射到容器的80端口。 -
--name my-nginx: 给容器起个名字,方便管理。 -
nginx: 镜像名,默认从Docker Hub拉取最新版。 运行后,在浏览器访问http://你的服务器IP:8080,你应该能看到Nginx的欢迎页面。这证明Docker的网络和端口映射功能完全正常。
-
5. 核心配置调优与国内镜像加速
默认安装的Docker可能不适合所有生产场景。我们需要根据实际情况调整其配置,其中最重要的一项就是为在中国大陆的用户配置镜像加速器,以解决拉取镜像速度慢的问题。
5.1 配置Daemon参数与镜像加速
Docker守护进程的配置文件是
/etc/docker/daemon.json
。如果文件不存在,可以创建它。
配置镜像加速器(以阿里云为例):
-
登录阿里云容器镜像服务控制台(cr.console.aliyun.com),根据指引获取你的专属加速器地址。它看起来像
https://xxxx.mirror.aliyuncs.com。 -
编辑或创建配置文件:
sudo nano /etc/docker/daemon.json -
输入以下内容(将
你的加速器地址替换为实际地址):{ "registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"], "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "storage-driver": "overlay2" }-
registry-mirrors: 核心配置 ,指定镜像加速器地址。可以配置多个,用逗号分隔。 -
exec-opts: 设置cgroup驱动为systemd,这对于使用systemd作为init系统的Linux发行版(如Ubuntu、CentOS 7+)是推荐配置,能提高系统稳定性。 -
log-driver和log-opts: 配置容器日志驱动为json-file,并限制单个日志文件最大100MB,最多保留3个文件,防止日志占满磁盘。 -
storage-driver: 明确指定存储驱动为overlay2。
-
-
保存并退出编辑器(在nano中按
Ctrl+X,然后按Y确认,再按回车)。 -
重新加载配置并重启Docker服务:
sudo systemctl daemon-reload sudo systemctl restart docker -
验证加速器是否生效:
docker info在输出信息中,找到
Registry Mirrors部分,确认你配置的加速器地址已经列在其中。
实操心得 :除了阿里云,国内还有很多可用的公共加速器,如中科大、网易、腾讯云等。但公共加速器可能存在同步延迟或不稳定。对于生产环境, 强烈建议使用云服务商提供的私有加速器 (如阿里云ACR、腾讯云TCR等),它们通常速度更快、更稳定,并且支持私有镜像仓库。配置多个镜像源时,Docker会按顺序尝试,第一个失败后尝试第二个。
5.2 数据目录与存储驱动优化
默认情况下,Docker的所有数据(镜像、容器、卷)都存放在
/var/lib/docker
。如果系统根分区空间较小,这可能会成为问题。
更改Docker数据根目录:
-
停止Docker服务:
sudo systemctl stop docker -
编辑
/etc/docker/daemon.json,添加或修改data-root项(假设新目录是/data/docker):{ "data-root": "/data/docker", ... // 其他原有配置 } -
将原有数据迁移到新目录(可选,如果新安装可跳过):
sudo rsync -avxP /var/lib/docker/ /data/docker/ -
重启Docker服务:
sudo systemctl start docker -
验证新目录是否被使用:
docker info | grep "Docker Root Dir"
关于存储驱动
:
overlay2
是目前Linux内核(4.x以上)首选的存储驱动,它比旧的
aufs
或
devicemapper
性能更好。除非有特殊需求,否则不要更改。你可以通过
docker info
查看当前使用的驱动。
5.3 网络与安全基础配置
调整默认的网桥IP段
:Docker默认会创建一个名为
docker0
的网桥,并分配
172.17.0.1/16
的IP段。如果这个网段和你内网的其他网段冲突,就需要修改。
在
/etc/docker/daemon.json
中添加:
{
"bip": "192.168.100.1/24",
... // 其他配置
}
这会将
docker0
网桥的IP设置为
192.168.100.1
,并为容器分配
192.168.100.0/24
网段的IP。
限制容器资源
:虽然Docker通过Cgroups可以限制CPU、内存等,但默认没有限制。你可以在运行容器时通过
-m
、
--cpus
等参数进行限制,更佳实践是在编排工具(如Docker Compose或Kubernetes)中定义资源请求和限制。
6. 生产环境部署的进阶考量与避坑指南
将Docker用于个人学习与用于生产环境,关注点截然不同。生产环境要求稳定性、可维护性、安全性和可观测性。以下是几个关键的进阶考量点。
6.1 日志与监控方案设计
容器是短暂的,其标准输出(stdout)和标准错误(stderr)是日志的主要来源。默认的
json-file
驱动会将日志保存在宿主机的文件中,但这不利于集中查看和分析。
生产环境日志方案:
-
日志驱动
:考虑使用
journald(如果宿主机使用systemd)或者直接配置为syslog,将日志发送到宿主机的系统日志服务。 -
集中式日志
:更专业的做法是使用
fluentd、logstash或filebeat等日志采集器,从容器的日志文件或docker logs接口收集日志,并发送到Elasticsearch、Loki或云厂商的日志服务中,便于搜索、分析和告警。 -
配置示例(在daemon.json中)
:
{ "log-driver": "syslog", "log-opts": { "syslog-address": "udp://localhost:514", "tag": "{{.Name}}" } }
监控方案:
-
Docker原生命令
:
docker stats可以实时查看容器的CPU、内存、网络IO等使用情况,适合临时诊断。 - cAdvisor :Google开源的容器资源监控工具,提供Web UI和Metrics接口,可以方便地集成到Prometheus中。
- Prometheus + Grafana :这是容器监控的事实标准。Prometheus负责抓取cAdvisor或容器暴露的metrics数据,Grafana用于可视化展示和告警。
- 商业监控 :如果使用云服务,阿里云、腾讯云等提供的容器服务都自带完善的监控和告警功能。
6.2 存储与数据持久化策略
容器本身是无状态的,其内部文件系统的变更会随着容器的删除而消失。任何需要持久化的数据(如数据库文件、上传的图片、应用程序日志)都必须存储在容器之外。
Docker的持久化机制:
-
绑定挂载(Bind Mounts) :将宿主机上的一个目录或文件直接挂载到容器中。
docker run -v /宿主机/绝对路径:/容器内路径 nginx- 优点 :直接、性能好,宿主机上可以直接访问和管理文件。
- 缺点 :容器与宿主机路径强耦合,移植性差。宿主机目录需要事先存在且有正确权限。
-
卷(Volumes) :由Docker管理,存储在宿主机文件系统的某个区域(默认是
/var/lib/docker/volumes/)。docker run -v 卷名:/容器内路径 nginx # 或先创建卷 docker volume create my-vol docker run -v my-vol:/容器内路径 nginx-
优点
:是Docker首选的持久化方式。与容器生命周期解耦,易于备份、迁移和管理(通过
docker volume命令)。性能通常也很好。 - 缺点 :数据存储在Docker管理的区域,不便于宿主机其他非Docker进程直接访问。
-
优点
:是Docker首选的持久化方式。与容器生命周期解耦,易于备份、迁移和管理(通过
-
临时文件系统(tmpfs mount) :将数据存储在宿主机的内存中,容器停止后数据消失。适用于存储敏感信息或不需要持久化的临时文件。
生产环境建议:
- 数据库数据 :务必使用 卷 或 绑定挂载 到可靠的、有备份的存储上(如云硬盘、NAS)。
- 配置文件 :可以使用绑定挂载,方便在宿主机修改。但更优雅的方式是使用配置管理工具或在构建镜像时固化配置。
- 日志文件 :建议将应用日志直接输出到stdout/stderr,由Docker收集。如果应用必须写日志文件,则挂载卷来持久化。
-
权限问题
:这是最常见的坑。容器内进程通常以非root用户(如uid 1000)运行,而挂载的宿主机目录可能属于root或其他用户。务必确保挂载目录对容器内进程的用户有读写权限。可以在运行容器时使用
-u参数指定用户ID,或者在宿主机上调整目录权限(chown或chmod)。
6.3 安全加固最佳实践
容器安全是一个庞大话题,这里列出几个最紧要的实践:
-
非Root用户运行容器 :在Dockerfile中使用
USER指令,或者在docker run时使用-u参数,指定一个非root的用户来运行容器内的主进程。这可以限制容器被攻破后的影响范围。FROM alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser CMD ["sleep", "infinity"] -
最小化镜像 :使用体积小的基础镜像(如Alpine Linux),并仅在镜像中安装必要的运行时依赖。多阶段构建(multi-stage build)是减少最终镜像大小的利器。
-
定期更新镜像 :基础镜像和软件包可能存在安全漏洞。定期(例如每周)重建和部署你的应用镜像,以获取最新的安全补丁。可以使用CI/CD流水线自动化这个过程。
-
限制容器能力 :默认情况下,容器拥有很多Linux能力(Capabilities)。通过
--cap-drop可以删除不需要的能力,通过--security-opt可以设置更严格的安全选项(如no-new-privileges)。docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE --security-opt=no-new-privileges nginx -
扫描镜像漏洞 :使用镜像安全扫描工具,如Trivy、Anchore Grype或云厂商提供的扫描服务,在镜像构建和部署前发现已知漏洞。
-
网络隔离 :不要使用默认的
bridge网络让所有容器互通。为不同的应用栈创建独立的Docker网络(docker network create),只有需要通信的容器才连接到同一个网络。
6.4 编排工具入门:Docker Compose
当你的应用由多个容器组成(例如一个Web应用容器 + 一个数据库容器 + 一个缓存容器)时,手动管理每个容器的启动、停止和连接会非常麻烦。Docker Compose就是用来解决这个问题的工具,它允许你使用一个YAML文件(
docker-compose.yml
)来定义和运行多容器应用。
一个简单的
docker-compose.yml
示例:
version: '3.8' # 指定Compose文件格式版本
services: # 定义服务(即容器)
web: # 服务名:web
image: nginx:alpine # 使用的镜像
ports:
- "80:80" # 端口映射
volumes:
- ./html:/usr/share/nginx/html # 绑定挂载静态页面
depends_on: # 依赖关系,会先启动db服务
- db
networks:
- app-net # 连接到自定义网络
db: # 服务名:db
image: mysql:8.0
environment: # 环境变量
MYSQL_ROOT_PASSWORD: secretpassword
MYSQL_DATABASE: myapp
volumes:
- db_data:/var/lib/mysql # 使用命名卷持久化数据
networks:
- app-net
volumes: # 声明在顶部使用的命名卷
db_data:
networks: # 声明自定义网络
app-net:
driver: bridge
常用命令:
-
docker compose up -d:启动所有服务(-d后台运行)。 -
docker compose down:停止并移除所有容器、网络。 -
docker compose ps:查看服务状态。 -
docker compose logs -f web:查看并跟随web服务的日志。
Docker Compose极大地简化了本地开发、测试和多服务应用的部署,是通往更复杂编排系统(如Kubernetes)的良好跳板。在生产环境,对于中小型应用,使用Docker Compose配合一些健康检查、重启策略和监控,也是一个完全可行的方案。
更多推荐
所有评论(0)