Minimal configuration for Apache reverse proxy in Docker container

Xophmeister picture Xophmeister · Oct 20, 2014 · Viewed 11.2k times · Source

I am trying to setup a Ubuntu Docker container which runs a Node.js HTTP app on port 9000. To mimic the setup of the production environment, I would also like to run Apache as a simple reverse proxy server within the container that forwards to this app from, say, port 80 (which I expose to the big bad world).

I've been able to set up the Node.js app container fine and I can install and setup Apache within my Dockerfile; but I'm completely new to setting up a reverse proxy, so while Apache certainly starts, it doesn't proxy.

My Dockerfile looks something like:

# 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"]

...where the apache2.conf I'm appending to /etc/apache2/apache2.conf is:

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/

I am running this image using the following command:

docker run -p 80:80 -p 81:9000 -d IMAGE

What I'm expecting is that going to http://$DOCKER_HOST (i.e., the root) will be picked up by Apache and forwarded to localhost:9000 (i.e., my app) in the container. (If I go to http://$DOCKER_HOST:81, I go straight to the app; just to prove that it's up and running. This works.) I suspect that the problem isn't at all to do with Docker, but the Apache configuration.

Answer

Thomasleveil picture Thomasleveil · Oct 21, 2014

In your Dockerfile, the RUN statements define commands that will be run by the docker daemon when building the docker image. Those commands won't be executed when you use the docker run command.

In your case you are trying to come up with a docker image that would start two processes:

  • apache server
  • nodejs server

But the start-app.sh script in CMD ["./start-app.sh"] seems to only start the nodejs server.

You cannot have the docker run command start more that one process, but you can have it start a process that will start others. There are differents ways to achieve this, take a look at:

but more simply you could replace your CMD instruction with:

CMD     /bin/bash -c "service apache2 start; ./start-app.sh"

and remove the useless RUN service apache2 start line.

In your container, Docker will start one process (/bin/bash) which in turn will start apache and then run ./start-app.sh.