Almost all of my docker containers are web applications that run on port 80. To allow them to all run on a single host, I allow docker to assign a random unused port, and use the jwilder/nginx-proxy
(reference) as a reverse proxy. This requires the jwilder/nginx-proxy to be running before the container has started, which is easy enough in the bash script I run to start the container after it has been built:
...
#######################
# ensure that we are running the frontend proxy
# which allows us to run multiple web containers
RESULT=`docker ps | grep jwilder | wc -l`
if [ $RESULT -gt 0 ];then
echo "found frontend proxy."
else
echo "Deploying frontend proxy"
docker run -d \
-p 80:80 \
-v /var/run/docker.sock:/tmp/docker.sock \
-t jwilder/nginx-proxy
fi
#######################
# Now start the container.
docker run -d \
-e VIRTUAL_HOST=$VIRTUAL_HOST \
-p 80 \
-p 443 \
--name="$PROJECT_NAME" \
$CONTAINER_IMAGE
Often I need to reboot my servers and I need a solution that will start all my containers automatically and in the right order.
I can use the docker run paramater --restart=always
to have all of my running containers start up automatically after a reboot, however, how can I ensure that my reverse proxy container starts first before anything else, and there is a short delay before any of the other containers are started (in any order).
Ideally, I would like a solution that would not be distro specific, such as using supervisord rather than writing an upstart or systemd startup script, but I need a way to hook into triggering after the docker daemon has finished starting successfully.
If you expose port 80 on all your containers with webapplications you could link to them to your Nginx container.
Here is a small sample docker-compose.yml
:
app:
build: app/
expose:
- "80"
api:
build: api/
expose:
- "80"
webserver:
image: nginx
ports:
- "80:80"
volumes:
- default.conf:/etc/nginx/conf.d/default.conf
links:
- app
- api
And here the configuration for Nginx:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app;
}
location /api {
proxy_pass http://api;
}
}
upstream app {
server app:80;
}
upstream api {
server api:80;
}
When you link a container to another container (in this case to Nginx) Docker changes the /etc/hosts
file and add lines like this:
172.17.0.7 api 165637cfd4ab yourproject_api_1
172.17.0.5 app dedf870dec53 yourproject_app_1
So Nginx knows about the api and app containers.
When a request comes in at 'localhost:80' Nginx will proxy it to http://app:80
. The hosts
resolves a request to htt://app
to 172.17.0.7
and so this request is forwarded to the app container.
Start all containers with $ docker-compose up
and you're done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With