Working as a Developer/DevOps who works with docker on daily basis or just getting started to learn using the container tech tools, I think there are some good practices that most people will agree on following.
So here are some tips I found while learning about creating Docker images.
1. Always chain RUN commands
Each RUN command will create a new extra layer because RUN command commits the changes you made in the top writable layer into a new image, You need to reduce images (to decrease complexity and increase speed).
So don’t do this
FROM ubuntu:xenial RUN apt-get update Run apt-get install -y git RUN apt-get install -y vim RUN apt-get install -y curl
FROM ubuntu:xenial RUN apt-get update && apt-get install -y curl \ git \ vim
2. Use COPY instead of ADD unless you are sure you need ADD
COPY : is a command used to copy files from the source directory to your container file system.
ADD also can copy files from source to container it also can download files and unpack zipped files.
COPY are functionally similar, generally speaking,
COPY is preferred. That’s because it’s more transparent than
3. Avoid using [:latest] tag
From command picks your base docker image you are building on, try to specify an official release tag and not
latest tag (tagging image latest release with
latest ) is just a convention not all maintainers obligated to follow it, so specify a tag.
4. Sort your multi-line dependencies in alphanumeric order
When installing dependencies there is a best practice to order dependencies in alphanumeric order. this way you will avoid duplication.
RUN apt-get update && apt-get install -y curl \ git \ vim
5. Always use unprivileged normal user to run your app
By default, your container process runs as the root user, which introduces the risk of (given a scenario if a hacker breaks in the container using root user) they can also hack into your host machine.
So before running your app using
CMD create normal user and use him to run your app like:
RUN useradd -ms /bin/bash ahmed USER ahmed CMD [“python”, “app.py”]
6. Make sure to invalidate image cache when you update images.
apt-get update and
apt-get install helps to avoid running outdated images, the problem happens because for
apt-get update instruction, if run alone, will be cached with old updates, however, if you add new package like git to install it’s probably you won’t install the latest version of git if the
apt-get update is cached, being aware of that problem you can stop using the cache if needed
docker build — no-cache=true
docker-compose: when using docker-compose you just need to make sure you build images, as
docker-compose up -d only builds images if they don’t exist, so if you change anything you need to build them again.
7. Avoid using the Host network unless you know what you are doing.
Creating a container with Host Network type can be risky, it’s the network with minimum security level because it shares same network interfaces as the host machine, although it’s fast (because requests don’t have to go through hosts IP mapping tables) it’s risky and not advisable to do it in production.
There are four networks types between docker containers : [Closed-Bridge-Host-Overlay]
Bridge: is the default where containers in the same bridge network can communicate with each other and outside world.
Closed: is isolated can’t even connect to the internet.
Overlay: is used with multi-host networking across many hosts (like in docker-swarm or Kubernetes)
Hope you liked the tips, you can check more best practices here https://docs.docker.com/develop/develop-images/dockerfile_best-practices
Please contact me if you have any thoughts about the topic
Thanks for reading ❤️