我需要调试一个在 docker 内部崩溃的应用程序,如何实现当应用程序崩溃时 docker 不会停止,从而允许我进入-it
并尝试手动启动该应用程序?
答案1
你可以,我需要将单个包添加到现有的docker中以使我的Python应用程序运行,并且不想等待构建时间。
docker run container_name tail -f /dev/null
然后通过
docker exec -it container_name /bin/sh
参考:https://levelup.gitconnected.com/keep-docker-container-running-for-debugging-fc2dfa39472c
答案2
所以最后我做了以下事情:
首先,要知道有可能暂停容器在运行任何命令之前,例如npm start
,等等。然后我们可以使用终端进入docker容器并手动运行任何命令。像这样运行应用程序不会在出现严重错误时退出并关闭容器。我们甚至可以在 docker 中挂载本地文件系统然后从那里运行应用程序,docker 实时获取更改 -非常适合调试!
项目布局
在我的例子中,它是一个 NestJS 应用程序,其中包含两个重要文件夹
/src
- 应用程序源代码(开发,nest start --watch
)/dist
- 构建应用程序的输出文件夹(生产)
(npm run build
(nest build
),npm run start:prod
(node dist/src/main
))
然后配置 docker 以将构建的/dist
文件夹和相关文件复制到用作启动应用程序/app
的文件夹。WORKDIR
摘录自Dockerfile
(简化了很多)
WORKDIR /app
RUN npm run build
COPY /app/tsconfig.json ./tsconfig.json
COPY /app/package.json ./package.json
COPY /app/dist ./dist
CMD ["npm", "run", "start:prod"]
清楚了这一点,我们现在来看看package.json
"scripts"
"scripts": {
"dev": "npm run start:dev",
"dev:docker": "npm run docker:debug:start:local",
"build": "nest build",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/src/main",
"docker:build": "docker build -t my-nest-service --platform linux/amd64 .",
"docker:start": "docker run --env-file ./.env --rm --name my-nest-service -p 9002:9002 my-nest-service",
"docker:stop": "docker stop my-nest-service",
"docker:debug:start": "docker run --env-file ./.env --rm --name my-nest-service -p 9002:9002 my-nest-service sleep infinity",
"docker:debug:start:local": "docker run -v %cd%:/app --env-file ./.env --rm --name my-nest-service -p 9002:9002 my-nest-service sleep infinity",
"docker:debug:enter": "docker exec -it my-nest-service sh"
}
解释
因此,上面发生的事情是,我们有命令来构建应用程序build
、启动开发或生产start:dev
start:prod
、启动和停止 docker docker:start
docker:stop
、启动 docker 暂停docker:debug:start
、使用终端进入 dockerdocker:debug:enter
等等。
然后是一个特殊命令dev:docker
或docker:debug:start:local
,它允许我们将本地存储库挂载在 Docker 的/app
文件夹中,该文件夹(如上所述)是WORKDIR
我们的应用程序代码被复制到的文件夹。
dev:docker # alias for docker:debug:start:local
docker:build
docker:start # Starts the image and app from container's `dist` folder
docker:stop
docker:debug:start # Starts image without running the app
docker:debug:start:local # Same as above but mounts local filesystem
docker:debug:enter # Allows us to connect terminal inside running container
Docker 内部调试
dev:docker
- 启动处于暂停状态的 docker 容器(pause infinity
)并挂载本地仓库docker:debug:enter
- 这使我们能够通过终端进入容器内部npm run dev
然后我们可以从 docker 内部手动运行该应用程序- 使用调试工具,通过 VSCode 进行远程连接等等。
以下是我们的实际摘录README.md
:
Docker 内部开发
对...有用调试docker 也适用于平台无关的发展在部署环境中,镜像本身设置为运行npm run start:prod
(参见Dockerfile CMD
). 所有以docker:
in为前缀的命令包文件.json从未使用过,只是为了方便在本地环境中控制 docker。
dev:docker # alias for docker:debug:start:local
docker:build
docker:start # Starts the image and app from container's `dist` folder
docker:stop
docker:debug:start # Starts image without running the app
docker:debug:start:local # Same as above but mounts local filesystem
docker:debug:enter # Allows us to connect terminal inside running container
PS:在 docker 内部进行本地开发请使用 trio dev:docker
, docker:debug:enter
, npm run dev
。阅读下文。
构建映像
npm run docker:build
使用以下命令启动容器
sleep
sleep
在运行应用程序之前暂停容器,这使得我们即使在发生终止错误的情况下也可以检查它。
有两个选项:a) 运行完整包建造 在容器内.这将运行文件夹中的代码
dist
(参见DockerfileCMD
命令)。npm run docker:debug:start npm run start:prod # then inside docker (see step 3a)
b) 或者运行挂载本地仓库。这将用您本地 repo 的内容完全覆盖容器的
/app
目录,对 repo 的每个更改都将反映在 docker 内部。
*注意%var%
是 Windows 语法,$var
在 Unix 上使用。npm run docker:debug:start:local npm run dev # then inside docker (see step 3b)
连接到容器
从第二个终端启动此命令。docker:debug:enter
然后,在容器内部,您可以
a) 从 启动构建的生产代码dist
。这是 docker 在 Dockerfile 中使用的相同命令CMD
。npm run start:prod
b) 从 开始
src
。(使用 时docker:debug:start:local
。)npm run dev
此时,您可以运行任何命令,因为您已经链接了完整的本地存储库。
在浏览器中打开应用程序 http://localhost:9002/api/v1/ 并执行您的操作。
停止容器
docker:stop
提示:您可以检查正在运行的容器。
docker ps
以正常方式启动应用程序以验证一切是否正常,并在浏览器中通过 http://localhost:9002/api/v1/ 进行测试。
PS:您可能需要重建您的图像1)。# run prod in docker npm run docker:start # runs prod without docker npm run start:prod