最近在离线环境下上线部署了一个项目,需要搞各种依赖,被离线环境搞得痛不欲生,之前了解过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):
安装步骤:双击安装包,一路 “下一步”(不用改默认配置),安装完成后启动 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等)
操作步骤:
-
新建总文件夹
vue_django_docker; -
把你的 Vue 项目完整复制到
frontend文件夹(确保frontend里有package.json和src); -
把你的 Django 项目完整复制到
backend文件夹(确保backend里有manage.py); -
暂时先空着
docker-compose.yml、frontend/Dockerfile、backend/Dockerfile、backend/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_db | DB_NAME: my_db | 数据库名必须完全一致 |
| MYSQL_ROOT_PASSWORD: 123456 | DB_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、访问验证(看成果啦!)
打开浏览器,输入以下地址,能正常访问就是部署成功:
-
前端访问:http://localhost(或你的服务器 IP)
(因为前端映射了主机 80 端口,直接输入 IP/localhost即可,不用加端口)
-
后端接口访问:http://localhost:8000(或你的服务器 IP:8000)
(比如访问http://localhost:8000/admin,输入刚才创建的超级管理员账号密码,能进入 Django 后台就是正常)
-
数据库访问:用 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、小白避坑指南(重点!)
-
端口被占用:如果启动报错 “port is already in use”,说明 80、8000、3306 端口被其他程序占用(比如本地装了 MySQL 占用 3306),修改 docker-compose.yml 中的端口映射即可(比如把
3306:3306改成3307:3306,访问数据库时用 3307 端口)。 -
配置写错:最常见的是数据库密码、项目名不对应,回头检查 docker-compose.yml 和 Django 的 settings.py。
-
镜像下载慢:国内网络可配置 Docker 镜像源(Docker Desktop 在设置里找 “Docker Engine”,添加阿里云镜像加速)。
-
数据丢失:MySQL 的数据存在总文件夹的
mysql目录下,不要手动删除这个文件夹,否则数据库数据会丢失。 -
前端刷新 404:Vue 路由用 history 模式时会出现,解决方案:在 frontend 文件夹里新建
nginx.conf,修改 Dockerfile 引用该配置(不懂可以先把 Vue 路由改成 hash 模式,暂时规避)。
778

被折叠的 条评论
为什么被折叠?



