如何用Dockerfile部署Sveltekit应用?解决vite未找到报错
解决Docker部署SvelteKit时vite未找到的问题
问题重现
执行Docker运行命令:
docker run --publish 8000:8000 my_project
出现报错:
my-project@0.0.1 build
vite buildsh: vite: not found
问题原因分析
- NODE_ENV=production导致devDependencies未安装:Dockerfile设置了
ENV NODE_ENV=production,此时npm install默认会跳过devDependencies,而vite正好在devDependencies中。即便单独执行RUN npm install vite,如果后续COPY . .覆盖了容器内的node_modules(比如本地未装vite或.dockerignore未排除node_modules),也会导致vite丢失。 - 构建流程不合理:容器启动时才执行
npm run build,而非提前完成构建,既浪费资源也容易引发依赖问题。
解决方案
方案1:调整npm安装命令,包含devDependencies
修改Dockerfile中的RUN npm install命令,强制安装所有依赖(包括devDependencies):
# syntax=docker/dockerfile:1 FROM node:19.4.0-alpine3.16 ENV NODE_ENV=production WORKDIR /app COPY ["package.json", "package-lock.json*", "./"] # 强制安装所有依赖,包括devDependencies RUN npm install --include=dev # 无需单独安装dotenv、@directus/sdk、vite,package.json已声明 COPY . . # 构建后启动应用(根据你的SvelteKit适配器调整启动命令,示例用adapter-node) RUN npm run build CMD ["node", "build/index.js"]
同时,必须添加.dockerignore文件,避免本地文件覆盖容器内依赖:
node_modules .env .DS_Store
方案2:将vite移至dependencies
修改package.json,把vite从devDependencies移到dependencies中:
"dependencies": { "@directus/sdk": "^10.3.1", "dotenv": "^16.0.3", "vite": "^4.0.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", "vitest": "^0.25.3" }
之后Dockerfile中的RUN npm install会自动安装vite,无需额外命令。
方案3:多阶段构建(推荐)
多阶段构建分离构建环境与生产环境,镜像体积更小、更安全:
# 第一阶段:构建应用 FROM node:19.4.0-alpine3.16 AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm install # 默认安装所有依赖(包括devDependencies) COPY . . RUN npm run build # 第二阶段:生产环境运行 FROM node:19.4.0-alpine3.16 ENV NODE_ENV=production WORKDIR /app # 仅复制构建产物和运行所需依赖 COPY --from=builder /app/package.json ./ COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/build ./build # 根据SvelteKit适配器调整启动命令,示例为adapter-node CMD ["node", "build/index.js"]
同样需要添加.dockerignore文件排除本地node_modules。
关键注意点
- 确认SvelteKit适配器配置正确:如果使用
adapter-auto,Railway会自动适配;如果自定义适配器,需确保启动命令对应正确。 - 避免本地
node_modules污染容器:.dockerignore是必须的,否则本地依赖会覆盖容器内安装的版本。
内容的提问来源于stack exchange,提问作者HONjramiroz98
相关产品推荐
相关产品推荐

