Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start Docker Containers In Specific Order After Reboot

Tags:

docker

Context

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

The Problem

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.

like image 453
Programster Avatar asked Jun 12 '15 09:06

Programster


1 Answers

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.

like image 80
OrangeTux Avatar answered Nov 10 '22 07:11

OrangeTux