Docker Compose与私有仓库部署指南

 更新时间:2025年12月12日 09:36:30   作者:士别三日。  
本文介绍了DockerCompose和Harbor在现代应用开发中的应用,通过WordPress实战展示了如何使用DockerCompose进行单机编排,并通过Harbor实现企业级私有仓库的管理,感兴趣的朋友跟随小编一起看看吧

引言

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

一、Docker Compose:单机编排的利器

1. Docker Compose在容器编排生态中的位置

关键观点

  • Docker Compose:学习门槛低,适合入门和快速原型开发
  • Kubernetes:功能强大但复杂,需要专门团队维护
  • 渐进式路径:Compose → Kubernetes是最佳学习路径

2. Docker Compose快速安装指南

# 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 项目结构规划

wordpress-site/
├── docker-compose.yml          # 编排配置文件
├── .env                        # 环境变量文件(敏感信息)
├── db_data/                    # MySQL数据目录
│   └── [自动创建]
├── web_data/                   # WordPress文件目录
│   └── [自动创建]
└── nginx-conf/                 # Nginx配置(可选扩展)
    └── wordpress.conf

3.2 完整的docker-compose.yml配置

# 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文件)

# 数据库配置
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 一键部署与管理

#!/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管理命令大全

#  基础操作
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 基础安装与配置

#!/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 镜像推送到私有仓库

# 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 环境准备

#!/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 离线安装

#!/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日常使用

#!/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(生产就绪)

# 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和声明式部署的趋势

无论你是刚开始接触容器技术,还是已经在生产环境中大规模使用,希望本文都能为你提供有价值的参考和指导。祝你在容器化的道路上越走越远!

相关文章

  • docker安装OpenWebUI报错500的原因及解决方法

    docker安装OpenWebUI报错500的原因及解决方法

    Open WebUI是一个可扩展、功能丰富且用户友好的自托管WebUI,旨在完全离线操作,这篇文章主要介绍了docker安装OpenWebUI报错500的原因及解决方法,需要的朋友可以参考下
    2025-07-07
  • Docker 容器全部停止的几种方法实现

    Docker 容器全部停止的几种方法实现

    我们需要停止所有的容器时,可以使用一些命令来实现,本文主要介绍了Docker 容器全部停止的几种方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • Docker加载镜像时报错no space left on device的彻底解决方案

    Docker加载镜像时报错no space left on device的彻底解

    本文详细记录了在部署FastDDS镜像时遇到磁盘空间不足的问题,并介绍了从排查到彻底解决的完整过程,通过分析根分区空间占用情况,将Docker数据根目录迁移到大分区,并修改daemon.json文件中的data-root配置,最终成功解决了问题,需要的朋友可以参考下
    2025-11-11
  • 搭建一个私有的Docker registry教程

    搭建一个私有的Docker registry教程

    这篇文章提供了一个非常务实的方法来处理搭建私有Docker registry时出现的各种错综复杂的情况。我们将会使用一个运行于DigitalOcean(之后简称为DO)的非常小巧的512MB VPS 实例
    2016-09-09
  • CentOS 8.4安装Docker的详细教程

    CentOS 8.4安装Docker的详细教程

    这篇文章主要介绍了CentOS 8.4安装Docker的详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • docker搭建jenkins服务的示例

    docker搭建jenkins服务的示例

    这篇文章主要介绍了docker搭建jenkins服务的示例,帮助大家更好的理解和使用docker容器,感兴趣的朋友可以了解下
    2020-09-09
  • Docker连接超时的5种快速解决方法总结

    Docker连接超时的5种快速解决方法总结

    在实际的开发和测试过程中,模拟网络请求超时是非常有必要的,因为在真实的生产环境中,网络请求超时是常见的情况之一,这篇文章主要介绍了Docker连接超时的5种快速解决方法,需要的朋友可以参考下
    2025-08-08
  • 编写最佳的Dockerfile的方法

    编写最佳的Dockerfile的方法

    本文给大家分享的是如何编写最佳的dockerfile的方法,通过具体实例帮助大家快速掌握编写Dockerfile的技巧
    2017-06-06
  • Docker容器数据卷介绍及操作示例

    Docker容器数据卷介绍及操作示例

    这篇文章主要为大家介绍了Docker容器数据卷介绍及操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • docker run容器运行的方法实现

    docker run容器运行的方法实现

    本文主要介绍了docker run容器运行的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论