The true docker way for deployment

Hello everyone!

I’m interesting in right way of deploying web app using docker.

For example, I had 3 containers:

  1. App container with nginx/php-fpm and php code (someone could tell to divide them into two containers, may be you are right, but it’s not the main question of this topic)
  2. Broker container with node code for websockets
  3. DB container with Postgre

I had this files for successful containers build:

- dockerfiles
    - dev
        - build-app
            - Dockerfile
        - build-node
            - Dockerfile
            - package.json
        - docker-compose.yml
    - prod
        - the same structure...

My docker-compose.yml looks like this:

app:
    container_name: project-app
    net: docker_internal_net
    # set the build context to the project root
    build: ../..
    # set the path to Dockerfile relative to build context
    dockerfile: ./dockerfiles/dev/build-app/Dockerfile
postgres:
    container_name: project-postgres
    net: docker_internal_net
    image: postgres:9.4.5
    volumes:
        - /var/db/postgres:/var/lib/postgresql/data
node:
    container_name: project-node
    net: docker_internal_net
    # set the build context to the project root
    build: ../..
    # set the path to Dockerfile relative to build context
    dockerfile: ./dockerfiles/dev/build-node/Dockerfile
    volumes:
        - /var/log/project/nodejs:/app/log

build-app/Dockerfile:

FROM myprivateimage
# some other instructions

build-node/Dockerfile:

FROM node:4.2.1

ADD ./dockerfiles/node /app # adds nodejs files to container

COPY ./dockerfiles/dev/build-node/package.json /app/

WORKDIR /app

RUN npm install --silent

CMD npm start > /app/log/node.log

myprivateimage build from phusion/baseimage:0.9.17 with some additions.

I had docker-compose.yml to manipulate them in one command with docker-compose. And now my deploy looks like this:

docker-compose stop # 1
docker-compose rm -f # 2
docker-compose build # 3
docker-compose run # 4

And it works, but between removing the containers (#2) and running them back (#4) I had a long build command (#3), now It takes from 0.5-2 minutes dowtime for completely build.


I google a lot and all I saw were advises for building new image in background and then just stops and run again my containers from new build.

So I made this steps:

  1. build new revision image

    trying to run the same container as project-app

    docker run -d --name project-app-deploy --net docker_internal_net myprivateimage

    doing some init stuff, generate new revision nginx config, etc…

    docker exec -it project-app-deploy /some/init/scripts

    save changes

    docker commit -a myusername -m “revision 12345” project-app-deploy project-app:12345

    tag is as latest

    docker tag -f project-app:12345 project-app:latest

  2. changed into build-app/Dockerfile the from command to FROM project-app:latest, so in this image I had the latest stable build

  3. Because project-node can not be build as project-app (run+exec+commit), because of add instruction in its Dockerfile, so I need to execute docker build -f ./dockerfiles/dev/build-node/Dockerfile -t project-node:12345 ./dockerfiles, then tag it to latest, and also changed the from command in its Dockerfile too.

Ok, looks good. I’ve tried, and the results is much faster as my old deploy strategy.


THE QUESTION: It’s okay if i need two Dockerfile & docker-compose.yml files for deploy build & container run (total 4 pair of files: deploy app, deploy node, build app, build node)? Because as you can see below I execute docker run manually, copypasted all the thing. But I think base (eg deploy) docker-compose.yml with child (eg real app) docker-compose.yml with extends – if better.

Any comments is appreciated!

Thanks for you advises.