Docker and Docker-compose analysis

Introduction

As we mentioned in Full Stack Deployments with Docker Compose | by Austin Sasko | Mar, 2022 | Medium, Docker is a containerization software that allows us to enhance our ability to build software. We no longer have to worry about the type of server that hosts our data being Windows and therefore not supporting certain software, or being Ubuntu vs CentOS and not having certain packages. This article will detail the infrastructure, software, and configurations for how this works.

Docker

Docker creates a compact pieced together resource that you can run, based on the provided instruction set. This resource is called a Docker Image and becomes your container when you run it.

Docker images — There are two types of images, a base image and a parent image (most types of images). A parent image is FROM another built image, for example FROM centos:7, whereas a base image starts with FROM scratch. scratch is a special image that Docker has to indicate that the image we are building should not be based on any other image but instead be a minimal environment that has no pre-existing file system until you run the next step in the Dockerfile. scratch is usually used to build an OS container image or to run a statically compiled binary that does not have any dependencies and can be ran at the lowest level.

Additional reading

Historical Context

Before Docker, installing software on a server was often a lengthy time consuming process that was done by following documentation and knowledgebase articles. After some time it was done via server automation tools like Ansible in playbooks.

Dockerfile

A Dockerfile is the instruction set that tells Docker how to create a new container. Some important instructions are:

FROM — The file starts with the FROM command which will provide the instruction for what your new image should built/based off of. FROM ubuntu:16or FROM python:3.10are examples of basing your container off of a base image.

  • Syntax: FROM centos:7 # Bases image off of Centos 7

RUN — Once you have your FROM defined, you can run certain commands to continue to build out your container. For example if you need to make network modifications or install an apt/yum package, you can use RUN

  • Syntax: RUN apt-get update -y # Updates all available apt packages

ADD — This instruction will add whatever the src provided is to the provided dest path in the container. If src is a compressed file format (.zip/.tar.gz) then it will be extracted when added into the container image. If src is a URL, will fetch the URL and place it into the provided dest path.

  • Syntax: ADD https://example.com/script.py / # Adds script.py to the / directory

COPY — This instruction is nearly identical to ADD but it does not automatically extract compressed files nor does it allow the src to be a URL. COPY is recommended to be used when just copying files/directories from the source to the destination and if anything more complex is needed, then ADD should be considered

  • Syntax: COPY script.py / # Adds script.py to the / directory

ENTRYPOINT — This instruction defines the binary or command that must be run every time when you first enter or run the container. Often is used to define the shell used when running an interactive container or the script that the container is made for (e.g. a web server running flask.py). Command args should be separated by commas encapsulated in quotes.

Syntax: ENTRYPOINT ["python3", "web_server.py"] or ENTRYPOINT ["/bin/bash"]

CMD — This instruction defines commands that should be run when you first enter or run the container. This command can be overridden by a CLI argument or in a parent image. Often is used to define recommended behaviors for the container but ones that are not absolutely required, e.g. a container that has multiple scripts that can be ran but defaults to main.py can have CMD ["python3", "main.py"] and someone can override that to specify CMD python3 other.py . Command args should be separated by commas and encapsulated in quotes. CMD can be paired with ENTRYPOINT to provide a command / parameter behavior. Specifying python3 in the ENTRYPOINT and then filename.py in the CMD can provide an experience that ensures the container ALWAYS runs python3 and then the file that gets ran changes based on inputs.

  • Syntax: CMD ["echo", "Welcome"] or CMD ["cd", "/home"]

ENV — This instruction defines environment variables that can be accessed by anything in the container. Useful for variables that are unique to that environment, like IP addresses usernames, etc. Treated just like normal system environment variables.

  • Syntax: ENV DEST_IP="1.2.3.4" or ENV WEB_USER="asasko"

You can have a docker image run your web application using just a few of these instructions.

FROM python:3.10
COPY web_server.py /
ENTRYPOINT ["python", "/web_server.py"]

Commands

Docker provides a CLI to interact with, build, or manage containers/images. Some important commands to keep in mind are:

docker build — Used to run the full instruction set given from a Dockerfile and turn it into a built container image. Useful flags:

  1. -t Specify a name for the built container image. If not specified, will be generated as a hash

docker create (Usually not used in favor of docker run) — Used to create a ready-to-start container from a built docker image. Useful flags:

  1. — -name Specify a name for the container. If not specified, will be generated as a hash
  2. -t — Used to specify that you want a “pseduo-tty” which means that you want to do certain operations like have a colored terminal, use prompts, bash functions, etc.
  • Syntax: docker create name_of_built_image --name container_name -t

docker start — (Usually not used, in favor of docker run) — Used to run start a stopped/inactive container. Useful flags:

  1. -i — Used to specify that you want to start the container and attach interactively, to be able to run commands in the container, for example you want to “log in” to the container and run commands, see the system react, and be able to continue to run commands in that live environment.
  • Syntax: docker start container_name -i

docker restart — Used to restart a docker container.

  • Syntax: docker restart container_name

docker run — Used to run a built container image. Useful flags:

  1. -i — Used to specify that you want to be able to run commands and interact container, for example you want to “log in” to the container and run commands, see the system react, and be able to continue to run commands in that live environment. This will not let you treat the container environment as if connected via terminal (no prompts, bash functions, etc.) without -t flag.
  2. -t — Used to specify that you want a “pseduo-tty” which means that you want to do certain operations like have a colored terminal, use prompts, bash functions, etc.
  3. -d — Used to run a container in detached state, where the process(es) and outputs are backgrounded.
  4. --rm — Used to remove the container when the main process(es) exit/finishes
  • Syntax: docker run my_image

docker ps — Used to list the containers. Defaults to listing only running containers. Useful flags:

  1. -a — Used to list all containers regardless of current state.
  • Syntax: docker ps

docker rm — Used to delete/remove a container.

  • Syntax: docker rm container_name

docker rmi — Used to delete/remove an image.

  • Syntax: docker rmi image_name

docker logs — Used to see/review the container output/logs. Useful flags:

  1. -f — Used to follow the logs of a container live
  • Syntax: docker logs container_name

Docker-compose

Docker-compose is tool used to orchestrate environments, stacks, or multiple containers. If you wanted to have a web server, database, and monitoring container (3 containers) all working together, docker-compose would help make the consistent deployment of all 3 together much easier. Docker-compose uses a build file called docker-compose.yml and will automatically detect and rebuild/recreate services that have changed. Some important commands for it are:

  1. docker-compose -f compose.yml— Used to specify the docker compose configuration file

docker-compose up — Used to turn on the services specified in docker-compose.yml. Useful flags:

  1. -d — Used to start the containers in a detached state
  2. --build — Used to build new images for a service even if one is already built
  3. --force-recreate — Used to forcibly recreate all services specified in the compose yml even if nothing changed
  4. Syntax: docker-compose up -d

docker-compose down — Used to turn off the services specified in docker-compose.yml. Useful flags:

  1. --rmi — Used to remove the images that were built for the services
  2. -v — Used to remove the volumes from the containers that were built
  • Syntax: docker-compose down

docker-compose restart — Used to restart all docker-compose services

  • Syntax: docker-compose restart

docker-compose logs — Used to see/review the container output/logs. Useful flags:

  1. -f — Used to follow the logs of a container live
  • Syntax: docker-compose logs

docker-compose rm — Used to remove all stopped services. Useful flags:

  1. -v — Used to remove volumes / data that was attached to any of the stopped services
  • Syntax: docker-compose rm

Example docker-compose file spec:

version: '3'services:
mariadb: # Name of compose service
container_name: mariadb # Name for the container
restart: always # Defines the restart policy for the service Start containers automatically | Docker Documentation
volumes: # Define where to store persistent data from the container directory specified, /var/lib/mysql
- mysql-data:/var/lib/mysql
env_file: # Define a file that has the environment variables for the container
- db.env
volumes:
example_volume:

Best commands to know / Most frequently used

  1. docker-compose up
  2. docker-compose down
  3. Docker build
  4. Docker run

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store