Docker容器执行docker run后自动停止的解决方案咨询
问题
构建的Docker镜像执行docker run后容器自动停止,需在单个Docker容器中同时运行客户端与服务端。已知docker-compose方案可正常运行,现咨询仅通过docker run命令保持容器持续运行的方法。
相关文件与命令
Dockerfile
FROM node:14.14.0-alpine RUN apk update && apk add bash SHELL ["/bin/bash", "-o", "pipefail", "-c"] WORKDIR /app EXPOSE 3000 EXPOSE 4565 CMD ["npm","run","prebuild"]
镜像构建命令
docker build -t sample .
当前运行命令
docker run -d -it --name sm -v `pwd`:/app sample
package.json 脚本(根据截图整理)
prebuild:rimraf dist(清理构建目录)build:nest build(服务端构建)start:nest start(启动服务端)start:dev:nest start --watch(开发模式启动服务端)start:prod:node dist/main(生产模式启动服务端)client:cd client && npm start(启动客户端)client:build:cd client && npm run build(客户端构建)
解决思路与方案
容器停止的核心原因是当前CMD指定的npm run prebuild是一次性任务,执行完毕后进程退出,容器随之终止。要维持容器运行,必须启动一个长期存活的前台进程,同时完成客户端与服务端的启动。
方案1:使用启动脚本(推荐)
- 在项目根目录创建
start.sh启动脚本:
#!/bin/bash # 执行预构建步骤 npm run prebuild # 后台启动服务端 npm run start:dev & # 前台启动客户端(维持容器存活) npm run client
- 给脚本添加执行权限:
chmod +x start.sh
- 修改Dockerfile,将脚本复制到容器并设置为启动命令:
FROM node:14.14.0-alpine RUN apk update && apk add bash SHELL ["/bin/bash", "-o", "pipefail", "-c"] WORKDIR /app # 复制启动脚本 COPY start.sh . RUN chmod +x start.sh EXPOSE 3000 EXPOSE 4565 # 设置脚本为启动命令 CMD ["./start.sh"]
- 重新构建镜像并运行:
docker build -t sample . docker run -d -it --name sm -v `pwd`:/app sample
方案2:直接在docker run命令中指定复合命令
无需修改Dockerfile,直接在运行时覆盖CMD,用bash执行复合命令:
docker run -d -it --name sm -v `pwd`:/app sample /bin/bash -c "npm run prebuild && npm run start:dev & npm run client"
注意事项
- 若使用生产环境,将
start:dev替换为start:prod;客户端若需生产模式启动,需确保已完成构建(可加入npm run client:build)并使用对应命令(如serve -s client/build,需提前在容器中安装serve) - 必须保证至少有一个进程在前台运行,否则容器会停止;上述方案中客户端在前台运行,服务端后台运行,满足要求
内容的提问来源于stack exchange,提问作者Shreyas Murali
相关产品推荐
相关产品推荐

