写给前端仔仔的docker实战

那是19年,正在上大三的柏成用一堆屎山代码从零搭建了一款个人博客,对于一个刚刚入门的前端崽来说,想要部署在云服务器上,需要安装mysql,redis,配置环境变量 ....... 过五关斩六将,每一步都踩了好多好多坑

服务器到期后,柏成也没再续费.......

21年,柏成又想重启个人博客,哐哐哐一顿操作,顺利上线,还精挑细选了域名 burc.com.cn

服务器到期后,柏成也没再续费.......

25年初,柏成又想重启个人博客,问题来了,那么能不能一行命令,自动安装所有依赖,完成部署操作呢?

答案是:可以!docker 闪亮登场

docker 核心概念

我们先了解下 docker的几个核心概念:镜像、容器、仓库、Dockerfile

  • 镜像(Image): 镜像是容器的"模板",是将软件环境打包好的模板,用来创建容器的,一个镜像可以创建多个容器
  • 容器(Container): 应用程序及其依赖环境的运行实例,启动一个镜像就是一个容器,容器与容器之间相互隔离,并且互不影响, 可以简单理解为一个"轻量级、可移植的微型操作系统"
  • 仓库(Registry) : 类似于代码托管平台(如 GitHub),我们可以制作镜像然后 push 推送到云端的仓库,也可以从仓库 pull 拉取镜像
  • Dockerfile: 包含了一系列指令和配置,用于描述如何组装一个 docker镜像,相当于列出了镜像所需的原材料。通过 Dockerfile,你可以自动化地构建镜像,确保在不同的环境中都可以复现相同的容器

下面这张图展示了他们之间的关系

docker 基础操作

这里就不做过多介绍

docker-compose

通过一个单独的 YAML 文件定义和管理多个 Docker 容器的配置

统一配置 :通过一个 docker-compose.yml 文件,可以同时定义多个服务及其依赖关系(例如数据库、缓存、反向代理等)

一键管理:只需一条命令即可启动、停止所有服务

  • 启动:docker-compose up -d
  • 停止:docker-compose down

我们先对docker-compose.yml 有个大体认知,至于YAML文件里的内容是什么,最后附上源码

容器化部署实战

柏成通过 Docker 和 Docker Compose 实现了多容器化部署,包含后端服务、前端服务、数据库服务、redis服务以及 Nginx 服务,目录结构如下

前端服务(frontend)

react 文件夹下是前端 build打包的产物

Dockerfile 定义了如何构建前端镜像

powershell 复制代码
# 使用官方 Nginx 镜像作为基础镜像
FROM nginx:latest

# 将当前目录的内容拷贝到 Nginx 默认的静态文件目录
COPY ./react/ /usr/share/nginx/html/

# 暴露 Nginx 默认端口
EXPOSE 80

后端服务(backend)

node 文件夹下是整个后端项目

Dockerfile 定义了如何构建后端镜像

powershell 复制代码
# 使用 Node.js 构建阶段
FROM node:18

# 设置工作目录
WORKDIR /app

# 复制宿主机 ./node/目录中的文件 到容器的 /app/node/
COPY ./node/ ./

# 更换 npm 镜像源为淘宝镜像
RUN npm config set registry https://registry.npm.taobao.org/

# 禁用 SSL 证书验证(可选,只有在其他解决方法无效时使用)
RUN npm config set strict-ssl false

# 安装依赖
RUN npm install

# 暴露后端端口,这里其实没用。我们在node后端服务中暴露了5000端口,以node进程暴露的为准
# EXPOSE 5000

# 启动后端服务
CMD ["npm", "run", "prd"]

数据库服务

初始化脚本

blog.sql 是数据库初始化脚本,用于创建表和初始数据

我们在docker-compose.yml中通过 volumes 将其映射到了 mysql容器内部 /docker-entrypoint-initdb.d/blog.sql

/docker-entrypoint-initdb.d/是一个特殊目录,在 mysql容器初始化时,会自动执行放置在该目录下的 .sql 文件

powershell 复制代码
volumes:
   - ./mysql/blog.sql:/docker-entrypoint-initdb.d/blog.sql 

数据持久化

mysql_data 是用于 MySQL 数据库的持久化存储挂载点

默认情况下,所有数据存储在容器的文件系统中。如果容器被删除或重新创建,数据会丢失

我们将主机上的mysql_data目录挂载到容器内,用来持久化存储数据

当我们新增、更新 mysql数据时,mysql数据会映射到本地目录;反之当容器重启后,也会自动加载 ./mysql/mysql_data中的文件,自动恢复数据

powershell 复制代码
volumes:
   - ./mysql/mysql_data:/var/lib/mysql

Nginx服务

nginx.conf文件是 Nginx 的配置文件,用于反向代理前端和后端服务,以及提供静态资源服务

powershell 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 8M; # (设置客户端请求体最大值) 
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            proxy_pass http://frontend:80;  # 800 是 frontend 容器内部端口
            index  index.html index.htm;
        }

        # 配置后端 API 代理
        location /api/ {
            proxy_pass http://backend:5000;  # 替换为你的后端服务地址,5000 是 backend 容器内部端口
            
           # 超时设置
            proxy_connect_timeout 60s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;

            # 禁用缓存
            proxy_buffering off;

            # 保持连接
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

docker-compose.yml

docker-compose.yml全部源码如下

powershell 复制代码
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80" # 将主机的 80 端口映射到容器的 80 端口
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf # 挂载自定义的 Nginx 配置文件
    depends_on:
      - frontend
      - backend
    networks:
      - app_network
      
  frontend:
    build:
      context: ./frontend # 指定前端项目 ./fronten文件夹作为构建上下文
      dockerfile: Dockerfile # 指定构建镜像时使用的 Dockerfile
    ports:
      - "3001:80" # 将容器内的 80 端口映射到主机的 3001 端口,3001端口供外部访问
    depends_on:
      - backend # 指定该服务依赖 backend,确保 backend 服务先启动
    networks:
      - app_network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8001:5000" # 将容器内的 5000 端口映射到主机的 8001 端口,8001端口供外部访问
    depends_on: 
      # 后端服务依赖 mysql 和 redis 服务,确保它们先启动
      mysql: # backend 服务会等待 mysql 服务的健康检查(healthcheck)通过后再启动
        condition: service_healthy
      redis: # backend 服务会等待 redis 服务容器启动
        condition: service_started
    networks:
      - app_network

  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: always
    command: --default-authentication-plugin=mysql_native_password # 身份验证协议兼容
    ports:
      - "3307:3306" # 将容器内的 3306 端口(MySQL 默认端口)映射到主机的 3307 端口
    environment:
      MYSQL_ROOT_PASSWORD: 123456 # 设置 root用户密码
      MYSQL_DATABASE: blog # 初始化时会自动创建一个名为 blog 的数据库
    volumes:
      # 将主机上的 ./mysql/blog.sql 文件(一个 SQL 脚本文件)挂载到容器内的 /docker-entrypoint-initdb.d/blog.sql 目录
      # 特殊目录 /docker-entrypoint-initdb.d/ : 在容器初始化时,会自动执行放置在 /docker-entrypoint-initdb.d/ 目录中的 .sql 文件
      # 因此,当容器第一次启动时, 执行 blog.sql 来初始化数据库表结构
      - ./mysql/blog.sql:/docker-entrypoint-initdb.d/blog.sql 
      # 默认情况下,所有数据存储在容器的文件系统中。如果容器被删除或重新创建,数据会丢失
      # 我们将主机上的./mysql/mysql_data目录 挂载到容器内,用来持久化存储数据
      # 当我们通过项目向 MySQL新增、更新数据时,MySQL 数据目录会地映射到本地目录;反之当容器重启后,会自动加载 ./mysql/mysql_data中的文件,自动恢复数据
      - ./mysql/mysql_data:/var/lib/mysql
    healthcheck: # 定义健康检查,确保 mysql 服务在正常运行后标记为健康
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p666666"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - app_network

  redis:
    image: redis:alpine
    container_name: redis
    ports:
      - "6379:6379"
    networks:
      - app_network

# 显式声明一个网络,并将服务连接到该网络(默认创建的网络好像不太行。。。)
networks:
  app_network:
    driver: bridge

结语

这样我们就实现了 docker容器化部署,通过一行命令即可启动所有服务并将其运行在后台,以后,柏成个人博客再次迁移服务器时,就不用一个一个安装服务了,爽歪歪啊!

powershell 复制代码
docker-compose up -d
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
金刚猿6 小时前
01_虚拟机中间件部署_root 用户安装 docker 容器,配置非root用户权限
docker·中间件·容器
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端