Docker部署全栈项目实操?

访客 全栈框架 1

《从零到一:Docker部署全栈项目实操指南(附避坑清单)》


目录导读

  1. 全栈容器化的核心价值:为何你的项目必须用Docker?
  2. 前后端分离的镜像构建实战:从Dockerfile到多阶段构建
  3. Nginx反向代理 + 数据库容器化编排
  4. docker-compose一键部署:网络、环境变量与数据持久化
  5. 生产环境踩坑记录:权限、跨域、日志与性能调优
  6. 问答环节:关于Docker部署的5个高频问题

全栈容器化的核心价值

传统部署方式中,前端(React/Vue)、后端(Node.js/Java/Python)、数据库(MySQL/MongoDB)运行时环境若不一致,极易出现“在我电脑上能跑”的尴尬,Docker通过容器化将应用及依赖打包为标准镜像,确保开发、测试、生产环境一致。

实操收益

  • 环境隔离:每个微服务独立容器,互不干扰
  • 快速伸缩:基于Kubernetes可水平扩展容器实例
  • 版本控制:每个镜像对应特定代码Commit

前后端分离的镜像构建实战

前端镜像:Nginx多阶段构建

# 构建阶段
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

技巧:使用.dockerignore排除node_modules、.env等文件,减小镜像体积。

后端镜像:轻量级运行

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

避坑:若后端依赖sharp等C++库,需安装build-basepython3等编译工具,建议使用node:18-slim基础镜像代替alpine以减少兼容问题。

Nginx反向代理 + 数据库容器化编排

Docker-compose.yml 核心配置

version: '3.8'
services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - app-net
  backend:
    build: ./backend
    environment:
      - DB_HOST=mariadb
      - DB_USER=root
      - DB_PASSWORD=secret
    ports:
      - "3000:3000"
    depends_on:
      - mariadb
    networks:
      - app-net
  mariadb:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - app-net
volumes:
  db-data:
networks:
  app-net:

关键点

  • 网络隔离:所有服务共享app-net,通过服务名(如backend)互相访问,无需IP绑定
  • 数据持久化:数据库挂载命名卷db-data,防止容器重启丢失数据
  • 端口暴露:仅前端暴露80端口,后端和数据库不对外暴露更安全

docker-compose一键部署

# 在项目根目录执行
docker-compose up -d --build

生产环境优化建议

  • 环境变量外置:使用.env文件,在compose中通过${VARIABLE}引用
  • 健康检查:为后端添加healthcheck,确保服务就绪后再启动Nginx
  • 日志切割:配置logging驱动限制日志文件大小,避免磁盘爆满

生产环境踩坑记录

① 权限与用户映射

容器默认以root运行,挂载宿主机目录时可能产生文件所有权问题。
解决:在Dockerfile中创建特定用户(如node),并赋予挂载目录读写权限。

② 跨域请求失败

前后端不同容器端口时,浏览器可能拦截跨域请求。
解决:Nginx统一转发,配置如下:

location /api/ {
    proxy_pass http://backend:3000/;
    add_header Access-Control-Allow-Origin *;
}

③ 容器时区不一致

默认UTC时区导致日志时间偏差。
解决:在docker-compose中添加环境变量TZ=Asia/Shanghai,或挂载宿主机时区文件。

④ 性能调优

  • 减少镜像层:合并RUN指令,使用apt-get update && apt-get install -y
  • 使用Alpine镜像:体积缩小60%,但注意部分依赖需额外编译工具

问答环节:关于Docker部署的5个高频问题

Q1:Docker容器中的数据库如何备份?
A:使用docker exec导出SQL文件:docker exec mariadb-container mysqldump -u root -p myapp > backup.sql,或挂载卷定时备份backup目录。

Q2:如何更新部署?
A:只需修改代码后重新docker-compose up -d --build,Docker会自动使用新镜像重建更改的服务。

Q3:容器日志占用磁盘太多怎么办?
A:在docker-compose.yml中添加:

logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

Q4:是否必须使用docker-compose?
A:小型项目可用;但多服务场景强烈推荐Compose(或K8s),让部署步骤从10步缩至1条命令。

Q5:前端静态资源如何更新而不重建镜像?
A:使用volumes挂载宿主机静态文件目录,但生产环境应走CDN + 持续部署流水线。

标签: Docker部署 全栈

抱歉,评论功能暂时关闭!