docker-dockerfile练习

docker-dockerfile练习

    • [1. 开发环境标准化](#1. 开发环境标准化)
    • [2. 静态网站托管](#2. 静态网站托管)
    • [3. 多服务应用(WordPress)](#3. 多服务应用(WordPress))
    • [4. 微服务+负载均衡](#4. 微服务+负载均衡)
    • [5. 数据持久化与备份](#5. 数据持久化与备份)
    • [6. 多阶段构建优化镜像](#6. 多阶段构建优化镜像)
    • [7. 日志集中管理(EFK/ELK)](#7. 日志集中管理(EFK/ELK))
    • [8. 私有镜像仓库与CI模拟](#8. 私有镜像仓库与CI模拟)
    • [9. 网络隔离与通信](#9. 网络隔离与通信)
    • [10. 安全加固:以非root用户运行](#10. 安全加固:以非root用户运行)
    • [11. 资源限制与健康检查](#11. 资源限制与健康检查)
    • [12. Docker Swarm 集群部署](#12. Docker Swarm 集群部署)

1. 开发环境标准化

背景 :公司新入职了几名Python开发,每个人的本地环境(Python版本、依赖包)不一致,导致"在我电脑上能跑"的问题频发。
需求

  • 为现有的一个Python Flask项目(假设项目代码在Git仓库中)编写Dockerfile。
  • 要求使用Python 3.9 slim镜像,安装requirements.txt中的依赖,暴露5000端口。
  • 开发人员能够通过一条命令启动容器,并在本地修改代码后容器自动重载(使用volume挂载代码)。
  • 最终开发团队所有人都使用同一个Docker镜像运行项目。

a.在/app路径中创建dockerfile文件

bash 复制代码
# 要求使用Python 3.9 slim镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 安装`requirements.txt`中的依赖
COPY requirements.txt .
# 安装python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 将项目代码复制到容器(开发时会用 volume 覆盖,此步骤用于构建完整镜像)
# 将宿主机上项目根目录的所有文件,复制到镜像的 /app 目录下。
COPY . .

# 设置环境变量,使 Flask 以开发模式运行并开启自动重载
ENV FLASK_APP=app.py
ENV FLASK_ENV=development
ENV FLASK_DEBUG=1

# 暴露5000端口
EXPOSE 5000

# 启动命令:flask run 监听所有地址,开启重载
CMD ["flask", "run", "--host=0.0.0.0", "--port=5000", "--reload"]

b.构建镜像

bash 复制代码
# 在myapp文件夹执行
docker build -t my-flask-app .

# 推送镜像
docker tag my-flask-app your-registry/my-flask-app:latest
docker push your-registry/my-flask-app:latest

# 拉取镜像
docker pull your-registry/my-flask-app:latest

c.开发时运行容器

bash 复制代码
docker run -p 5000:5000 -v $(pwd):/app your-registry/my-flask-app
  • -p 5000:5000:将容器 5000 端口映射到宿主机,访问 http://localhost:5000 即可。
  • -v $(pwd):/app:将当前目录挂载到容器的 /app,覆盖镜像中的代码,本地修改即时生效。
  • your-registry/my-flask-app:公司内部docker hub的名称
  • 容器启动后,Flask 会监视文件变化并自动重启服务。

2. 静态网站托管

背景 :市场部需要上线一个简单的品牌展示静态网站(HTML+CSS+JS),希望快速部署并能随时更新内容。
需求

  • 使用Nginx官方镜像,将本地./public目录下的静态文件打包到镜像中。
  • 编写Dockerfile,复制文件到/usr/share/nginx/html
  • 构建镜像,运行容器并映射宿主机8080端口,访问http://localhost:8080看到网站。
  • 优化:未来更新内容只需要替换本地文件并重新构建镜像,或通过挂载卷实现热更新。

a.创建dockerfile文件

bash 复制代码
# 使用Nginx官方镜像
FROM nginx:alpine

# 将本地`./public`目录下的静态文件打包到镜像中
COPY ./public /usr/share/nginx/html

# 映射宿主机8080端口
EXPOSE 80

b.构建镜像

bash 复制代码
docker build -t my-nginx-app .

# 推送镜像
docker tag my-nginx-app your-registry/my-nginx-app:latest
docker push your-registry/my-nginx-app:latest

# 拉取镜像
docker pull your-registry/my-nginx-app:lates

c.运行容器

bash 复制代码
docker run -d -p 8080:80 -v $(pwd):/public:/usr/share/nginx/html:ro your-registry/my-nginx-app

3. 多服务应用(WordPress)

背景 :公司要搭建一个企业博客,运维团队希望用WordPress快速实现,同时保证数据不丢失。
需求

  • 使用docker-compose.yml定义两个服务:db(MySQL 5.7)和wordpress(最新版PHP+Apache)。
  • MySQL需设置root密码、创建数据库,数据持久化到宿主机./mysql_data目录。
  • WordPress服务链接到MySQL,并暴露80端口,访问即可安装博客。
  • 要求容器重启后数据依然存在。

a.创建yaml文件

bash 复制代码
version: '3'                                        # 是Compose文件版本

services:                                           # 定义两个服务
  db:
    image: mysql:5.7
    container_name: wordpress_db
    restart: always                                 # 确保容器退出时自动重启
    environment:
      MYSQL_ROOT_PASSWORD: QAZ@!123qqaa             # 设置 root 密码
      MYSQL_DATABASE: wordpress                     # 自动创建名为 wordpress 的数据库
    volumes:
      - ./mysql_data:/var/lib/mysql                 # 将数据库数据持久化到宿主机当前目录的 mysql_data 文件夹
    ports:
      - "3306:3306"                                 # (可选)暴露 MySQL 端口,通常不需要对外暴露,可注释掉

  wordpress:
    image: wordpress:latest
    container_name: wordpress_app
    restart: always                                 # 确保容器退出时自动重启
    depends_on:
      - db                                          # 确保数据库先启动
    ports:
      - "8080:80"                                   # 将容器的 80 端口映射到宿主机的 8080 端口
    environment:
      WORDPRESS_DB_HOST: db:3306                    # 数据库服务名(db)加端口
      WORDPRESS_DB_USER: root                       # 连接数据库的用户名(此处使用 root)
      WORDPRESS_DB_PASSWORD: QAZ@!123qqaa           # 对应上面设置的 root 密码
      WORDPRESS_DB_NAME: wordpress                  # 数据库名
    # 可选:持久化 WordPress 上传的文件和插件(如需完整备份可取消注释)
    # volumes:
    #   - ./wp-content:/var/www/html/wp-content

运行:

bash 复制代码
# 首次启动会拉取 MySQL 和 WordPress 镜像。
docker-compose up -d

停止:

bash 复制代码
docker-compose down

4. 微服务+负载均衡

背景 :公司有一个Node.js的API服务,访问量逐渐增大,需要水平扩展并统一入口。
需求

  • 编写Node.js应用Dockerfile,应用监听3000端口,返回当前容器的主机名(或IP)便于验证负载。
  • 使用docker-compose定义:
    • app服务:构建本地镜像,并启动3个副本(--scale app=3)。
    • nginx服务:使用官方nginx镜像,配置反向代理将请求分发到3个app实例(轮询)。
  • 测试访问nginx(80端口),每次刷新应看到不同容器返回的信息。

5. 数据持久化与备份

背景 :公司内部使用PostgreSQL作为核心业务数据库,需要定期备份数据,同时避免容器删除导致数据丢失。
需求

  • 运行PostgreSQL容器,使用命名卷(db-data)持久化数据库文件。
  • 设置环境变量初始化数据库和用户。
  • 创建一个临时容器(如postgres:latest)挂载同一个卷,并执行pg_dump备份数据到宿主机。
  • 模拟删除原容器,重新创建一个新容器使用相同卷,验证数据是否恢复。

6. 多阶段构建优化镜像

背景 :开发了一个Go语言编写的REST API,但直接构建的镜像包含了编译工具,体积超过500MB,部署慢。
需求

  • 编写多阶段Dockerfile:
    • 阶段一:使用golang:1.18作为构建环境,编译出二进制文件。
    • 阶段二:使用alpine:latest,仅复制编译好的二进制文件,并设置CMD运行它。
  • 要求最终镜像大小控制在20MB以内。
  • 构建并运行,验证API功能正常。

7. 日志集中管理(EFK/ELK)

背景 :公司有多个微服务容器,日志分散在各个主机上,排查问题困难。需要统一收集、检索和可视化。
需求

  • 使用docker-compose部署Elasticsearch、Fluentd(或Logstash)、Kibana。
  • 配置Fluentd收集所有容器的标准输出日志,发送到Elasticsearch。
  • 在Kibana中创建索引模式,能够查看和搜索日志。
  • 额外:让其中一个应用产生不同级别的日志,验证日志收集。

8. 私有镜像仓库与CI模拟

背景 :公司不允许将镜像推送到Docker Hub,需要搭建内部镜像仓库,并模拟CI流程:代码提交后自动构建并推送到私有仓库。
需求

  • 运行一个registry:2容器作为私有仓库,挂载本地目录存储镜像,端口映射到5000。
  • 编写一个简单的应用Dockerfile,构建后打上标签localhost:5000/myapp:latest,推送到私有仓库。
  • 从另一台机器(或本机删除原镜像后)拉取并运行该镜像,验证私有仓库可用。
  • 模拟CI:写一个shell脚本,自动执行构建、打标签、推送。

9. 网络隔离与通信

背景 :公司有一个三层的应用:前端Nginx、后端API、数据库。要求前端可以访问API,API可以访问数据库,但数据库不能直接暴露给前端,且外界只能访问Nginx。
需求

  • 创建两个自定义网络:frontendbackend
  • Nginx容器连接frontend网络,同时通过某种方式能访问API(例如将API也连入frontend,但API还需要访问数据库)。
  • API容器同时连接frontendbackend网络。
  • 数据库容器只连接backend网络。
  • 测试:从Nginx容器能ping通API,但不能ping通数据库;从API容器能ping通数据库;外部无法直接访问API和数据库端口。

10. 安全加固:以非root用户运行

背景 :安全团队扫描发现,公司很多容器默认以root运行,存在安全隐患。要求所有应用容器必须使用非root用户。
需求

  • 选择一个基础镜像(如node:14),在Dockerfile中创建用户appuser,并赋予其对应用目录的权限。
  • 确保容器启动命令使用该用户(USER appuser)。
  • 构建镜像,运行后进入容器验证用户身份,并验证应用是否能正常监听端口(可能需要使用大于1024的端口或设置权限)。
  • 注意:如果应用需要绑定80端口,需要额外处理(如使用authbind或转发)。

11. 资源限制与健康检查

背景 :某Java应用消耗内存较高,偶尔会因为内存不足被OOM Killer杀死。运维希望限制容器资源,并增加健康检查以便自动恢复。
需求

  • 编写Dockerfile运行一个Java应用(可以是简单的Spring Boot示例)。
  • 使用docker run时限制内存为512M、CPU为0.5核。
  • 在Dockerfile中添加HEALTHCHECK指令,定期检查应用的健康端点(如/actuator/health)。
  • 运行容器,观察资源限制效果,并模拟应用故障,查看Docker的健康状态变化。

12. Docker Swarm 集群部署

背景 :公司要将一个Web服务部署到三台服务器上,需要实现高可用和滚动更新。
需求

  • 搭建一个单节点Swarm集群(或使用虚拟机模拟多节点)。
  • 创建一个docker-compose.yml(version 3.8)定义服务,包含:
    • web服务:使用前面构建的镜像,部署2个副本,更新策略为滚动更新。
    • redis服务:用于会话缓存。
  • 将服务部署为Stack(docker stack deploy)。
  • 模拟滚动更新:修改镜像标签,重新部署,观察更新过程服务不中断。
  • 将服务暴露到集群外部(使用路由网或发布端口)。
相关推荐
Malone-AI2 小时前
docker换镜像源(docker desktop)
docker·容器
机 _ 长2 小时前
NVIDIA 显卡驱动安装指南 (CentOS Stream 9 / RTX 5090)
linux·运维·centos
赛博云推-Twitter热门霸屏工具2 小时前
推特自动化营销软件推荐:赛博云推实现Twitter热门霸屏与精准获客
运维·自动化·媒体·twitter
网云工程师手记3 小时前
企业多出口负载与故障切换实战:4 种调度模式 + 主备线路高可用
运维·服务器·网络·安全·网络安全
深圳市恒讯科技3 小时前
大带宽服务器和CDN加速如何配合使用?
运维·服务器
the sun343 小时前
打通嵌入式与 Linux:USB 转串口通信实战
linux·运维·服务器
qhqh3103 小时前
k8s的service、ingress controller和ingress
云原生·容器·kubernetes
susu10830189114 小时前
Ubuntu 离线环境 安装 Docker Compose
运维·docker·容器
要开心吖ZSH4 小时前
(三)OpenClaw 云端服务器控制本地 Windows 浏览器完整配置指南(SSH方式)
运维·服务器·windows·openclaw