2 回答
TA贡献1942条经验 获得超3个赞
一般来说,这两种方法在生产中都应该避免,但是如果我比较卷挂载和每个容器两个进程,我会选择每个容器两个进程,而不是将主机代码挂载到容器,
在某些情况下,第一种方法会失败,例如Fargate的情况,其中没有一种无服务器的主机,那么在这种情况下,您肯定会为每个容器运行两个进程。
每个容器运行多个进程的主要问题是“如果 php-fpm 关闭并且 Nginx 进程正在运行怎么办”。但是您可以使用多种方法处理这种情况,您可以通过 docker 文档查看建议的方法。
docker-multi-service_container
docker 文档使用自定义脚本或 supervisord 覆盖了这个场景。
如果你需要在一个容器中运行多个服务,你可以通过几种不同的方式来完成。
将所有命令放在一个包装脚本中,并附上测试和调试信息。将包装脚本作为您的 CMD 运行。这是一个非常幼稚的例子。首先,包装脚本:
#!/bin/bash
# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_first_process: $status"
exit $status
fi
# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_second_process: $status"
exit $status
fi
# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds
while sleep 60; do
ps aux |grep my_first_process |grep -q -v grep
PROCESS_1_STATUS=$?
ps aux |grep my_second_process |grep -q -v grep
PROCESS_2_STATUS=$?
# If the greps above find anything, they exit with 0 status
# If they are not both 0, then something is wrong
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
exit 1
fi
done
使用像 supervisord 这样的流程管理器。这是一种中等重量的方法,需要您将 supervisord 及其配置打包到您的镜像中(或基于包含 supervisord 的镜像)以及它管理的不同应用程序。然后你启动 supervisord,它会为你管理你的流程。这是一个使用这种方法的 Dockerfile 示例,假设预先编写的 supervisord.conf、my_first_process 和 my_second_process 文件都与 Dockerfile 存在于同一目录中。
但是,如果您正在寻找主管,则可以在其中一个程序被杀死后检查关闭主管以及其他类似的方法来监视该过程。
TA贡献1810条经验 获得超5个赞
您可以创建两个单独的 Docker 映像,一个仅包含您的静态资产,另一个包含可运行的后端代码。静态资产图像可以最小为
# Dockerfile.nginx
FROM nginx:latest
COPY . /usr/share/nginx/html
不要在任何地方绑定安装任何东西。让你的 CI 系统构建两个镜像
TAG=20191214
docker build -t myname/myapp-php:$TAG .
docker build -t myname/myapp-nginx:$TAG -f Dockerfile.nginx .
现在您可以运行两个单独的容器(不违反每个容器一个进程的准则),独立扩展它们(3 个 nginx 但 30 个 PHP),而不必手动复制您的源代码。
另一种有用的技术是将您的静态资产发布到一些外部托管系统;如果您无论如何都在 AWS 中运行,那么 S3 在这里运行良好。您仍然需要某种代理来将请求转发到资产商店或后端服务,但现在可以只是带有自定义配置文件的 Nginx;它不需要您的任何应用程序代码。(在 Kubernetes 中,您可以使用指向带有nginx.conf文件的配置映射的 Nginx 部署来运行它。)
当你设置你的 CI 系统时,你绝对不应该在构建或集成测试时将挂载代码绑定到你的容器中。测试您正在构建的容器中的实际内容,而不是源代码的其他副本。您可以创建两个单独的 Docker 映像,一个仅包含您的静态资产,另一个包含可运行的后端代码。静态资产图像可以最小为
# Dockerfile.nginx
FROM nginx:latest
COPY . /usr/share/nginx/html
不要在任何地方绑定安装任何东西。让你的 CI 系统构建两个镜像
TAG=20191214
docker build -t myname/myapp-php:$TAG .
docker build -t myname/myapp-nginx:$TAG -f Dockerfile.nginx .
现在您可以运行两个单独的容器(不违反每个容器一个进程的准则),独立扩展它们(3 个 nginx 但 30 个 PHP),而不必手动复制您的源代码。
另一种有用的技术是将您的静态资产发布到一些外部托管系统;如果您无论如何都在 AWS 中运行,那么 S3 在这里运行良好。您仍然需要某种代理来将请求转发到资产商店或后端服务,但现在可以只是带有自定义配置文件的 Nginx;它不需要您的任何应用程序代码。(在 Kubernetes 中,您可以使用指向带有nginx.conf文件的配置映射的 Nginx 部署来运行它。)
当你设置你的 CI 系统时,你绝对不应该在构建或集成测试时将挂载代码绑定到你的容器中。测试您正在构建的容器中的实际内容,而不是源代码的其他副本。
- 2 回答
- 0 关注
- 140 浏览
添加回答
举报
