Tips & Tricks with Docker & Docker compose

I'll be updating this post with new tips and tricks about Docker & Docker compose as my personal list of useful commands and configurations.


Use base Docker image scratch

If for any reason you wanna use a image without anything use Docker scratch image

FROM scratch  

This image it's basically no useful at all unless you have a binary with all the dependencies on it to run it


Tag an image

$ docker tag [image_id] [image_name]:[tag]

Persist images

$ docker save [image_name]

Persist containers

$ docker export [container_id]

Load images from a tar file

$ docker load < [tar_file]

History of our images

$ docker history [image_name]

This will give us more details about all the steps (intermediate containers) needed to build our image.

Create a container from an image

sudo docker run -d [image_name] -p [host_map_port:container_exposed_port]  

Squashing images

I't as simple as create a container from the image and the export it, create a container flat the image and will leave it with just one layer

$ docker export [image_id] | sudo docker import - [image_name]:[image_tag]

ssh into the docker container

$ docker exec -it [container_name] bash

Publish your images to DockerHub

As simple as run:

$ docker login

Introduce your credentials

$docker push [image_name]

You can as well as just link your GitHub project to Docker Hub project and build images automatically

List all containers

$ docker ps

Kill the actual container (turn it off)

$ docker kill [container_name]

Remove container

$ docker rm [container_name]

Remove all stoped containers

docker rm $(docker ps -a -q)  

Remove all untagged containers

docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

Build the actual container (the one on the path where running the command)

$ docker build .

Remove that Image Id plus all the version of that imagen

$ docker rmi 58a51672eb36

 Show all docker images

$ docker images

Build and tag

$ docker build -t api .

Note: that build and tag won't work and we'll need to build first, show images second and last tag the image

Keep clean our Dockerfile and minimal

The following is a good example of how our Dockerfile should looks like

FROM frolvlad/alpine-glibc


RUN set -ex \  
  && apk --no-cache add --virtual .build-dependencies \
    curl \
  && curl -fsSL${FILEBEAT_VERSION}-x86_64.tar.gz -o /tmp/filebeat.tar.gz \
  && cd /tmp \
  && echo "${FILEBEAT_SRC_SHA1} *filebeat.tar.gz" | sha1sum -c - \
  && tar -xzf filebeat.tar.gz \
  && cd filebeat-* \
  && cp filebeat /bin \
  && rm -rf /tmp/filebeat* \
  && apk del .build-dependencies

CMD [ "filebeat", "-e" ]  
  • Separation for redability
  • Use a tmp folder to operate
  • Block of operations to keep the images to a minimum size
  • Virtual dependencies on Alpine to make easy clean up after the installation
  • Alphabetic order to easy track dependencies/environment variables

Notice: I'm not copying any config file in here or exposing any port those are things that I will do on the image that it's gonna use this very base image

Persist data in a container

For example if running postgres and you wanna keep your database even if you destroy your container you will need to add the following to your Dockerfile

VOLUME /var/lib/postgresql/data  

Use Embedded Docker DNS

This is the IP of the embedded docker dns resolver useful if you need to resolver others containers links with in your app like when using nginx that you need to specify a resolver.

Honor user when COPY or ADD

With Docker 17.09 we have gain the following flag for the COPY and ADD commands --chown

So we can do something like this to set a specific user to a file/folder that we are copying:

ADD --chown=someuser:somegroup /foo /bar  
COPY --chown=someuser:somegroup /foo /bar  


Docker compose

 Build a base image

Note: is recommended to use a tools to build first the needed image from our Dockerfiles

We can use this command on our docker-compose.yml file to generate a base image from which inherit our containers like:

    command: /bin/true

And then use in our Dockerfiles the FROM like:

    FROM: compose_base

There is more detail about how to implement this and why not to do it on this two threads:

Set a container name

You can add the following to your docker-compose.yml file to set the container name:

    container_name: forex

Set an image name

If you are building from a Dockerfile you can add image to set your image name as:

      context: ../../../app/
      dockerfile: Dockerfile
    image: base


Allow both image and build in a service config, and use image as the image name when building, if it exists.

Run the docker compose configuration file docker-compose.yml

$ docker-compose up -d

Build and link the docker container with the rest

$ docker-compose build api

Fix problem when docker-compose up doesn't work

If we are seeing the following issue when docker-compose up

docker-compose up  
Recreating appname_api_1...  
No such image: appname_api:latest (tag: latest)  

We'll need to run

$ docker-compose rm api


Remove all containers, images and networks created by docker-compose up command

docker-compose -f docker-compose.yml down --rmi all  




Interesting plugin to make our life easier when working with Vagrant and Docker compose leighmcculloch/vagrant-docker-compose