一、为什么 2015 年要写这份"一站式"
2015 年的 CentOS 7 服务器基本就是"yum 源 + Docker + Web 服务"三件套。本篇把三个场景串成一篇深度文——从国内 yum 源选择、装 Docker CE、起 Harbor 私有仓库,到 Docker 化部署 Nginx + 申请 Let’s Encrypt 免费证书并自动续期。每个环节的坑都标出来了。
本文写于 2015-09-15。Let’s Encrypt 2015-09-14 进入公开 beta,2016-04 正式 GA,本文示例贴近 Let’s Encrypt 早期生态。CentOS 7 已 2024-06-30 进入 ELS 阶段,新机器建议直接 Rocky / Alma 9。
二、国内 yum 源选择
CentOS 7 装好后第一件事就是换源——官方源国内外都慢,国内服务器一定要换。常见选择:
| 源 | 特点 |
|---|
阿里云 mirrors.aliyun.com/repo/Centos-7.repo | 同步快、稳定、企业用得多 |
网易 163 mirrors.163.com/.help/CentOS7-Base-163.repo | 老牌、文档多 |
| 中科大 USTC | 高校机房友好 |
| 清华 TUNA | 高校机房友好 |
阿里云(企业最常见):
1
2
3
4
| mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all && yum makecache
yum update
|
装 EPEL 源(很多 Python 包靠它):
1
| yum install -y epel-release
|
三、Docker CE 安装
3.1 卸载旧版
1
2
3
4
5
6
7
8
| sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
|
注意:/var/lib/docker 目录(镜像、容器、卷、网络)默认不会删,重装后数据还在。
3.2 走官方 yum 源
1
2
3
| sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce
|
想装指定老版本:
1
2
| yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce-18.09.1
|
2015-2017 社区更常用:
1
2
3
| curl -sSL https://get.docker.com/ | sh
systemctl start docker
systemctl enable docker
|
3.4 加 docker 用户组
1
2
| sudo usermod -aG docker <your-user>
# 重新登录生效
|
3.5 验证
1
| sudo docker run hello-world
|
四、配置阿里云 Docker 镜像加速
DockerHub 拉镜像国内极慢,必须配镜像加速器。2015-2016 年用得最多的是 daocloud.io:
1
2
3
4
5
6
7
8
9
| mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries": []
}
EOF
systemctl daemon-reload
systemctl restart docker
|
多镜像源写法(2020+ 推荐):
1
2
3
4
5
6
7
| {
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.mirrors.ustc.edu.cn"
],
"insecure-registries": ["<your-private-registry>:5000"]
}
|
验证是否生效:
1
2
| ps -ef | grep docker
# 命令行里看到 --registry-mirror=... 就对了
|
五、装 docker-compose
5.1 早期:pip 装(2015-2017)
1
2
| yum install -y python-pip
pip install docker-compose
|
5.2 中期:二进制直装
1
2
3
4
| curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose version
|
5.3 2020+:Docker CLI plugin
1
2
3
4
5
6
| # Compose v2
mkdir -p ~/.docker/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64 \
-o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version
|
六、Harbor 私有仓库
Harbor 是 VMware 开源的镜像仓库(2016-03 第一个 release),到 2017-2018 年成为国内事实标准。2017-2019 期间安装用 离线包最稳:
6.1 下载离线安装包
1
2
3
| wget https://github.com/vmware/harbor/releases/download/v1.9.1/harbor-offline-installer-v1.9.1.tgz
tar -xvf harbor-offline-installer-v1.9.1.tgz
cd harbor
|
6.2 改配置
1
2
3
4
5
6
| vim harbor.yml
hostname: <your-registry-ip-or-domain> # 例: 192.168.6.128
http:
port: 28083
harbor_admin_password: <your-admin-pass>
|
6.3 装 + 启
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| ./install.sh
# 启停
docker-compose stop
docker-compose start
# 改完配置要重生效
docker-compose down -v
vim harbor.yml
./prepare
docker-compose up -d
# 推镜像
docker login <your-registry-ip>:28083
docker tag alpine <your-registry-ip>:28083/dev/alpine:3.10.3
docker push <your-registry-ip>:28083/dev/alpine:3.10.3
|
6.4 默认凭据
- admin 账号:
admin / Harbor12345(生产环境一定要改) - db_auth PostgreSQL root:
root123(同上)
七、Docker 容器日志切割
不切日志,/var/lib/docker/containers/ 下的 *-json.log 可以把磁盘塞满:
1
2
3
4
5
6
7
8
9
10
| # /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}
systemctl daemon-reload
systemctl restart docker
|
坑提醒:只对新建容器生效,老容器需要 docker rm 后重建。
清空单个容器日志:
1
| truncate -s 0 /var/lib/docker/containers/<container-id>/*-json.log
|
八、Nginx + Let’s Encrypt 免费证书
Let’s Encrypt 2015-09-14 公开 beta、2016-04 正式 GA,把免费 HTTPS 证书从"程序员折腾"变成了"运维 5 分钟"。证书有效期 90 天,必须用 certbot renew 自动续期。
8.1 安装 certbot
1
2
| yum install -y epel-release
yum install -y certbot
|
8.2 申请证书(webroot 方式)
要求域名已经解析到本机:
1
2
3
4
5
| certbot certonly --webroot \
-w /var/www/html \
-d mydemo.com \
-m <your-email> \
--agree-tos
|
成功后证书在:
1
2
3
4
5
| /etc/letsencrypt/live/mydemo.com/
├── cert.pem # 用户证书
├── chain.pem # 中间证书
├── fullchain.pem # cert + chain
└── privkey.pem # 私钥
|
8.3 查有效期
1
2
3
| openssl x509 -noout -dates -in /etc/letsencrypt/live/mydemo.com/cert.pem
# notBefore=...
# notAfter=...
|
8.4 配合 Docker Nginx
把证书目录和站点目录挂进容器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # docker-compose.yml
services:
nginx:
image: nginx
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- /var/www/html:/usr/share/nginx/html:ro
- /webser/etc/nginx:/etc/nginx/conf.d
- /webser/logs/nginx:/var/log/nginx
- /etc/ssl:/etc/ssl
- /etc/letsencrypt:/etc/letsencrypt
|
8.5 Nginx 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| server {
listen 443 ssl http2;
server_name mydemo.com;
ssl_certificate /etc/letsencrypt/live/mydemo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydemo.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
# 前向保密(PFS)参数
ssl_dhparam /etc/ssl/private/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:...:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
ssl_prefer_server_ciphers on;
root /usr/share/nginx/html;
index index.html;
}
|
dhparam.pem 生成(一次性,2-3 分钟):
1
2
| mkdir -p /etc/ssl/private
openssl dhparam 2048 -out /etc/ssl/private/dhparam.pem
|
8.6 自动续期 crontab
1
2
3
4
| crontab -e
# 每月 1 号 05:00 续期 + 重启 nginx
00 05 01 * * /usr/bin/certbot renew --quiet && docker restart nginx
|
坑提醒:续期时网站必须能访问到 /.well-known/acme-challenge/——也就是说 HTTP 80 端口必须能从公网访问到 webroot。
九、Docker 存储路径搬家
/var/lib/docker 默认在根盘,根盘很容易塞满:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| systemctl stop docker
mkdir -p /home/docker
vim /usr/lib/systemd/system/docker.service
# ExecStart=/usr/bin/dockerd \
# --graph=/home/docker \ # Docker 17.05+ 推荐 data-root
# -H fd:// \
# --containerd=/run/containerd/containerd.sock
systemctl disable docker
systemctl enable docker
systemctl daemon-reload
systemctl start docker
docker info | grep "Docker Root Dir"
# Docker Root Dir: /home/docker
|
17.05+ 推荐用 data-root 而不是 --graph,后者已 deprecated。
十、磁盘空间排查速查
1
2
3
4
5
6
7
8
9
10
11
| # 全局
df -h
# 各目录占用
du -sh /*
# 当前目录前 10 大
du -hd 1 | sort -hr | head
# 删除 7 天前的文件
find ./ -mtime +7 | xargs rm -rf
|
生产环境慎用 rm -rf / 这类命令——本文示例中所有路径都加了具体子目录,是基本的安全习惯。
十一、典型坑速查
| 现象 | 原因 | 处理 |
|---|
docker run 报 “Cannot connect to the Docker daemon” | daemon 没启 / 装完没 reload | systemctl daemon-reload && systemctl restart docker |
| 拉镜像超慢 | 没配镜像加速 | 改 /etc/docker/daemon.json 的 registry-mirrors |
docker-compose 命令找不到 | 只装了 docker,没装 compose | 走 §5 装 compose |
| 容器日志把磁盘塞满 | 没切日志大小 | 改 daemon.json 的 log-opts |
| Let’s Encrypt 续期失败 | 80 端口被占 / 域名解析不到 | certbot renew --dry-run 模拟一次排查 |
| Harbor 装完访问 502 | 端口冲突 / yml 改完没 prepare | 改完 yml 必跑 ./prepare |
十二、下一步
- 想把 Harbor 升级到 v2.x → 见 Harbor 升级文档,先备份
/data/database 再升级 - 想换 SSL 自动化方案(acme.sh / Caddy) → 见
2017-09-15 CentOS 7 开发环境 - 想上 Kubernetes → 走 kubeadm,先关 swap(见
2012-12-15 CentOS 7 早期实践) - 不想自己维护 Harbor → 换 Docker Hub Pro / 阿里云 ACR / 腾讯云 TCR
参考资料
2024 视角:Docker 24+ / 25+ / 26+ 已经"云原生一体化"
2015 那篇是 Docker 1.7~1.12 时代。2024 视角下 Docker 已经 26+(2024-04),加上 containerd / BuildKit / compose v2 已经"完全成熟"。
一、Docker 24 → 26+(2024 主流)
- Docker 24.0(2023-05):引入 Docker Scout(镜像漏洞扫描)、Docker Debug。
- Docker 25.0(2024-01):Compose v2 全面替代 Compose v1(v1 已废弃)。
- Docker 26.0(2024-04):BuildKit 默认启用、WebAssembly 支持。
- Docker 27.0(2024-06):Testcontainers 集成、容器测试能力。
1
2
3
4
| docker --version
# Docker version 26.1.4, build 5650f9b
docker compose version
# Docker Compose version v2.27.0
|
二、containerd 替代 dockerd 的趋势
- 2024 大量 K8s 集群已经直接用 containerd(不再用 Docker):
- containerd 1.7+(2023-04):K8s CRI 兼容
- nerdctl:containerd 的 Docker-like CLI
- ctr(containerd 原生 CLI)
1
2
| # 用 nerdctl 跑容器(语法跟 docker 一样)
nerdctl run -d --name nginx -p 80:80 nginx:1.25
|
- 2024 趋势:K8s 节点不要装 Docker,直接装 containerd——少 30% 资源占用。
三、BuildKit 时代
- BuildKit(Docker 18.09+ 实验 → 26+ 默认)大幅提升
docker build 速度:- 并行构建(多 stage 一起)
- 缓存复用(跨 build 共享层缓存)
- mount 语法(
--mount=type=cache)
1
2
3
4
5
6
7
8
9
10
| # BuildKit 语法(2024 推荐)
# syntax=docker/dockerfile:1
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN --mount=type=cache,target=/root/.cache/go \
go build -o /out/app
FROM alpine
COPY --from=builder /out/app /app
|
四、Harbor v2.x 已成事实标准
2015 那篇是 Harbor v1.9 时代。2024 主流:
- Harbor 2.10+(2024):支持 OCI 标准、镜像签名(cosign)、P2P 镜像分发(kraken)。
- Harbor 2.11+(2024-05):AI 模型管理(ML Model Registry)—— LLM 镜像 / 权重文件直接托管。
1
2
3
4
5
6
| # 2024 装 Harbor 2.10
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar xvf harbor-offline-installer-v2.10.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml
./install.sh
|
五、Let’s Encrypt 的"现代"姿势
2015 那篇是 certbot + crontab。2024 主流:
acme.sh:单脚本,80+ DNS 厂商支持,更轻量:
1
2
3
4
5
6
7
8
| curl https://get.acme.sh | sh
export Ali_Key="xxx"
export Ali_Secret="yyy"
acme.sh --issue -d example.com --dns dns_ali
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
|
lego(Go 写):另一个 ACME 客户端,比 certbot 快。- Caddy:内置 ACME——配置即用:
1
2
3
4
| example.com {
reverse_proxy localhost:3000
}
# 自动 HTTPS + 自动续期
|
六、阿里云 Docker 镜像加速 2024 现状
2015 那篇的 daocloud.io 已经 2020 起停止免费服务。
2024 推荐:
1
2
3
4
5
6
7
8
9
10
| {
"registry-mirrors": [
"https://docker.m.daocloud.io", # DaoCloud 现仍可
"https://mirror.baidubce.com", # 百度云
"https://hub-mirror.c.163.com", # 网易
"https://docker.mirrors.ustc.edu.cn", # 中科大
"https://docker.nju.edu.cn", # 南京大学
"https://docker.mirrors.sjtug.sjtu.edu.cn" # 上交大
]
}
|
- 2024 国内云厂商镜像(更稳定):
- 阿里云:
<regionId>.mirror.aliyuncs.com(每个 region 独立) - 腾讯云:
mirror.ccs.tencentyun.com - 华为云:
swr.cn-north-4.myhuaweicloud.com
七、docker-compose → docker compose 时代
- 2024 已无
docker-compose(v1 命令),统一用 docker compose(v2 plugin)。 - 2023-08 Docker 移除 Compose v1,所有项目必须迁移:
1
2
3
4
5
| # 旧
docker-compose up -d
# 新
docker compose up -d
|
八、Docker 在 K8s 时代的"角色"
- 2024 大量生产项目已经不用 Docker 跑生产——直接用 K8s + containerd。
- Docker 仍用的场景:
- 本地开发
- CI/CD 构建
- 小规模部署(< 10 容器)
- 个人项目
- K8s 时代:
- K3s(轻量 K8s,单二进制)
- K0s(CNCF 零摩擦 K8s)
- MicroK8s(Ubuntu 出的)
- minikube(本地开发)
九、Docker 替代品
- Podman(Red Hat 出,CentOS Stream / RHEL 9 默认):无 daemon 架构,rootless 容器。
- nerdctl(containerd CLI):K8s 节点首选。
- Buildah:专为 build 场景,无 daemon。
- LXC / LXD:系统容器(类似 VM 的容器)。