Nodejs项目前后端放入一个docker容器中运行
前言:最近结合bolt AI开发了一个工具管理系统,详情见ToolsManager,用的是nodejs开发的前后端,本来想部署在NAS上,前端部署比较方便,后端部署nas上没有现成的管理界面,导致每次启动和关闭都要用SSH连接并且输入指令,感觉有点麻烦,于是就有了把前后端同时放入一个docker容器内运行的想法,思路如下:
1、环境准备:
docker相关:Windows环境下的docker desktop,docker版本为25.0.3。
使用到的docker镜像:node:18-alpine(轻量化的node环境),nginx:alpine(轻量化的nginx环境)。
docker镜像保存和导入
docker save -o 【文件名】 【镜像id】
导入我用的群晖的Container Manager直接导入的,注意有的镜像导入成功后没显示是因为镜像信息是
,只需要在命令行中用一下代码改名即可 docker images
docker tag 【镜像id】 【镜像名字】
文件目录结构:
└─ToolsManager
├─backend
│ ├─【后端文件】
├─frontend
│ ├─dist
│ │ ├─【前端build文件】
│ ├─【前端其他文件】
├─Dockerfile【docker build文件】
└─nginx.conf【nginx 配置文件】
2、为什么用Nginx代理?
如果直接将前端和后端代码仍进docker里面单独运行,当外部访问前端端口时,如果前端直接用127.0.0.1或者localhost访问就会出现跨域问题,此时的解决办法只能将后端端口也给映射出去,如图所示。
但是实际使用时基本上不会直接操作后端,没必要把后端暴露出来。
既然前端不能通过本地ip直接访问后端,那么加一个中间人转接呢?于是就有了nginx代理的方法,如下图所示:
这样做的好处就是前端通过代理直接访问本地后端,不用将后端端口暴露出去了。
3、相关文件配置
(1)前端
配置url的时候什么都不输入就好了,我就改了下面三处:
/src/config/api.ts
baseUrl: import.meta.env.VITE_API_URL || ''
.env
VITE_API_URL=
.env.example
VITE_API_URL=
(2)后端
只需要设置正确的端口即可。
/src/index.js
const PORT = process.env.PORT || 3000;
.env
PORT=3000
(3)nginx.conf文件
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server {
listen 3030;
server_name 【外部访问的ip或者域名】;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3000/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
(4)Dockerfile文件
docker构建指令
cd 【Dockerfile所在目录】
docker build -t my-app .
Dockerfile
# 使用 node:18-alpine 作为基础镜像
FROM node:18-alpine AS nodejs
# 设置工作目录
WORKDIR /app
# 复制后端文件到容器中
COPY backend/ .
# 安装依赖并构建(如果需要)
RUN npm install
# 如果需要构建,取消下面的注释
# RUN npm run build
# 使用 nginx:alpine 作为基础镜像
FROM nginx:alpine
# 从 nodejs 阶段复制后端文件
COPY --from=nodejs /app /app
# 复制前端文件到 Nginx 的默认服务目录
COPY frontend/dist/ /usr/share/nginx/html/
# 复制自定义的 Nginx 配置文件(如果需要)
COPY nginx.conf /etc/nginx/nginx.conf
# 安装 Node.js 运行时
RUN apk add --no-cache nodejs
# 暴露前端端口
# EXPOSE 3000
EXPOSE 3030
# 启动 Nginx 和 Node.js 应用
CMD nginx && node /app/src/index.js
4、成功示例
Comments