【每天一个小笔记】01 Docker 部署项目

最近在离线环境下上线部署了一个项目,需要搞各种依赖,被离线环境搞得痛不欲生,之前了解过Docker,好像可以解决离线部署的痛点,所以进行了一次学习。根据我当前的Vue+Django+Mysql进行一次Docker部署。

一、Docker的基本信息

Docker 的定义:

Docker 是一个开源的容器化平台,用于开发、部署和运行应用程序。它通过容器技术将应用程序及其依赖项打包在一起,确保在不同环境中运行的一致性。

Docker 的核心组件:

Docker 引擎:核心运行时环境,负责创建和管理容器。
Docker 镜像:轻量级、可执行的软件包,包含运行应用程序所需的代码、库和配置。
Docker 容器:镜像的运行实例,提供隔离的环境运行应用程序。

Docker 的主要优势:

环境一致性:消除“在我机器上能运行”的问题,确保开发、测试和生产环境一致。
轻量高效:容器共享主机操作系统内核,启动快且资源占用低。
快速部署:镜像可快速分发和部署,适合持续集成和持续交付(CI/CD)。

Docker 的典型应用场景:

微服务架构:将应用程序分解为多个独立容器,便于扩展和维护。
开发环境标准化:团队共享相同的开发环境,减少配置冲突。
云原生应用:与 Kubernetes 等编排工具结合,支持大规模容器化部署。

Docker 的基本命令示例:

# 拉取镜像  
docker pull nginx  

# 运行容器  
docker run -d -p 8080:80 --name my-nginx nginx  

# 列出运行中的容器  
docker ps  

# 停止容器  
docker stop my-nginx  

Docker 与传统虚拟机的区别:

虚拟机:模拟完整操作系统,占用资源多,启动慢。
Docker 容器:共享主机内核,轻量且启动快,适合高密度部署。

Docker 通过容器化技术显著提升了软件开发和部署的效率,成为现代 DevOps 的重要工具之一。

二、Vue+Django+MySQL Docker 全流程部署

1、前置准备:安装 Docker 工具(必做)

首先得把 Docker 的 “工具箱” 装上,包含Docker(创建集装箱)和Docker Compose(管理多个集装箱),不同系统安装方式如下:

Windows/Mac 系统:

直接下载「Docker Desktop」(一键安装,自带 Docker Compose):

  • 下载地址:https://www.docker.com/products/docker-desktop/

  • 安装步骤:双击安装包,一路 “下一步”(不用改默认配置),安装完成后启动 Docker Desktop(桌面会有鲸鱼图标,变绿就是启动成功)。

我是在windows系统上进行的一次尝试,linux找机会再尝试啦。在windows上尝试Docker当然得先有Docker.desktop啦,幸运的是我在尝试dify的时候就已经下载安装了:安装Dorker Desktop

2、整理项目目录(像整理文件柜一样)

先建一个总文件夹(比如叫vue_django_docker),然后把前端、后端项目按下面的结构放好,目录结构必须严格对应(否则后续配置会找不到文件):

vue_django_docker/  # 总文件夹(随便命名,建议英文)
├── docker-compose.yml  # 后续要创建的“总配置文件”(管三个服务)
├── frontend/  # 前端文件夹(必须叫这个名字,放Vue项目)
│   ├── Dockerfile  # 后续要创建的前端配置文件
│   ├── package.json  # Vue项目自带的(有这个文件说明是Vue项目根目录)
│   ├── src/  # Vue项目自带的源码文件夹
│   └── (其他Vue项目文件,比如public、vue.config.js等)
└── backend/  # 后端文件夹(必须叫这个名字,放Django项目)
    ├── Dockerfile  # 后续要创建的后端配置文件
    ├── requirements.txt  # Django依赖清单(后续创建)
    ├── manage.py  # Django项目自带的(有这个文件说明是Django项目根目录)
    └── (其他Django项目文件,比如项目文件夹、apps等)

操作步骤:

  1. 新建总文件夹vue_django_docker

  2. 把你的 Vue 项目完整复制到frontend文件夹(确保frontend里有package.jsonsrc);

  3. 把你的 Django 项目完整复制到backend文件夹(确保backend里有manage.py);

  4. 暂时先空着docker-compose.ymlfrontend/Dockerfilebackend/Dockerfilebackend/requirements.txt,后续一步步创建。

AI说前后端文件必须叫frontend和backend当然不是必须的,可以取其他的名称,不过需要注意:如果修改了文件夹名称,必须同步修改相关配置文件中的对应引用,否则会导致配置失效

3、编写各服务的 “集装箱配置”(Dockerfile)

每个服务(前端、后端)需要一个Dockerfile,告诉 Docker “怎么打造这个集装箱”,不用懂原理,复制粘贴改少量内容即可。

前端 Vue 的配置(frontend/Dockerfile)

frontend文件夹里新建一个文件,命名为Dockerfile没有后缀名,注意大小写),粘贴以下内容:

# 第一步:打包Vue项目(生成静态文件)
FROM node:16-alpine as builder
WORKDIR /app
# 复制Vue的依赖文件,安装依赖(用国内镜像加速)
COPY package.json package-lock.json ./
RUN npm install --registry=https://registry.npmmirror.com
# 复制所有Vue文件,打包生成静态文件
COPY . ./
RUN npm run build
​
# 第二步:用Nginx托管静态文件(提供访问服务)
FROM nginx:alpine
# 把第一步打包好的文件复制到Nginx里
COPY --from=builder /app/dist /usr/share/nginx/html
# 暴露80端口(外部可以访问)
EXPOSE 80
# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]

✅ 无需修改,直接保存即可(只要你的 Vue 项目能正常执行npm run build,这个配置就管用)。

后端 Django 的配置

(1)先创建依赖清单(backend/requirements.txt)

backend文件夹里新建requirements.txt(有后缀名),粘贴以下内容(根据你的 Django 版本微调,添加其他需要的python库):

Django==3.2.20  # 如果你知道自己的Django版本,替换成你的(比如4.2.0)
djangorestframework==3.14.0  # 用DRF写接口就保留,不用就删掉
mysqlclient==2.2.0  # 连接MySQL必须有
gunicorn==21.2.0  # 生产环境运行Django(比runserver稳定)
corsheaders==4.3.0  # 解决前端访问后端的跨域问题

✅ 保存即可(后续 Docker 会自动安装这些依赖)。

(2)编写后端 Dockerfile(backend/Dockerfile)

backend文件夹里新建Dockerfile(无后缀名),粘贴以下内容:

# 基础镜像(Python版本要和你的Django兼容,3.9通用)
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖清单,安装依赖(国内镜像加速)
COPY requirements.txt ./
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 复制所有Django项目文件
COPY . ./
# 暴露8000端口(Django默认端口)
EXPOSE 8000
# 启动Django(用gunicorn,生产环境专用)
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "你的Django项目名.wsgi:application"]

唯一需要修改的地方:把最后一行的「你的 Django 项目名」替换成你 Django 的项目文件夹名(就是有wsgi.py文件的那个文件夹,比如你的 Django 项目创建时叫myproject,就改成myproject.wsgi:application)。

4、编写 “总控配置”(docker-compose.yml)

这是核心文件,放在总文件夹vue_django_docker根目录下,命名为docker-compose.yml(无后缀名),作用是 “统一管理三个集装箱,让它们互相配合”。

粘贴以下内容,只需要修改标注「需要自定义」的地方,其他不用动:

version: '3.8' #可以删除,高版本的Docker已经不用这个了
​
services:
  # 1. 数据库集装箱(MySQL)
  mysql:
    image: mysql:8.0  # 数据库版本,不用改
    container_name: my_mysql  # 集装箱名字,随便起
    restart: always  # 意外崩溃自动重启
    environment:
      # 以下4项需要自定义!!!记好你的配置,后续要用
      MYSQL_ROOT_PASSWORD: 123456  # 数据库root密码(自己设,比如123456)
      MYSQL_DATABASE: my_db  # 自动创建的数据库名(自己设,比如my_db)
      MYSQL_USER: test  # 自定义普通用户(可选,不用改也可以)
      MYSQL_PASSWORD: 123456  # 普通用户密码(和上面密码一致即可)
      TZ: Asia/Shanghai  # 时区,不用改
    volumes:
      # 数据持久化:把数据库数据存到主机,删除集装箱数据不丢
      - ./mysql:/var/lib/mysql
    ports:
      - "3306:3306"  # 主机3306端口映射集装箱3306端口
    networks:
      - app_net  # 加入自定义网络,实现三个集装箱互通
​
  # 2. 后端Django集装箱
  backend:
    build: ./backend  # 用backend文件夹的Dockerfile构建
    container_name: my_django
    restart: always
    depends_on:
      - mysql  # 先启动数据库,再启动后端
    environment:
      # 数据库连接配置,要和上面MySQL的配置对应!!!
      DB_HOST: mysql
      DB_PORT: 3306
      DB_NAME: my_db  # 对应上面的MYSQL_DATABASE
      DB_USER: root  # 用root用户即可
      DB_PASSWORD: 123456  # 对应上面的MYSQL_ROOT_PASSWORD
      TZ: Asia/Shanghai
    ports:
      - "8000:8000"  # 主机8000端口映射集装箱8000端口
    networks:
      - app_net
​
  # 3. 前端Vue集装箱
  frontend:
    build: ./frontend  # 用frontend文件夹的Dockerfile构建
    container_name: my_vue
    restart: always
    depends_on:
      - backend  # 先启动后端,再启动前端
    ports:
      - "80:80"  # 主机80端口映射集装箱80端口(直接用IP访问前端)
    networks:
      - app_net
​
# 自定义网络,让三个集装箱能互相访问
networks:
  app_net:
    driver: bridge

在docker的容器中,端口和外部的端口是完全隔离的,所以需要内外端口进行映射,在映射过程中比如80:80的意思就是把容器内部的80端口映射到我们主机的80端口,如果我们80端口被占用了,就换成其他的比如3000:80就是映射到我们主机的3000端口。

容器端口与主机端口是完全隔离的:Docker 容器拥有独立的网络命名空间,容器内的端口属于容器私有网络环境,和主机的端口互不干扰、完全隔离,主机无法直接访问容器内的端口,必须通过端口映射建立关联。

端口映射的核心用途:通过映射打通主机和容器的网络访问通道,让外部(或主机本身)能通过主机端口访问到容器内对应服务。

关键修改点(必须对应):

MySQL 配置项Django 环境变量配置项说明
MYSQL_DATABASE: my_dbDB_NAME: my_db数据库名必须完全一致
MYSQL_ROOT_PASSWORD: 123456DB_PASSWORD: 123456数据库密码必须完全一致
无需修改DB_HOST: mysql固定写 mysql(集装箱名字)

5、修改项目内部配置(让服务互相认得到)

Django 后端:修改数据库连接(settings.py)

打开backend/你的Django项目名/settings.py(有DATABASES配置的文件),找到数据库配置部分,替换成以下内容(不用改,直接粘贴,会自动读取上面的环境变量):

import os
​
# 原来的DATABASES配置注释掉,替换成这个
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': os.environ.get('DB_HOST', 'localhost'),
        'PORT': os.environ.get('DB_PORT', 3306),
        'NAME': os.environ.get('DB_NAME', 'my_db'),
        'USER': os.environ.get('DB_USER', 'root'),
        'PASSWORD': os.environ.get('DB_PASSWORD', '123456'),
        'OPTIONS': {
            'charset': 'utf8mb4',
        }
    }
}
​
# 解决跨域问题(让前端能访问后端接口)
# 找到INSTALLED_APPS,添加'corsheaders'
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',  # 新增这一行
    '你的app名',  # 你自己的Django app,保留不变
]
​
# 找到MIDDLEWARE,添加'corsheaders.middleware.CorsMiddleware'(放最前面)
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 新增这一行,放最前面
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 其他原有配置保留不变
]
​
# 在settings.py末尾添加以下内容
CORS_ALLOW_ALL_ORIGINS = True  # 允许所有前端访问(开发环境可用,生产环境可改具体域名)
ALLOWED_HOSTS = ['*']  # 允许所有主机访问后端(方便测试)

Vue 前端:修改接口请求地址

打开 Vue 项目中封装 axios 的文件(一般在src/utils/request.js,如果没有就找你发起请求的地方),修改接口基础地址:

import axios from 'axios';
​
// 基础地址:改成你的服务器IP(本地测试就是localhost,远程服务器填服务器IP)
const baseURL = 'http://localhost:8000';  // 关键:对应后端映射的8000端口
​
const service = axios.create({
  baseURL: baseURL,
  timeout: 5000
});
​
export default service;

✅ 比如你前端请求后端接口/api/user,实际会访问http://localhost:8000/api/user,刚好对应后端服务。

6、一键启动所有服务(核心步骤)

进入总文件夹:

打开终端(Windows 用 CMD 或 PowerShell,Mac/Linux 用终端),通过cd命令进入vue_django_docker总文件夹(比如你的总文件夹在桌面,命令如下):

# Windows示例
cd Desktop/vue_django_docker
​
# Mac/Linux示例
cd ~/Desktop/vue_django_docker

构建并启动容器:

在终端输入以下命令(复制粘贴即可,首次运行会下载镜像,可能需要几分钟,耐心等待):

# 构建镜像+启动容器(后台运行,--build表示构建镜像)
docker-compose up -d --build

在下载构建镜像的时候,我的各种环境依赖老是给我报错,原因是因为各种不兼容,比如Django版本太高,Python的版本太低等等,如果一切顺利的话docker-compose up -d --build就可以一次性前后端数据库全部搞定。

所以在构建镜像的时候我的做法是直接单个下载,比如下载python的时候:

# 手动拉取镜像,指定Docker官方仓库,确保镜像完整性
docker pull docker.io/library/python:3.11-slim

我直接先预拉取好正确的镜像然后再docker-compose up -d --build,这样避免了好多的问题:

  • 避免网络波动或仓库访问问题导致的镜像拉取失败;
  • 预拉取的镜像会被 Docker 缓存,后续docker-compose build时会直接复用,无需重新下载,提升构建效率。

查看启动状态:

输入以下命令,查看三个容器是否正常运行(状态显示Up就是成功):

docker-compose ps

如果显示Exited,说明启动失败,输入docker-compose logs -f backend(查看后端日志)或docker-compose logs -f mysql(查看数据库日志)排查问题(一般是配置写错了,回头检查密码、项目名是否对应)。

7、初始化 Django 数据库(让后端连接数据库)

容器启动后,后端还没和数据库同步,需要执行迁移命令(创建数据表):

进入后端容器:

终端输入以下命令(my_django是 docker-compose.yml 中后端容器的名字,要对应):

docker exec -it my_django bash

执行后,终端提示符会变成root@容器ID:/app#,说明已经进入后端容器内部了。

 执行数据库迁移:

在容器内依次输入以下命令(和平时操作 Django 一样):

# 执行迁移(创建数据表)
python manage.py migrate
​
# (可选)创建超级管理员(用于登录Django后台)
python manage.py createsuperuser

执行createsuperuser后,会提示你输入用户名、邮箱、密码(密码输入时不显示,输完回车即可),创建完成后,输入exit退出容器。

8、访问验证(看成果啦!)

打开浏览器,输入以下地址,能正常访问就是部署成功:

  1. 前端访问:http://localhost(或你的服务器 IP)

    (因为前端映射了主机 80 端口,直接输入 IP/localhost即可,不用加端口)

  2. 后端接口访问:http://localhost:8000(或你的服务器 IP:8000)

    (比如访问http://localhost:8000/admin,输入刚才创建的超级管理员账号密码,能进入 Django 后台就是正常)

  3. 数据库访问:用 Navicat、DataGrip 等工具,连接地址localhost,端口3306,用户名root,密码你设置的123456,能连接上并看到my_db数据库就是正常。

9、常用运维命令(小白必备)

不用记太多,记住这几个常用的就行:

停止所有服务

(容器保留,下次可直接启动):

docker-compose down
重新启动所有服务:

docker-compose up -d
重启单个服务

(比如后端改了代码,重启后端):

docker-compose restart backend
查看日志

(排查问题用,比如前端报错):

docker-compose logs -f frontend  # 实时查看前端日志
docker-compose logs -f backend   # 实时查看后端日志
删除容器(谨慎使用,数据会丢失,除非备份了)

docker-compose down --volumes

10、小白避坑指南(重点!)

  1. 端口被占用:如果启动报错 “port is already in use”,说明 80、8000、3306 端口被其他程序占用(比如本地装了 MySQL 占用 3306),修改 docker-compose.yml 中的端口映射即可(比如把3306:3306改成3307:3306,访问数据库时用 3307 端口)。

  2. 配置写错:最常见的是数据库密码、项目名不对应,回头检查 docker-compose.yml 和 Django 的 settings.py。

  3. 镜像下载慢:国内网络可配置 Docker 镜像源(Docker Desktop 在设置里找 “Docker Engine”,添加阿里云镜像加速)。

  4. 数据丢失:MySQL 的数据存在总文件夹的mysql目录下,不要手动删除这个文件夹,否则数据库数据会丢失。

  5. 前端刷新 404:Vue 路由用 history 模式时会出现,解决方案:在 frontend 文件夹里新建nginx.conf,修改 Dockerfile 引用该配置(不懂可以先把 Vue 路由改成 hash 模式,暂时规避)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值