Docker 容器化 Web 服务架构搭建与自动化运维项目

项目描述:

基于 Linux 环境完成完整 Web 业务容器化落地,全程独立搭建、优化、运维整套容器架构。手动编写 Dockerfile 构建业务镜像并进行分层优化,提升镜像构建效率与安全性;使用 Docker Compose 完成多服务容器编排,统一管理服务启动、依赖、重启逻辑。配置数据卷实现数据持久化,避免容器重建数据丢失;对容器进行 CPU、内存资源配额限制,防止单容器抢占整机资源。部署 cAdvisor 实现容器资源监控,实时查看容器运行状态、资源占用情况。编写 Shell 自动化巡检脚本,结合 Crontab 实现分钟级容器健康巡检,自动识别异常退出容器并自愈重启,完善日志重定向收集,解决容器意外宕机业务中断、人工运维成本高的问题,保障 Web 服务稳定持续运行。

技术栈:

Linux、Shell、Docker、Docker Compose、cAdvisor、容器网络、数据卷持久化、定时任

环境准备:

  • 系统:CentOS 7 / CentOS 8 / Ubuntu 均可
  • 一台云服务器 / 虚拟机
  • 关闭防火墙、关闭 selinux

第一步:安装前的准备:

bash 复制代码
​# 1.更新依赖
[root@docker ~]# yum update -y

# 2.安装依赖工具
[root@docker ~]# yum install -y yum-utils

第二步 安装docker docker compose

bash 复制代码
[root@docker ~]# cat > /etc/yum.repos.d/docker-ce.repo <<EOF                                                                                                            [docker]
name=Docker
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/\$releasever/\$basear                                                                                         ch/stable                                                                                                                                                               enabled=1                                                                                                                                                               gpgcheck=0                                                                                                                                                              EOF                                                                                                                                                                     [root@docker ~]# yum clean all
正在更新 Subscription Management 软件仓库。
无法读取客户身份

本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。

17 个文件已删除
[root@docker ~]# yum makecache
正在更新 Subscription Management 软件仓库。
无法读取客户身份

本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。

Docker                                         117 kB/s |  83 kB     00:00
AppStream                                      242 MB/s | 7.7 MB     00:00
BaseOS                                         195 MB/s | 2.1 MB     00:00
元数据缓存已建立。
[root@docker ~]# yum install -y docker-ce docker-ce-cli containerd.io docker-co                                                                                         mpose-plugin
# docker-ce   服务端
# docker-ce-cli  客户端
# containerd.io  容器运行时,底层管理器
# docker-compose-plugin   compose的安装包
                                                           

第三步:开启ip转发配置国内docker加速器:

bash 复制代码
[root@docker ~]# cat > /etc/sysctl.d/docker.conf <<EOF
net.ipv4.ip_forward = 1
EOF
[root@docker ~]# sysctl --system
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
* Applying /usr/lib/sysctl.d/50-coredump.conf ...
* Applying /usr/lib/sysctl.d/50-default.conf ...
* Applying /usr/lib/sysctl.d/50-libkcapi-optmem_max.conf ...
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
* Applying /usr/lib/sysctl.d/50-redhat.conf ...
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/docker.conf ...
* Applying /etc/sysctl.conf ...
kernel.yama.ptrace_scope = 0
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h
kernel.core_pipe_limit = 16
fs.suid_dumpable = 2
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.eth0.rp_filter = 2
net.ipv4.conf.lo.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.eth0.promote_secondaries = 1
net.ipv4.conf.lo.promote_secondaries = 1
net.ipv4.ping_group_range = 0 2147483647
net.core.default_qdisc = fq_codel
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_regular = 1
fs.protected_fifos = 1
net.core.optmem_max = 81920
kernel.pid_max = 4194304
kernel.kptr_restrict = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.ip_forward = 1
[root@docker ~]# cat > /etc/docker/daemon.json <<EOF
{
    "registry-mirrors": ["https://docker.1ms.run"]
}
EOF

# 这个加速器不太好用  最后花钱有的代理  
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl  enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /u                                                                                         sr/lib/systemd/system/docker.service.

第四步: 搭建项目目录:

bash 复制代码
[root@docker ~]# mkdir -p /opt/web/{nginx,mysql,logs,app}
[root@docker ~]# cd /opt/web
[root@docker web]# ll
总用量 0
drwxr-xr-x 2 root root 6  8月 14 12:17 app
drwxr-xr-x 2 root root 6  8月 14 12:17 logs
drwxr-xr-x 2 root root 6  8月 14 12:17 mysql
drwxr-xr-x 2 root root 6  8月 14 12:17 nginx

第五步:创建镜像

bash 复制代码
[root@docker ~]# vim /opt/web/nginx/Dockerfile
FROM nginx:alpine
# 替换国内源、优化镜像
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 时区统一
RUN apk add --no-cache tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 拷贝自定义配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

第六步:部署nginx.conf

bash 复制代码
[root@docker ~]# vim /opt/web/nginx/nginx.conf
server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }

    # 日志输出到控制台(方便收集日志)
    access_log /dev/stdout;
    error_log /dev/stderr;
}
~

第七步:编写 Docker Compose 编排文件

bash 复制代码
[root@docker ~]# vim /opt/web/docker-compose.yml
version: '3'

services:
  nginx:
    build: ./nginx
    ports:
      - "80:80"
    volumes:
      - ./app:/usr/share/nginx/html # 为了持久化
      - ./logs:/var/log/nginx  # 为了日志不被丢失
    restart: always
    depends_on: # 在运行nginx前先运行mysql  
      - mysql
    # 限制资源(企业规范)
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M

  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    restart: always

第八步:部署测试页面,模拟业务代码

bash 复制代码
[root@docker ~]# vim /opt/web/app/index.html
<!DOCTYPE html>
<html lang="zh-CN">
        <head>
                    <meta charset="UTF-8">
                        <title>部署测试</title>
        </head>
        <body>
                    <h1>Docker Compose 容器化运维项目部署成功</h1>
        </body>
</html>
~

运行结果:

bash 复制代码
[root@docker web]# docker compose up -d
WARN[0000] /opt/web/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] up 14/14
 ✔ Image mysql:5.7 Pulled                                                                                                                                        1016.9s
[+] Building 7.6s (11/11) FINISHED
 => [internal] load local bake definitions                                                                                                                         0.0s
 => => reading from stdin 468B                                                                                                                                     0.0s
 => [internal] load build definition from Dockerfile                                                                                                               0.0s
 => => transferring dockerfile: 270B                                                                                                                               0.0s
 => [internal] load metadata for docker.io/library/nginx:alpine                                                                                                    1.2s
 => [internal] load .dockerignore                                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                                    0.0s
 => [1/4] FROM docker.io/library/nginx:alpine@sha256:4a73073bd557c65b759505da037898b61f1be6cbcc3c2c3aeac22d2a470c1752                                              4.0s
 => => resolve docker.io/library/nginx:alpine@sha256:4a73073bd557c65b759505da037898b61f1be6cbcc3c2c3aeac22d2a470c1752                                              0.0s
 => => sha256:390dc935348d8070e695fbaae2a4bb114fb9e69c59f628e7576036ee9d5244c9 1.40kB / 1.40kB                                                                     0.6s
 => => sha256:46519e7231d2eb5604df229beb44d59719a489eaa7aca52982535a010b07a9ed 20.31MB / 20.31MB                                                                   2.7s
 => => sha256:d0008c891db48b5f526d914bce9e8d889fe1a9d1f08291ae03fe97f871726f38 1.21kB / 1.21kB                                                                     0.7s
 => => sha256:46f977ee452f4399c208714afa034868d6056864f8a0cf3c643ab143dd802c80 404B / 404B                                                                         0.5s
 => => sha256:62bec68d7c31c4c8a19d812d84da5f7748e54690c037979945b6c5b6c924b142 957B / 957B                                                                         0.2s
 => => sha256:1223f016b4e4a2c21f7c49d4837fbfd47a9da6436b511690ca1e582fc2810d59 627B / 627B                                                                         0.2s
 => => sha256:3cd534fe98c64d68a1f4f1c83abb8d5cba7ecfd7be88e592389929d12e6253da 1.89MB / 1.89MB                                                                     1.5s
 => => sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4 3.85MB / 3.85MB                                                                     2.5s
 => => extracting sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4                                                                          0.1s
 => => extracting sha256:3cd534fe98c64d68a1f4f1c83abb8d5cba7ecfd7be88e592389929d12e6253da                                                                          0.1s
 => => extracting sha256:1223f016b4e4a2c21f7c49d4837fbfd47a9da6436b511690ca1e582fc2810d59                                                                          0.0s
 => => extracting sha256:62bec68d7c31c4c8a19d812d84da5f7748e54690c037979945b6c5b6c924b142                                                                          0.0s
 => => extracting sha256:46f977ee452f4399c208714afa034868d6056864f8a0cf3c643ab143dd802c80                                                                          0.0s
 => => extracting sha256:d0008c891db48b5f526d914bce9e8d889fe1a9d1f08291ae03fe97f871726f38                                                                          0.0s
 => => extracting sha256:390dc935348d8070e695fbaae2a4bb114fb9e69c59f628e7576036ee9d5244c9                                                                          0.0s
 => => extracting sha256:46519e7231d2eb5604df229beb44d59719a489eaa7aca52982535a010b07a9ed                                                                          0.5s
 => [internal] load build context                                                                                                                                  0.0s
 => => transferring context: 289B                                                                                                                                  0.0s
 => [2/4] RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories                                                                         0.7s
 => [3/4] RUN apk add --no-cache tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime                                                                     1.4s
 => [4/4] COPY nginx.conf /etc/nginx/conf.d/default.conf                                                                                                           0.0s
 => exporting to image                                                                                                                                             0.2s
 => => exporting layers                                                                                                                                            0.1s
 => => exporting manifest sha256:c50d135099e68af444908be8fc0259d6e3726d26eedd5a2d26709473fac450d9                                                                  0.0s
 => => exporting config sha256:7e901ac3ae637979e78d648012b2f6472cb5e1d05ed8fa6d512227630b4f9d02                                                                    0.0s
 => => exporting attestation manifest sha256:55cfa8d1e3a8cfd552cb587cb08ef4386b41fa26ff37a35c8f5228486106179d                                                      0.0s
 => => exporting manifest list sha256:a996487fd6f1631e576b0501b769192782a0fc58266cc5d4f08f34ae437236f2                                                             0.0s
 => => naming to docker.io/library/web-nginx:latest                                                                                                                0.0s
[+] up 18/18king to docker.io/library/web-nginx:latest                                                                                                             0.0s
 ✔ Image mysql:5.7       Pulled                                                                                                                                  1016.9s
 ✔ Image web-nginx       Built                                                                                                                                      7.7s
 ✔ Network web_default   Created                                                                                                                                    0.0s
 ✔ Container web-mysql-1 Started                                                                                                                                    0.3s
 ✔ Container web-nginx-1 Started                             

页面展示:

做到这里项目基本上框架就做好了

第九步: 部署 cAdvisor 监控容器状态

bash 复制代码
[root@docker ~]# vim /opt/web/monitor.yml
version: '3'
services:
  cadvisor:
    image: gcr.nju.edu.cn/cadvisor/cadvisor:v0.49.1
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro  # 这个是读取文件系统占用  磁盘空间 进程等信息
      - /var/run:/var/run:ro # # 获取容器基本信息的
      - /sys:/sys:ro #容器的cpu  内存   磁盘io
      - /var/lib/docker/:/var/lib/docker:ro # docker存储层信息
    restart: always

展示页面:

第十步:写一个自动检测容器宕机自动重启的脚本:

bash 复制代码
[root@docker ~]# vim /opt/web/check.sh
#!/bin/bash
cd /opt/web
if [ $(docker  compose ps -a | grep -c Exited) -ne 0 ];then
    echo "【异常】检测到容器宕机,执行重启"
    docker compose restart
fi

授权加定时任务:

bash 复制代码
[root@docker web]# chmod +x check.sh
[root@docker web]# crontab -e
*/1 * * * *  /opt/web/check.sh  >>  /opt/web/logs/check.logs 2>&1

展示效果:

看一下又没重启成功:

项目收获与个人总结:

项目收获:

  • 完整掌握Docker 全流程落地,熟练手写 Dockerfile、镜像优化、数据卷持久化、容器资源限制、网络配置、启停重启运维逻辑。
  • 熟练使用 Docker Compose 完成多容器项目编排,理解容器依赖、启动顺序、集群化单机部署架构。
  • 掌握容器监控方案,熟练部署 cAdvisor 监控容器资源使用率、运行状态,具备基础容器运维监控能力。
  • 独立开发 Shell 自动化运维脚本,结合 Crontab 实现定时巡检、故障自愈、日志收集,理解生产环境自动化运维思路。
  • 深度踩坑并解决 Compose V2 命令兼容、容器状态识别失效、定时任务环境差异、日志丢失等真实生产问题,具备扎实的容器排错、落地、优化能力。

个人总结:

通过本次 Docker 容器化 Web 服务架构搭建项目,我系统掌握了基于容器技术的 Web 服务部署与轻量化运维流程,彻底理解了传统服务器部署与容器化部署的区别,实操能力和架构思维得到了明显提升。

首先,我熟练掌握了 Docker 容器的基础运行原理,理解了内核网络参数对容器服务的重要性。通过配置 docker.conf 内核参数,掌握了开启 IP 转发、网桥流量转发等优化配置的作用,解决了容器网络互通、端口映射、外网访问等常见问题,明白了容器环境需要专门的内核调优才能保证服务稳定运行。

其次,我独立完成了 Nginx Web 服务的容器化配置。亲手编写并优化了 Nginx 站点配置,掌握了监听端口、静态资源目录挂载、日志标准输出等核心配置。尤其理解了容器环境中将日志输出至 /dev/stdout、/dev/stderr 的意义,解决了容器日志无法收集、无法排查问题的痛点,掌握了容器服务标准化日志运维方式。

再者,我熟练掌握了 Docker Compose 自动化编排部署的流程。通过编写 compose 配置文件,实现服务一键创建、启动、重启和销毁,摆脱了手动敲命令部署的繁琐流程,体会到了容器化部署轻量化、可移植、一致性高、运维便捷的优势。同时掌握了日常运维常用命令,能够独立排查容器启动失败、端口冲突、挂载异常、日志异常等常见问题。

最后,本次项目让我建立了完整的容器化 Web 服务架构思维。从内核环境调优、服务配置编写、容器挂载映射,到自动化启动运维,形成了一套完整的部署链路。不仅巩固了 Linux 网络与服务运维基础,也让我对微服务、容器化、自动化运维的工程化思想有了更清晰的认知。

相关推荐
技术传感器2 小时前
让 Hermes 自动完成一个软件需求:从 Issue 到 PR 的 AI 开发流水线
人工智能·架构·aigc·需求分析·issue
梦想的旅途22 小时前
企微 API 二次开发:利用 AI Agent 实现自动化运维
运维·人工智能·企业微信
Rain的Java大神之路2 小时前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构
安科瑞-小李2 小时前
铁路智能运维进化路线:自动化→状态可视→预测维护
运维·自动化·数据采集·能耗可视化
霸道流氓气质2 小时前
微服务架构中多实例消息抢占问题:技术解析与解决方案
微服务·云原生·架构
Dr.kangder2 小时前
嵌入式面试总结(十八)——JTAG调试
嵌入式硬件·面试·职场和发展·架构·嵌入式
酷可达拉斯3 小时前
自动化运维-Ansible任务控制与流程控制
运维·自动化·ansible
HiDev_3 小时前
【非标自动化】2、认识元器件(电机保护器)
运维·自动化
奈斯先生Vector3 小时前
AI 视频不是会动的图片:用 Shot Contract、时间码与音画质检构建可交付流水线
人工智能·重构·架构·prompt·aigc·音视频