引言
在现代应用开发和部署中,容器化技术已经成为标配。然而,随着微服务架构的普及,单一容器已难以满足复杂应用的需求。本文将带领大家深入掌握Docker Compose编排工具和企业级私有仓库Harbor,实现从单体应用到复杂服务的高效管理与部署。
一、Docker Compose:单机编排的利器
1. Docker Compose在容器编排生态中的位置

关键观点:
-
Docker Compose:学习门槛低,适合入门和快速原型开发
-
Kubernetes:功能强大但复杂,需要专门团队维护
-
渐进式路径:Compose → Kubernetes是最佳学习路径
2. Docker Compose快速安装指南
bash
# 1. 下载Docker Compose二进制文件(国内加速)
$ curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` \
-o /usr/local/bin/docker-compose
# 2. 赋予执行权限
$ chmod +x /usr/local/bin/docker-compose
# 3. 验证安装
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
3. WordPress实战部署:从零到一
3.1 项目结构规划
bash
wordpress-site/
├── docker-compose.yml # 编排配置文件
├── .env # 环境变量文件(敏感信息)
├── db_data/ # MySQL数据目录
│ └── [自动创建]
├── web_data/ # WordPress文件目录
│ └── [自动创建]
└── nginx-conf/ # Nginx配置(可选扩展)
└── wordpress.conf
3.2 完整的docker-compose.yml配置
bash
# docker-compose.yml
version: '3.8'
# 定义网络(创建独立的桥接网络)
networks:
wordpress-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# 定义数据卷(持久化存储)
volumes:
db_data:
web_data:
# 定义服务
services:
# MySQL数据库服务
db:
image: mysql:5.7
container_name: wp-mysql
restart: unless-stopped
volumes:
- db_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初始化SQL脚本
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_INITDB_SKIP_TZINFO: 1
networks:
- wordpress-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--max_allowed_packet=64M
# WordPress应用服务
wordpress:
image: wordpress:php7.4-apache
container_name: wp-app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
volumes:
- web_data:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini # PHP配置
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: ${DB_NAME}
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_CONFIG_EXTRA: |
define('WP_SITEURL', 'http://${DOMAIN}');
define('WP_HOME', 'http://${DOMAIN}');
define('WP_DEBUG', ${WP_DEBUG});
define('WP_MEMORY_LIMIT', '256M');
networks:
wordpress-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wordpress.rule=Host(`${DOMAIN}`)"
- "traefik.http.services.wordpress.loadbalancer.server.port=80"
# Nginx反向代理(可选)
nginx:
image: nginx:alpine
container_name: wp-nginx
restart: unless-stopped
depends_on:
- wordpress
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx-conf:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
- web_data:/var/www/html:ro
networks:
- wordpress-network
3.3 环境变量配置(.env文件)
bash
# 数据库配置
DB_ROOT_PASSWORD=R00t!Passw0rd#2024
DB_NAME=wordpress_db
DB_USER=wp_user
DB_PASSWORD=WpUser!Secure#2024
# WordPress配置
DOMAIN=localhost # 生产环境修改为实际域名
WP_DEBUG=false
# 网络配置
NETWORK_SUBNET=172.20.0.0/16
# 时区设置
TZ=Asia/Shanghai
3.4 一键部署与管理
bash
#!/bin/bash
# deploy-wordpress.sh - WordPress一站式部署脚本
set -e
echo "🚀 开始部署WordPress..."
# 1. 创建项目目录
PROJECT_DIR="~/wordpress-site"
mkdir -p $PROJECT_DIR/{db_data,web_data,nginx-conf,ssl}
cd $PROJECT_DIR
# 2. 生成配置文件
if [ ! -f docker-compose.yml ]; then
echo "生成docker-compose.yml..."
# 这里可以加入自动生成逻辑
fi
# 3. 检查环境变量
if [ ! -f .env ]; then
echo " 警告: 未找到.env文件"
cp .env.example .env
echo "请编辑.env文件配置环境变量"
nano .env
fi
# 4. 启动服务
echo "启动Docker Compose服务..."
docker-compose up -d
# 5. 健康检查
echo "等待服务启动..."
sleep 10
for service in db wordpress; do
echo "检查 $service 状态..."
if docker-compose ps $service | grep -q "Up"; then
echo " $service 启动成功"
else
echo " $service 启动失败"
docker-compose logs $service
exit 1
fi
done
# 6. 输出访问信息
echo ""
echo "======================================"
echo " WordPress部署完成!"
echo ""
echo " 访问地址: http://localhost"
echo " 管理后台: http://localhost/wp-admin"
echo ""
echo " 服务状态:"
docker-compose ps
echo ""
echo " 查看日志: docker-compose logs -f"
echo " 停止服务: docker-compose down"
echo "======================================"
3.5 Docker Compose管理命令大全
bash
# 基础操作
dc up -d # 启动服务(后台运行)
dc down # 停止并移除服务
dc ps # 查看服务状态
dc logs -f # 跟踪日志输出
# 服务管理
dc start # 启动已停止的服务
dc stop # 停止运行中的服务
dc restart # 重启服务
dc pause # 暂停服务
dc unpause # 恢复服务
# 监控与调试
dc top # 查看容器进程
dc exec <service> sh # 进入容器Shell
dc config # 验证配置语法
dc port <service> # 查看端口映射
# 扩展与维护
dc up --scale web=3 # 扩展服务实例(web服务3个副本)
dc build # 重新构建镜像
dc pull # 拉取最新镜像
dc images # 查看项目相关镜像
# 清理维护
dc down -v # 停止并删除数据卷
dc rm -f # 强制移除容器
dc down --rmi all # 停止并删除所有镜像
二、Docker私有仓库:从Registry到Harbor
1. 私有仓库生态系统对比

2. Docker原生Registry快速搭建
2.1 基础安装与配置
bash
#!/bin/bash
# setup-registry.sh - Docker Registry快速安装
# 1. 创建数据目录
mkdir -p /data/docker-registry
chmod 755 /data/docker-registry
# 2. 创建认证文件(可选)
mkdir -p /auth
docker run --entrypoint htpasswd registry:2 \
-Bbn admin "SecurePass123!" > /auth/htpasswd
# 3. 启动Registry容器
docker run -d \
--name=private-registry \
--restart=unless-stopped \
-p 5000:5000 \
-v /data/docker-registry:/var/lib/registry \
-v /auth:/auth \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_STORAGE_DELETE_ENABLED=true \
registry:2
# 4. 客户端配置(所有要使用该仓库的机器)
cat << EOF > /etc/docker/daemon.json
{
"insecure-registries": ["192.168.1.100:5000"],
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
# 5. 重启Docker服务
systemctl daemon-reload
systemctl restart docker
# 6. 验证安装
curl -X GET http://192.168.1.100:5000/v2/_catalog
echo "Registry安装完成!"
2.2 镜像推送到私有仓库
bash
# 1. 登录到私有仓库
docker login 192.168.1.100:5000
Username: admin
Password: SecurePass123!
# 2. 给镜像打标签(关键步骤!)
# 格式:docker tag SOURCE_IMAGE[:TAG] REGISTRY_HOST:PORT/REPOSITORY[:TAG]
docker tag nginx:latest 192.168.1.100:5000/library/nginx:latest
docker tag mysql:8.0 192.168.1.100:5000/apps/mysql:8.0
# 3. 推送到仓库
docker push 192.168.1.100:5000/library/nginx:latest
docker push 192.168.1.100:5000/apps/mysql:8.0
# 4. 查看仓库内容
curl -X GET http://192.168.1.100:5000/v2/_catalog
# 输出:{"repositories":["library/nginx","apps/mysql"]}
curl -X GET http://192.168.1.100:5000/v2/library/nginx/tags/list
# 输出:{"name":"library/nginx","tags":["latest"]}
# 5. 从私有仓库拉取
docker pull 192.168.1.100:5000/library/nginx:latest
# 6. 清理本地缓存
docker image prune -f
3. Harbor企业级私有仓库
3.1 Harbor架构概览

3.2 Harbor安装部署
3.2.1 环境准备
bash
#!/bin/bash
# prepare-harbor-env.sh
echo " 检查系统环境..."
# 1. 检查Docker和Docker Compose
if ! command -v docker &> /dev/null; then
echo " Docker未安装,开始安装..."
curl -fsSL https://get.docker.com | bash -s docker
fi
if ! command -v docker-compose &> /dev/null; then
echo " Docker Compose未安装,开始安装..."
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
fi
# 2. 检查端口占用
PORTS=(80 443 4443)
for port in "${PORTS[@]}"; do
if ss -tulpn | grep ":${port}" > /dev/null; then
echo " 警告: 端口 ${port} 已被占用"
fi
done
# 3. 检查存储空间(至少20GB)
AVAILABLE_SPACE=$(df -BG / | tail -1 | awk '{print $4}' | tr -d 'G')
if [ "$AVAILABLE_SPACE" -lt 20 ]; then
echo " 磁盘空间不足,至少需要20GB"
exit 1
fi
# 4. 创建目录结构
mkdir -p /data/harbor/{data,cert,ca-download}
chmod -R 755 /data/harbor
echo " 环境检查通过"
3.2.2 离线安装
bash
#!/bin/bash
# install-harbor-offline.sh
HARBOR_VERSION="v2.5.1"
INSTALL_DIR="/opt/harbor"
DATA_DIR="/data/harbor"
echo " 开始安装Harbor ${HARBOR_VERSION}..."
# 1. 下载离线安装包
cd /tmp
wget https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz
# 2. 解压安装包
tar xzf harbor-offline-installer-${HARBOR_VERSION}.tgz -C /opt
mv /opt/harbor ${INSTALL_DIR}
# 3. 配置harbor.yml
cp harbor.yml.tmpl harbor.yml
cat > harbor.yml <<-EOF
hostname: harbor.local
http:
port: 80
https:
port: 443
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
harbor_admin_password: Harbor12345
database:
password: root123
data_volume: /data
clair:
updaters_interval: 12
jobservice:
max_job_workers: 10
notification:
webhook_job_max_retry: 10
chart:
absolute_url: disabled
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
_version: 2.5.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- clair
EOF
# 4. 执行安装
./install.sh
# 5. 验证安装
sleep 30
echo "检查Harbor服务状态..."
docker-compose ps
echo " Harbor安装完成!"
echo " 访问地址: https://harbor.local"
echo " 用户名: admin"
echo " 密码: Harbor12345"
3.3 Harbor日常使用
bash
#!/bin/bash
# push-to-harbor-with-scan.sh
HARBOR_HOST="harbor.local"
PROJECT="myapp"
IMAGE="nginx:1.21"
TAG="v1.0"
echo " 登录到Harbor..."
docker login $HARBOR_HOST -u admin -p Harbor12345
echo " 为镜像打标签..."
docker tag $IMAGE $HARBOR_HOST/$PROJECT/nginx:$TAG
echo " 推送镜像到Harbor..."
docker push $HARBOR_HOST/$PROJECT/nginx:$TAG
echo " 触发安全扫描..."
# 使用Harbor API触发扫描
curl -X POST \
-H "Authorization: Basic $(echo -n 'admin:Harbor12345' | base64)" \
"https://$HARBOR_HOST/api/v2.0/projects/$PROJECT/repositories/nginx/artifacts/$TAG/scan" \
-k
echo " 等待扫描完成..."
sleep 30
echo " 获取扫描结果..."
curl -X GET \
-H "Authorization: Basic $(echo -n 'admin:Harbor12345' | base64)" \
"https://$HARBOR_HOST/api/v2.0/projects/$PROJECT/repositories/nginx/artifacts/$TAG/additions/vulnerabilities" \
-k | jq '.'
echo " 镜像推送完成"
三、实战对比:Compose + Harbor完整方案
1. 企业级WordPress部署方案

2. 完整的docker-compose.yml(生产就绪)
bash
# production-wordpress.yml
version: '3.8'
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
x-common-labels: &common-labels
com.company.project: "wordpress"
com.company.environment: "production"
services:
# 使用Harbor中的镜像
mysql:
image: harbor.company.com/infra/mysql:8.0
container_name: mysql-production
restart: unless-stopped
logging: *default-logging
labels: *common-labels
volumes:
- mysql_data:/var/lib/mysql
- ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER_FILE: /run/secrets/mysql_user
MYSQL_PASSWORD_FILE: /run/secrets/mysql_password
secrets:
- mysql_root_password
- mysql_user
- mysql_password
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 3
wordpress:
image: harbor.company.com/apps/wordpress:6.0
container_name: wordpress-production
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
logging: *default-logging
labels: *common-labels
volumes:
- wp_content:/var/www/html/wp-content
- uploads:/var/www/html/wp-content/uploads
- ./config/php/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER_FILE: /run/secrets/mysql_user
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/mysql_password
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_DEBUG: "false"
WORDPRESS_CONFIG_EXTRA: |
define('WP_HOME', 'https://${DOMAIN}');
define('WP_SITEURL', 'https://${DOMAIN}');
define('FORCE_SSL_ADMIN', true);
define('WP_CACHE', true);
secrets:
- mysql_user
- mysql_password
networks:
- backend
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.wordpress.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.wordpress.entrypoints=websecure"
- "traefik.http.routers.wordpress.tls.certresolver=letsencrypt"
redis:
image: harbor.company.com/infra/redis:7.0-alpine
container_name: redis-cache
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis_data:/data
networks:
- backend
# 反向代理(生产环境推荐Traefik)
traefik:
image: traefik:v2.9
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./config/traefik/config.yml:/etc/traefik/config.yml:ro
- acme_data:/acme
networks:
- proxy
secrets:
mysql_root_password:
file: ./secrets/mysql_root_password.txt
mysql_user:
file: ./secrets/mysql_user.txt
mysql_password:
file: ./secrets/mysql_password.txt
volumes:
mysql_data:
driver: local
driver_opts:
type: none
o: bind
device: /data/mysql
wp_content:
uploads:
redis_data:
acme_data:
networks:
backend:
driver: bridge
proxy:
external: true
四、综合对比与选择指南
1. 技术选型决策矩阵

2. 技术栈对比表
| 维度 | Docker Compose + Registry | Docker Compose + Harbor | Kubernetes + Harbor |
|---|---|---|---|
| 学习曲线 | ⭐⭐☆☆☆ (简单) | ⭐⭐⭐☆☆ (中等) | ⭐⭐⭐⭐⭐ (陡峭) |
| 部署速度 | ⭐⭐⭐⭐⭐ (分钟级) | ⭐⭐⭐⭐☆ (小时级) | ⭐⭐☆☆☆ (天级) |
| 功能完整性 | ⭐⭐☆☆☆ (基础) | ⭐⭐⭐⭐☆ (完善) | ⭐⭐⭐⭐⭐ (全面) |
| 扩展性 | ⭐⭐☆☆☆ (单机) | ⭐⭐⭐☆☆ (有限集群) | ⭐⭐⭐⭐⭐ (无限扩展) |
| 维护成本 | ⭐☆☆☆☆ (很低) | ⭐⭐☆☆☆ (较低) | ⭐⭐⭐⭐⭐ (很高) |
| 适合场景 | 个人项目/原型开发 | 中小企业生产环境 | 大型企业/云原生转型 |
结语
Docker Compose和私有仓库是现代容器化技术栈中的重要组成部分。通过本文的学习,你应该掌握了:
Docker Compose核心用法:从简单的WordPress部署到生产就绪的配置
私有仓库的选择与应用:从基础的Registry到企业级的Harbor
镜像生命周期管理:构建、标签、推送、安全扫描的全流程
渐进式演进策略:从小规模起步到企业级架构的平滑升级路径
记住技术选择的黄金法则:没有最好的技术,只有最适合的技术。根据你的团队规模、业务需求和资源预算,做出明智的选择。
随着云原生生态的快速发展,新的工具和技术不断涌现。建议保持持续学习的习惯,关注:
-
Docker Compose V2的新特性
-
Harbor的最新版本和安全更新
-
新兴的容器镜像仓库解决方案
-
GitOps和声明式部署的趋势
无论你是刚开始接触容器技术,还是已经在生产环境中大规模使用,希望本文都能为你提供有价值的参考和指导。祝你在容器化的道路上越走越远!