Docker容器中Apache反向代理的最小配置

6
我正在尝试设置一个Ubuntu Docker容器,该容器在9000端口上运行一个Node.js HTTP应用程序。为了模仿生产环境的设置,我还想在容器内运行Apache作为简单的反向代理服务器,从80端口(我向大家公开)转发到该应用程序。
我已经成功设置了Node.js应用程序容器,并且可以在我的Dockerfile中安装和设置Apache;但是我完全不知道如何设置反向代理,因此虽然Apache确实启动了,但它没有进行代理。
我的Dockerfile大致如下:
# DOCKER-VERSION 1.3.0
FROM    ubuntu:12.04

# Install and set up Apache as a reverse proxy
RUN     apt-get -y install apache2 libapache2-mod-proxy-html
COPY    apache2.conf /etc/apache2/app.conf
RUN     cat /etc/apache2/app.conf >> /etc/apache2/apache2.conf
RUN     service apache2 start

# Install and set up Node.js and bundle app
# ...This works...

EXPOSE  80
CMD     ["./start-app.sh"]

我正在附加到/etc/apache2/apache2.confapache2.conf是:

ServerName localhost

LoadModule proxy_module      /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
LoadModule headers_module    /usr/lib/apache2/modules/mod_headers.so
LoadModule deflate_module    /usr/lib/apache2/modules/mod_deflate.so

<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>

ProxyPass        / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/

我正在使用以下命令运行此镜像:
docker run -p 80:80 -p 81:9000 -d IMAGE

我期望的是访问 http://$DOCKER_HOST (即根目录)能够被 Apache 捕获,并转发到容器内的 localhost:9000(即我的应用程序)。如果我访问 http://$DOCKER_HOST:81,我会直接进入应用程序,以证明它已经启动。这个方法可行。 我猜问题与 Docker 无关,而是 Apache 配置的原因。请注意,文本中保留了 HTML 标签,请勿删除。

你是否仅仅使用Apache反向代理来将Web服务器暴露在80端口而不是9000端口,或者它还有其他用途? - Thomasleveil
没错。在生产环境中,Apache正在执行其他无关的任务;我只是将反向代理层放在我的容器中,以便它与生产环境中的设置相匹配。 - Xophmeister
请编辑您的问题,加上您正在使用的命令来运行Docker容器。 - Thomasleveil
@Thomasleveil 编辑 - Xophmeister
1个回答

7
在你的Dockerfile中,RUN语句定义了在构建docker镜像时docker守护进程将要运行的命令。当使用docker run命令时这些命令不会被执行。
在你的情况下,你正在尝试创建一个Docker镜像,该镜像将启动两个进程:
  • Apache服务器
  • Node.js服务器
但是,在CMD ["./start-app.sh"]中的start-app.sh脚本似乎只启动了nodejs服务器。
你不能让docker run命令启动多个进程,但你可以让它启动一个将启动其他进程的进程。有不同的方法来实现这一点,请参阅以下链接: 但更简单的方法是将你的CMD指令替换为:
CMD     /bin/bash -c "service apache2 start; ./start-app.sh"

同时删除无用的 RUN service apache2 start 行。

在您的容器中,Docker 将启动一个进程 (/bin/bash),该进程将启动 apache 并运行 ./start-app.sh


请在 start-app.sh 脚本的顶部添加 service apache2 start - Thomasleveil
做到了 :) 谢谢...特别是你的第一段话为我解决了所有问题。 - Xophmeister
这是否需要我使用root运行容器才能执行“service apache2 start”命令?有没有一种方法可以使用普通用户完成此任务? - fy_iceworld
@fy_iceworld 我建议您运行两个容器,一个用于Apache(来自官方Docker镜像),另一个用于您的应用程序。这样做可以避免以root身份运行容器的问题。或者使用Traefik代替Apache作为反向代理角色。 - Thomasleveil
@Thomasleveil 我明白了,感谢您的快速回复! - fy_iceworld

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接