后端项目示例
- file-server(后端文件服务)
- 技术栈:Node.js 18 + Express.js 4 + TypeScript + MongoDB + Multer
- node-project(后端Node.js服务)
- 技术栈:Node.js 18 + Express.js 4 + TypeScript + MySQL + Redis + Sequelize + jsonwebtoken
1. 本地电脑环境准备
-
根据电脑类型下载安装对应的 docker
-
各个项目配置好打包命令
例如file-server项目package.json文件的scripts内容如下:"scripts": { "dev": "nodemon src/app.ts --exec ts-node", "build": "tsc && ts-node copyStatic.ts", "start": "node dist/app.js" }, -
提前选择配置好各个项目
Docker容器之间的访问方式
比如file-server怎么访问MongoDB的容器:- 使用
ip和端口访问,访问的url如下:mongodbUrl: 'mongodb://用户名:密码@ip地址:27017' - 使用
Docker创建自定义网络(docker network create),访问的url如下:mongodbUrl: 'mongodb://用户名:密码@mongodb:27017' // mongodb为运行的容器名称
- 使用
-
配置好各个项目的
Dockerfile文件
例如file-server的Dockerfile文件内容如下:FROM node:18.18.0 AS builder WORKDIR /app COPY package*.json ./ RUN yarn COPY . . RUN npm run build # 生成 /app/dist FROM node:18.18.0 WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/package*.json ./ RUN yarn --production EXPOSE 8001 CMD ["node", "dist/app.js"]
2. 腾讯云服务器环境准备
首先,你得拿点💰买个云服务器,我是蹲的双十一便宜买的腾讯云轻量云应用服务器,以下流程都按照腾讯云轻量云应用服务器的页面和操作方式编写:
-
服务器买好以后先在服务器上安装
Docker,我是在服务器装系统的时候就选了一个Docker应用模板的系统。 -
在腾讯云控制台上方搜索容器镜像服务,开通腾讯云镜像仓库个人版,然后按照要部署的项目名称新建仓库
3. 本地使用Docker构建镜像并推送到腾讯云服务器镜像仓库
- 在所有要放到服务器的项目目录下执行
docker build命令构建镜像(不包含数据库)
例如在file-server项目下面执行:docker build \ --platform linux/amd64 \ # 打包 linux/amd64(操作系统/架构)的镜像 -t ccr.ccs.tencentyun.com/my-namespace/file-server:[tag] . \ # my-namespace 云服务器容器镜像服务命名空间名称;# [tag] 是变量,你定义的版本号; # 不要忘记命令最后有一个 .(点),是为了指明 Dockerfile 文件的位置 - 登录腾讯云容器镜像服务
直接在镜像仓库里面可以看到每个仓库的操作列里面有个【快捷指令】,点开复制登录命令即可docker login ccr.ccs.tencentyun.com --username=你的用户名 # 然后输入密码 - 将所有镜像推送到腾讯云服务器镜像仓库中
例如file-server项目下面执行:# 镜像仓库 操作列 快捷指令可看到推送命令,可直接复制 docker push ccr.ccs.tencentyun.com/my-namespace/file-server:[tag] # [tag] 是变量,你定义的版本号
4. 在腾讯云服务器拉取file-server镜像并运行
-
拉取
file-server镜像# 镜像仓库 操作列 快捷指令可看到拉取命令,可直接复制 docker pull ccr.ccs.tencentyun.com/my-namespace/file-server:[tag] # [tag] 是变量,你定义的版本号 -
运行
file-server镜像- 通过
ip和端口访问MongoDB容器,直接运行并做好端口映射即可注意:docker run \ --name file-server \ --env-file /secrets/test.env \ # 加载当前部署环境的环境变量文件内容 -p 8000:8000 \ # 将云服务器的端口与容器内部端口绑定,实现外部访问 ccr.ccs.tencentyun.com/my-namespace/file-server:[tag] # [tag] 是变量,你定义的版本号-p 8000:8000实现外部访问时,要注意打开云服务器防火墙的端口访问限制,允许外部访问。 - 通过
Docker创建自定义网络访问MongoDB容器- 先创建自定义网络
docker network create file-net - 然后运行容器并加入网络
docker run \ --name file-server \ --network file-net \ # 加入自定义网络 -p 8000:8000 \ -e NODE_ENV=test \ ccr.ccs.tencentyun.com/my-namespace/file-server:[tag]
- 先创建自定义网络
- 通过
5. 在腾讯云服务器拉取node-project镜像并运行
- 拉取
node-project镜像# 镜像仓库 操作列 快捷指令可看到拉取命令,可直接复制 docker pull ccr.ccs.tencentyun.com/my-namespace/node-project:[tag] # [tag] 是变量,你定义的版本号 - 运行
node-project镜像- 通过
ip和端口访问MySQL和Redis容器,直接运行并做好端口映射即可注意:docker run \ --name node-project \ --env-file /secrets/test.env \ # 加载当前部署环境的环境变量文件内容 -p 8088:8088 \ # 将云服务器的端口与容器内部端口绑定,实现外部访问 ccr.ccs.tencentyun.com/my-namespace/node-project:[tag] # [tag] 是变量,你定义的版本号-p 8001:8001实现外部访问时,要注意打开云服务器防火墙的端口访问限制,允许外部访问。 - 通过前面用
Docker创建的自定义网络file-net访问MySQL和Redis容器docker run \ --name node-project \ --network file-net \ # 加入自定义网络 -p 8088:8088 \ -e NODE_ENV=test \ ccr.ccs.tencentyun.com/my-namespace/node-project:[tag]
- 通过
6. 在腾讯云服务器拉取MongoDB镜像并运行
- 拉取
MongoDB镜像docker pull mongo:latest # 拉取最新版 docker pull mongo:5.0 # 或指定版本(如 5.0) - 运行
MongoDB镜像注意:# 创建数据持久目录并授权 sudo mkdir -p /data/mongo/db && sudo chmod 755 /data/mongo/db # 运行镜像 docker run \ --name mongodb \ # 设置运行的容器名称为 mongodb --network file-net \ # 加入前面创建的自定义网络,实现同一个网络下的容器可直接通过容器名称访问 -p 27017:27017 \ # 将云服务器的端口与容器内部端口绑定,实现外部访问 -v /data/mongo/db:/data/db \ # 数据持久化,不持久化容器停止或删除后,内部文件系统会被清除 -e MONGO_INITDB_ROOT_USERNAME=用户名 \ # 设置用户名 -e MONGO_INITDB_ROOT_PASSWORD=密码 \ # 设置密码 mongo # 选择要运行的镜像名称-p 27017:27017实现外部访问时,要注意打开云服务器防火墙的端口访问限制,允许外部访问。
7. 在腾讯云服务器拉取MySQL镜像并运行
-
拉取
MySQL镜像docker pull mysql:8.0 -
创建数据持久目录并授权
sudo mkdir -p /data/mysql/{data,conf.d} && sudo chmod 755 /data/mysql/{data,conf.d} -
创建配置文件
my.cnftouch /data/mysql/conf.d/my.cnf # 创建配置文件 -
编辑配置文件
my.cnf,输入以下内容[client] default-character-set = utf8mb4 # 客户端连接默认字符集 [mysql] default-character-set = utf8mb4 # MySQL 命令行工具字符集 [mysqld] character-set-server = utf8mb4 # 服务端默认字符集 collation-server = utf8mb4_unicode_ci # 服务端校对规则 init_connect = 'SET NAMES utf8mb4' # 每个新连接自动执行SET NAMES skip-character-set-client-handshake = ON # 强制客户端使用服务端字符集 -
运行
MySQL镜像# 运行镜像 docker run \ --name mysql \ --network file-net \ # 加入前面创建的自定义网络,实现同一个网络下的容器可直接通过容器名称访问 -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=密码 \ -v /data/mysql/data:/var/lib/mysql \ # 挂载数据目录(数据持久化) -v /data/mysql/conf.d:/etc/mysql/conf.d \ # 挂载配置目录 mysql:8.0 -
安全加固(关键步骤)
进入容器修改密码策略,兼容旧版客户端:# 进入容器终端 docker exec -it mysql bash # 登录MySQL mysql -u root -p # 修改密码加密方式(解决低版本客户端连接问题) ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的新密码'; FLUSH PRIVILEGES; -
从本地
MySQL导出SQL文件,使用MySQL Workbench导出完整数据库
导出步骤:- 在Workbench中选择
Server→Data Export - 勾选目标数据库,选择
Dump Structure and Data(导出结构和数据) - 勾选
Export to Self-Contained File(生成单一SQL文件) - 指定文件路径(如
dump.sql)并点击Start Export
- 在Workbench中选择
-
将
SQL文件上传到服务器MySQL容器中,然后导入# 先将文件上传到服务器 /home/ubuntu 文件夹下 # 然后执行下面的命令复制到 mysql容器内 docker cp /home/ubuntu/you.sql mysql:/tmp/you.sql # 进入容器终端 docker exec -it mysql bash # 登录MySQL mysql -u root -p # 创建数据库 CREATE DATABASE db_name; # 检查是否创建成功,表格中显示有 db_name 则表示成功 SHOW DATABASES; # 使用创建的数据库 USE db_name; # 导入SQL文件到数据库中 SOURCE /tmp/you.sql; # 检查表结构 SHOW TABLES; # 随机抽取表数据检查 SELECT * FROM 表名 LIMIT 10;
8. 在腾讯云服务器拉取Redis镜像并运行
- 拉取
Redis镜像docker pull redis:latest # 拉取最新版 docker pull redis:5.0.5 # 或指定版本 - 创建创建数据持久目录并授权
# 创建数据持久目录并授权 sudo mkdir -p /data/redis/{data,conf} && sudo chmod 755 /data/redis/{data,conf} - 创建配置文件
redis.conftouch /data/redis/conf/redis.conf # 创建配置文件 - 编辑配置文件
redis.conf,输入以下内容# 允许远程连接 bind 0.0.0.0 # 关闭保护模式 protected-mode no # 设置密码 requirepass 密码 # 限制内存 maxmemory 2gb # 优先淘汰长期未使用的数据 maxmemory-policy allkeys-lru - 运行
Redis镜像# 运行镜像 docker run \ --name redis \ --network file-net \ # 加入前面创建的自定义网络,实现同一个网络下的容器可直接通过容器名称访问 -p 6379:6379 \ -v /data/redis/data:/data \ -v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \ redis \ redis-server /usr/local/etc/redis/redis.conf \ --requirepass 123456Aa \ # 设置访问密码,强制客户端连接时进行身份验证 --appendonly yes # 启用AOF持久化 - 检查
redis容器是否正常# 确认容器状态,为 UP 为正常 docker ps | grep redis # 使用 redis-cli 测试连接与密码 docker exec -it redis redis-cli AUTH 你的密码 # 返回 OK 表示密码正确 SET testkey "hello" # 测试写入 GET testkey # 应返回 "hello"
9. 根据不同后端服务的请求前缀配置Nignx转发
不配置Nignx访问不同的后端服务需要加上端口号,配置后直接访问域名或ip就行,Nignx根据不同的前缀进行转发。
- 云服务器安装
Nginxsudo apt update && sudo apt install nginx -y # 更新并安装Nginx sudo systemctl start nginx && sudo systemctl enable nginx # 启动并设置开机自启 - 修改
Nginx配置文件修改文件内容为:sudo vim /etc/nginx/sites-available/default # Ubuntu/Debianserver { listen 80; server_name _; # 无需域名,匹配所有请求 # 处理大文件上传(需≥Multer配置) client_max_body_size 500M; location /file-server/ { # 项目接口地址的统一路由前缀,每个项目的前缀应该设置为不同 proxy_pass http://localhost:8000; # 指向Docker映射端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /node-project/ { proxy_pass http://localhost:8088; # 指向Docker映射端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } - 保存文件后重启
Nginx服务sudo nginx -t # 检查配置文件语法是否正确 sudo systemctl reload nginx # 应用新配置