在Ubuntu 22.04上部署Docker前,有几个关键准备工作需要完成。我遇到过不少开发者跳过这些步骤直接安装,结果遇到各种依赖问题。首先确保你的系统是最新的,这个习惯能避免90%的兼容性问题:
bash复制sudo apt update && sudo apt upgrade -y
接下来安装基础工具包,这些组件看起来和Docker无关,但实际是APT通过HTTPS访问仓库的必备条件。曾经有同事在离线环境折腾半天,最后发现缺的就是这些:
bash复制sudo apt install -y apt-transport-https ca-certificates curl software-properties-common gnupg
关于密钥导入,官方文档会建议用apt-key add,但这个方法在Ubuntu 22.04已被标记为废弃。更安全的做法是创建专用密钥目录:
bash复制sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
仓库配置也有讲究,很多教程直接用的add-apt-repository,但手动配置能更灵活控制架构和版本。新建配置文件时注意jammy这个代号必须与你的Ubuntu版本匹配:
bash复制echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
更新完仓库后,别急着安装。先看看有哪些可用版本,这对生产环境特别重要。有次线上事故就是因为自动安装了最新版,结果与现有编排系统不兼容:
bash复制apt-cache madison docker-ce | awk '{ print $3 }'
安装时推荐锁定主版本号,比如要安装20.10.x系列的最新补丁版:
bash复制VERSION_STRING=5:20.10.24~3-0~ubuntu-jammy
sudo apt install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io
安装后验证不是简单看版本号就完事。我习惯用全套检查命令,特别是检查containerd的socket权限:
bash复制sudo docker --version
sudo docker run hello-world
ls -l /run/containerd/containerd.sock
关于目录迁移,/var/lib/docker确实容易撑爆根分区。但直接移动目录可能引发权限问题,更稳妥的做法是在安装前就规划好存储驱动。比如用btrfs分区可以这样预处理:
bash复制sudo mkdir -p /new_path/docker
sudo chmod 711 /new_path
echo '{"data-root": "/new_path/docker"}' | sudo tee /etc/docker/daemon.json
虽然现在Docker官方推荐使用Compose V2插件形式,但很多老项目还在用V1的二进制方式。这里给出两种安装方案,根据你的CI/CD环境选择:
方案一:传统二进制方式(适合老环境)
bash复制sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
方案二:现代插件方式(推荐新项目)
bash复制sudo apt install -y docker-compose-plugin
docker compose version
验证时要注意,V1和V2的命令语法有细微差别。曾经有自动化脚本因为docker-compose和docker compose的差异导致失败:
bash复制# V1方式
docker-compose --version
# V2方式
docker compose version
镜像加速只是基础配置,对于国内环境我建议同时配置多个镜像源。这个daemon.json配置还优化了日志和存储驱动:
json复制{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
配置生效后要完全重启服务,简单的restart有时不够彻底:
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker.socket docker.service
对于开发环境,建议把用户加入docker组,但要注意这相当于给用户root权限。更安全的做法是为每个项目创建专用组:
bash复制sudo groupadd docker-dev
sudo usermod -aG docker-dev $USER
newgrp docker-dev
sudo chown :docker-dev /var/run/docker.sock
网络问题:当遇到iptables冲突时,不是简单关闭防火墙,而是正确配置Docker的iptables规则:
bash复制sudo tee /etc/docker/daemon.json <<EOF
{
"iptables": false
}
EOF
目录权限:容器内用户映射到宿主机时经常出现权限拒绝。这个预处理脚本能自动修复数据卷权限:
bash复制#!/bin/bash
for dir in $(find /path/to/volumes -type d); do
sudo chmod 777 "$dir"
sudo setfacl -Rdm u:1000:rwx,g:1000:rwx "$dir"
done
资源限制:默认配置容易导致容器吃光系统资源。创建/etc/docker/daemon.json时加入这些限制:
json复制{
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65535,
"Soft": 65535
}
},
"storage-opts": [
"size=120GB"
]
}
用一个真实的Python项目演示完整流程。假设项目结构如下:
code复制myapp/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── src/
Dockerfile最佳实践:
dockerfile复制FROM python:3.9-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY src/ .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]
compose文件关键配置:
yaml复制services:
app:
build: .
ports:
- "8000:8000"
volumes:
- ./src:/app/src
environment:
- DEBUG=False
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
启动时建议先dry-run检查配置,再实际构建:
bash复制docker compose config
docker compose build --no-cache
docker compose up -d
查看容器日志不是简单用docker logs,结合journalctl才能看到完整信息:
bash复制journalctl -u docker.service -n 50 --no-pager
清理旧数据时注意,prune命令会删除所有未使用的资源。这个安全脚本只清理超过30天的资源:
bash复制docker system prune --filter "until=720h" --force
监控容器资源使用情况,推荐使用ctop这个神器:
bash复制docker run --rm -ti --name=ctop -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest
对于需要长期运行的容器,一定要配置健康检查。这个Redis配置示例能自动重启异常容器:
yaml复制healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s