Docker中Vue项目无法被宿主机访问的问题排查求助
Vue项目Docker容器无法被宿主机访问的排查与解决
问题背景
使用GitLab CI/CD部署Vue项目,后端FastAPI容器运行正常,但Vue容器部署后宿主机无法访问,浏览器报404。目标是让Vue容器通过宿主机IP正常访问,相关配置如下:
GitLab CI配置
Vue_container_deploy1: stage: deploy script: - x=$(docker ps -f "publish=49300" | awk '{print $1}'| sed -n '2p') - docker stop $x && docker rm $x - docker run -d -p 49300:5173 --network bridge --name myvue-w1-$CI_PIPELINE_ID vue:$CI_PIPELINE_ID - docker ps
Vue Dockerfile
FROM node:16.18.1 WORKDIR /usr/src/app ARG NODE_ENV ENV NODE_ENV $NODE_ENV COPY package.json /usr/src/app/ RUN npm install -g npm RUN npm install COPY . /usr/src/app/ # replace this with your application's default port CMD ["npm", "run", "build"] CMD ["npm", "run" ,"serve","-s","dist","--","--host","0.0.0.0"]
API.js
import axios from 'axios'; const apis = { production: 'http://192.168.0.150:49200/blog', // Online (generating environment) development: 'http://127.0.0.1:8000/blog/', // local (development environment) test: 'http://192.168.0.150:49200/blog' // (test environment) }; const baseURL = process.env.NODE_ENV === 'production' ? apis.production : apis.development; const ajax = axios.create({ baseURL: baseURL }); export default ajax;
package.json
{ "name": "vue-project", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "test:unit": "vitest", "serve": "vite", "test": "vue-cli-service build --mode test && npm run serve -s dist", "publish": "vue-cli-service build && vue-cli-service build --mode test" }, }
容器启动提示
VITE v4.4.4 ready in 337 ms ➜ Local: http://localhost:5173/ ➜ Network: http://172.17.0.4:5173/ (!) Could not auto-determine entry point from rollupOptions or html files and there are no explicit optimizeDeps.include patterns. Skipping dependency pre-bundling.
错误原因分析
- Dockerfile CMD指令冲突:Dockerfile中定义了两个
CMD,只有最后一个会执行,导致npm run build未运行,dist目录未生成。启动命令中-s dist找不到静态文件目录,直接返回404。 - Vite命令参数错误:
npm run serve对应vite命令,-s dist是静态文件服务(如vite preview)的参数,Vite开发服务器不支持该参数,导致无法识别入口文件,出现"无法自动确定入口点"警告,服务未正确加载资源。 - NODE_ENV未正确传递:构建镜像时未传入
NODE_ENV参数,容器内默认使用development环境,虽不直接影响访问,但会导致API地址选择不符合预期。
解决方案
1. 修复Dockerfile的CMD逻辑
Dockerfile仅支持一个CMD,需合并构建与启动命令,或用RUN预先生成dist目录:
FROM node:16.18.1 WORKDIR /usr/src/app ARG NODE_ENV=production ENV NODE_ENV $NODE_ENV COPY package.json /usr/src/app/ RUN npm install -g npm && npm install COPY . /usr/src/app/ # 预构建dist目录,再用vite preview启动静态服务 RUN npm run build CMD ["npm", "run", "preview", "--", "--host", "0.0.0.0", "--port", "5173"]
若需保留开发模式启动(不推荐生产环境使用),可合并命令:
CMD ["sh", "-c", "npm run build && npm run serve -- --host 0.0.0.0"]
2. 修正package.json的脚本参数
调整serve和preview命令,适配Vite参数规则:
{ "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview --host 0.0.0.0", "test:unit": "vitest", "serve": "vite --host 0.0.0.0", "test": "vue-cli-service build --mode test && npm run preview", "publish": "vue-cli-service build && vue-cli-service build --mode test" } }
3. 完善GitLab CI的镜像构建流程
在CI中补充镜像构建步骤,并传递NODE_ENV参数:
Vue_image_build: stage: build script: - docker build --build-arg NODE_ENV=production -t vue:$CI_PIPELINE_ID . only: - main # 根据实际分支调整 Vue_container_deploy1: stage: deploy needs: [Vue_image_build] script: - x=$(docker ps -f "publish=49300" | awk '{print $1}'| sed -n '2p') - if [ ! -z "$x" ]; then docker stop $x && docker rm $x; fi # 避免容器不存在时报错 - docker run -d -p 49300:5173 --network bridge --name myvue-w1-$CI_PIPELINE_ID vue:$CI_PIPELINE_ID - docker ps
4. 验证容器服务状态
部署后可进入容器检查关键状态:
# 进入容器 docker exec -it myvue-w1-<pipeline-id> sh # 检查dist目录是否存在 ls -la /usr/src/app/dist # 检查服务监听端口 netstat -tulpn | grep 5173
内容的提问来源于stack exchange,提问作者Exploit
相关产品推荐
相关产品推荐

