openEuler入门学习教程,从入门到精通,openEuler 24.03 中的Docker Compose、Dockerfile 编写、私有仓库搭建 — 语法详解与实战案例(13)
·
Docker Compose、Dockerfile 编写、私有仓库搭建 — 语法详解与实战案例
一、引入
在实际生产环境中,单容器部署远远不够。我们需要:
- Dockerfile:自定义镜像,标准化应用环境
- Docker Compose:编排多容器应用(如 Web + DB + Cache)
- 私有仓库:安全存储和分发企业内部镜像(如 Harbor)
掌握本章内容,你将能构建完整的企业级容器化部署体系。
二、Dockerfile 编写
1. Dockerfile 基本结构与指令
| 指令 | 作用 | 示例 |
|---|---|---|
FROM | 基础镜像 | FROM ubuntu:22.04 |
LABEL | 镜像元数据 | LABEL maintainer="admin@example.com" |
RUN | 执行命令(构建时) | RUN apt update && apt install -y curl |
COPY | 复制文件(宿主→镜像) | COPY app.py /app/ |
ADD | 复制+自动解压(慎用) | ADD app.tar.gz /app/ |
WORKDIR | 设置工作目录 | WORKDIR /app |
ENV | 设置环境变量 | ENV PORT=8080 |
ARG | 构建参数(构建时传入) | ARG VERSION=1.0 |
EXPOSE | 声明端口(非实际映射) | EXPOSE 8080 |
VOLUME | 声明数据卷 | VOLUME ["/data"] |
USER | 设置运行用户 | USER appuser |
HEALTHCHECK | 健康检查 | HEALTHCHECK --interval=30s CMD curl -f http://localhost:8080/health |
CMD | 容器启动默认命令(可被覆盖) | CMD ["python", "app.py"] |
ENTRYPOINT | 入口点(不可被覆盖,常与 CMD 配合) | ENTRYPOINT ["python"] |
✅ 最佳实践:
- 使用
.dockerignore忽略不需要的文件- 合并 RUN 指令减少层数
- 使用非 root 用户运行
- 清理构建缓存(如 apt clean)
📘 案例1:Python Flask 应用 Dockerfile
# 文件:Dockerfile
# 构建一个 Python Flask Web 应用镜像
# 1. 基础镜像
FROM python:3.11-slim
# 2. 标签
LABEL maintainer="dev@example.com" \
version="1.0" \
description="Flask Web Application"
# 3. 设置工作目录
WORKDIR /app
# 4. 复制依赖文件(先复制 requirements,利用缓存)
COPY requirements.txt .
# 5. 安装依赖(合并命令,清理缓存)
RUN pip install --no-cache-dir -r requirements.txt && \
rm -rf /root/.cache
# 6. 创建非 root 用户
RUN useradd --create-home --shell /bin/bash appuser
USER appuser
# 7. 复制应用代码
COPY . .
# 8. 声明端口
EXPOSE 5000
# 9. 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5000/health || exit 1
# 10. 启动命令
CMD ["python", "app.py"]
requirements.txt 示例:
Flask==2.3.3
requests==2.31.0
app.py 示例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Docker!"
@app.route('/health')
def health():
return "OK", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
📘 案例2:构建并运行镜像
# 1. 构建镜像(-t 指定标签)
docker build -t my-flask-app:1.0 .
# 2. 查看镜像
docker images | grep my-flask-app
# 3. 运行容器
docker run -d -p 5000:5000 --name flask-app my-flask-app:1.0
# 4. 查看健康状态
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# 5. 访问应用
curl http://localhost:5000
# 输出:Hello from Docker!
# 6. 查看健康检查结果
docker inspect --format='{{json .State.Health}}' flask-app | python -m json.tool
三、Docker Compose 多容器编排
1. Docker Compose 安装(openEuler 24.03)
📘 案例3:安装 Docker Compose
# 1. 下载最新版(替换 vX.X.X 为最新版本)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 2. 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 3. 验证安装
docker-compose --version
# 输出:Docker Compose version vX.X.X
2. docker-compose.yml 语法详解
| 字段 | 作用 | 示例 |
|---|---|---|
version | Compose 文件版本 | version: '3.8' |
services | 定义服务(容器) | web:, db: |
image | 使用的镜像 | image: nginx:latest |
build | 构建上下文 | build: . 或 build: {context: ., dockerfile: Dockerfile} |
ports | 端口映射 | ports: ["8080:80"] |
volumes | 数据卷挂载 | volumes: ["./data:/var/lib/mysql"] |
environment | 环境变量 | environment: MYSQL_ROOT_PASSWORD: root |
depends_on | 依赖服务 | depends_on: [db] |
networks | 自定义网络 | networks: [app-net] |
restart | 重启策略 | restart: unless-stopped |
healthcheck | 健康检查 | 同 Dockerfile |
📘 案例4:LNMP 多容器编排(docker-compose.yml)
# 文件:docker-compose.yml
# 功能:编排 Nginx + PHP + MySQL 服务
version: '3.8'
services:
# 1. MySQL 服务
mysql:
image: mysql:8.0
container_name: mysql-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: MySqlRoot123!
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 20s
timeout: 10s
retries: 3
# 2. PHP 服务
php:
build: ./php # 使用自定义 Dockerfile
container_name: php-fpm
restart: unless-stopped
volumes:
- ./www:/var/www/html
depends_on:
- mysql
# 3. Nginx 服务
nginx:
image: nginx:latest
container_name: nginx-web
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./www:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- php
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
# 定义数据卷
volumes:
mysql_data:
# 定义网络(默认会创建)
networks:
default:
name: lnmp-network
目录结构:
project/
├── docker-compose.yml
├── nginx/
│ └── conf.d/
│ └── default.conf
├── php/
│ ├── Dockerfile
│ └── php.ini
└── www/
└── index.php
php/Dockerfile:
FROM php:8.2-fpm
RUN docker-php-ext-install mysqli pdo pdo_mysql
COPY php.ini /usr/local/etc/php/
WORKDIR /var/www/html
nginx/conf.d/default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
www/index.php:
<?php
phpinfo();
?>
📘 案例5:使用 Docker Compose 部署
# 1. 启动所有服务(-d 后台运行)
docker-compose up -d
# 2. 查看服务状态
docker-compose ps
# 3. 查看日志
docker-compose logs nginx
# 4. 实时跟踪日志
docker-compose logs -f php
# 5. 进入容器
docker-compose exec mysql mysql -uroot -p
# 6. 停止服务
docker-compose stop
# 7. 启动已停止的服务
docker-compose start
# 8. 重新构建并启动
docker-compose up -d --build
# 9. 删除所有容器和网络(保留卷)
docker-compose down
# 10. 删除所有(包括卷)
docker-compose down -v
四、私有仓库搭建 — Harbor
Harbor 是企业级 Docker Registry,支持权限管理、漏洞扫描、Web UI。
1. 安装 Harbor(openEuler 24.03)
📘 案例6:安装 Harbor
# 1. 安装必要依赖
sudo dnf install -y yum-utils device-mapper-persistent-data lvm2
# 2. 安装 Docker Compose(如未安装)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 3. 下载 Harbor 安装包
wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz
tar -xzf harbor-offline-installer-v2.9.0.tgz
cd harbor
# 4. 复制配置文件
cp harbor.yml.tmpl harbor.yml
# 5. 编辑配置文件
sudo vim harbor.yml
修改 harbor.yml 关键配置:
hostname: your-server-ip-or-domain # 如 192.168.1.100
# 注释掉 https 部分(测试环境可不用 HTTPS)
# https:
# port: 443
# certificate: /your/certificate/path
# private_key: /your/private/key/path
# admin 初始密码
harbor_admin_password: Harbor12345
# 数据目录
data_volume: /data/harbor
# 日志目录
log:
location: /var/log/harbor
# 6. 运行准备脚本
sudo ./prepare
# 7. 启动 Harbor
sudo ./install.sh
# 8. 检查服务状态
sudo docker-compose ps -f
# 9. 访问 Web UI
# 浏览器打开:http://your-server-ip
# 用户名:admin
# 密码:Harbor12345
2. 使用 Harbor 私有仓库
📘 案例7:推送和拉取镜像
# 1. 登录 Harbor(使用 admin 或创建的用户)
docker login your-server-ip -u admin -p Harbor12345
# 2. 标记本地镜像(格式:仓库地址/项目名/镜像名:标签)
docker tag my-flask-app:1.0 your-server-ip/library/my-flask-app:1.0
# 3. 推送镜像到 Harbor
docker push your-server-ip/library/my-flask-app:1.0
# 4. 在 Web UI 查看:http://your-server-ip/harbor/projects
# 5. 从 Harbor 拉取镜像(其他机器)
docker login your-server-ip -u admin -p Harbor12345
docker pull your-server-ip/library/my-flask-app:1.0
# 6. 在 docker-compose.yml 中使用私有镜像
# 修改 docker-compose.yml:
# image: your-server-ip/library/my-flask-app:1.0
✅ 在 Harbor Web UI 中可创建项目、用户、设置权限、扫描漏洞。
五、综合性实战案例
▶ 案例8:微服务架构一键部署(Spring Boot + MySQL + Redis)
# 文件:docker-compose.yml
# 功能:部署 Spring Boot 应用 + MySQL + Redis
version: '3.8'
services:
# 1. MySQL 服务
mysql:
image: mysql:8.0
container_name: mysql-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 20s
timeout: 10s
retries: 3
# 2. Redis 服务
redis:
image: redis:7.0
container_name: redis-cache
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
# 3. Spring Boot 应用
app:
build: ./app # 包含 Dockerfile 和 jar 包
container_name: spring-app
restart: unless-stopped
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/myapp
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root123
SPRING_REDIS_HOST: redis
SPRING_REDIS_PORT: 6379
depends_on:
- mysql
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
mysql_data:
redis_data:
networks:
default:
name: microservice-network
app/Dockerfile:
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY *.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
部署步骤:
# 1. 构建并启动
docker-compose up -d
# 2. 查看日志
docker-compose logs -f app
# 3. 访问应用
curl http://localhost:8080
# 4. 推送到私有仓库(可选)
docker-compose build
docker tag spring-app:latest your-harbor-ip/library/spring-app:1.0
docker push your-harbor-ip/library/spring-app:1.0
▶ 案例9:自动化构建与推送脚本(CI/CD 雏形)
#!/bin/bash
# 文件:build_push.sh
# 功能:自动构建镜像并推送到 Harbor
PROJECT_NAME="my-flask-app"
VERSION="1.0.0"
HARBOR_HOST="192.168.1.100"
HARBOR_PROJECT="library"
HARBOR_USER="admin"
HARBOR_PASS="Harbor12345"
IMAGE_NAME="$HARBOR_HOST/$HARBOR_PROJECT/$PROJECT_NAME:$VERSION"
echo "🚀 开始构建和推送镜像..."
# 1. 构建镜像
docker build -t $IMAGE_NAME .
# 2. 检查构建是否成功
if [ $? -ne 0 ]; then
echo "❌ 镜像构建失败!"
exit 1
fi
# 3. 登录 Harbor
echo "$HARBOR_PASS" | docker login $HARBOR_HOST -u $HARBOR_USER --password-stdin
# 4. 推送镜像
docker push $IMAGE_NAME
# 5. 清理本地镜像(可选)
# docker rmi $IMAGE_NAME
# 6. 更新 docker-compose.yml(可选)
sed -i "s|image: .*|image: $IMAGE_NAME|" docker-compose.yml
echo "🎉 镜像构建和推送完成!"
echo "📦 镜像地址: $IMAGE_NAME"
▶ 案例10:Harbor 备份与恢复脚本
#!/bin/bash
# 文件:harbor_backup.sh
# 功能:备份 Harbor 数据和配置
BACKUP_DIR="/backup/harbor/$(date +%Y%m%d_%H%M%S)"
HARBOR_DIR="/path/to/harbor" # Harbor 安装目录
DATA_DIR="/data/harbor" # 数据目录
echo "📦 开始备份 Harbor..."
# 1. 创建备份目录
mkdir -p $BACKUP_DIR
# 2. 停止 Harbor 服务
cd $HARBOR_DIR
sudo docker-compose down
# 3. 备份配置文件
cp harbor.yml $BACKUP_DIR/
cp common/config/registry/config.yml $BACKUP_DIR/
# 4. 备份数据目录
tar -czf $BACKUP_DIR/harbor_data.tar.gz -C / data/harbor
# 5. 备份数据库(如果使用外部数据库需单独备份)
# 此处假设使用 Harbor 内置数据库
sudo docker run --rm -v harbor-db:/var/lib/mysql -v $BACKUP_DIR:/backup \
alpine tar -czf /backup/harbor_db.tar.gz -C /var/lib/mysql .
# 6. 重启 Harbor
sudo docker-compose up -d
# 7. 显示备份结果
ls -lh $BACKUP_DIR
echo "✅ Harbor 备份完成!"
echo "📁 备份位置: $BACKUP_DIR"
六、小结
✅ 本章你已掌握:
- Dockerfile:编写规范、多阶段构建、健康检查、安全加固
- Docker Compose:多容器编排、服务依赖、网络配置、健康检查
- 私有仓库:Harbor 安装、镜像推送/拉取、权限管理
- 综合实战:微服务部署、自动化构建、Harbor 备份
📌 企业级容器化最佳实践:
- 使用多阶段构建减小镜像体积
- 非 root 用户运行容器
- 使用健康检查确保服务可用性
- 私有仓库管理企业镜像,避免依赖公网
- 定期备份 Harbor 数据和配置
- 结合 CI/CD 工具(如 Jenkins、GitLab CI)实现自动化部署
掌握本章内容后,你将能构建完整的企业级容器化应用部署体系,为云原生转型打下坚实基础!
更多推荐

所有评论(0)