What is a docker Image and Docker container?

A Docker image consists of read-only layers each of which represents a Dockerfile instruction. The layers are stacked and each one is a delta of the changes from the previous layer. 

When you run an image and generate a container, you add a new writable layer (the “container layer”) on top of the underlying layers. All changes made to the running container, such as writing new files, modifying existing files, and deleting files, are written to this thin writable container layer.

Dockerfile vs Docker Compose

Remember, docker-compose.yml files are used for defining and running multi-container Docker applications, whereas Dockerfiles are simple text files that contain the commands to assemble an image that will be used to deploy containers. The commmads may refer to a base image that will be used by Dockerfile.

Options to deploy images into containers:

  1. Execute pull,run commands with parameters one by one at the terminal. Any update to the packages can be done only after creating the container.
  2. Run Dockerfile to assemble an image. Dockerfile will have references to a base image, files to override, ports to be open etc.
  3. Use docker-compose.yml file and run it . It gets complicated because you can use docker-compose.yml in such a way that it will call upon a Dockerfile to allow you to create even more complex container rollouts.

1.Terminal deployment

Create a project folder
$ mkdir myDockerBuild
Pull docker image from dockerhub
$ docker pull alpine
Check creation of images using
$Docker images Or docker image ls
Run the image as a container. The image updates needs to be run manually
$docker container run alpine -d
To List the containers that are running
$ docker container ls
To List all the containers
$ docker ps -a
To update the packages,
Log into the docker container: 
>root$ docker exec -it <containerid> bash
Run commands to update and install as required. These commands need to be executed for every container to ensure it meets your needs.
Inside the container
$apk update && apk upgrade

2.Dockerfile

Dockerfile is a file used to build a Docker image to your specifics, but one container at a time. With a Dockerfile constructed, you could then easily build the same image over and over, without having to walk through the process manually over each server.

Some of the available commands are: 

FROM,ADD, ENTRYPOINT, RUN, CMD ,EXPOSE, ENV, MAINTAINER, VOLUME , WORKDIR

Creating Dockerfile to create a custom alpine image

Create a directory
$mkdir mydockerbuild
$cd mydockerbuild
Create and open a file Dockerfile. Type up below content:
   FROM alpine:latest
   RUN apk update && apk upgrade
   CMD echo “Inside alpine container using Dockerfile”
Building the image
$docker build -t “name:Dockerfile” .
This should be run by a user in the docker group. 
Don't forget the . at the end of the command.
Build multiple images from this Dockerfile
$docker build -t "webdev:Dockerfile" .
$docker build -t "appdev:Dockerfile" .
$docker build -t "secdev:Dockerfile" .
To check the images created
$docker images

3.Docker Compose

Docker-compose is used for defining and running multi-container docker applications while Dockerfile can create only one container at a time.

The docker-compose.yml file is broken into sections, each section represents a single container which, when combined with the other containers, create the service.

For example, you could have a docker-compose.yml file that consists of two sections: web – the web server portion of the application. db – the database server portion of the application.

In the docker project directory, create a file named docker-compose.yml with below contents. 

version: '3'
services:
web:
image: nginx
db:
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=demodb

You could instruct docker-compose that the web portion will be defined in the Dockerfile. In fact,  with docker-compose, you can include multiple Dockerfiles to build very complex stacks. We’ll get there soon.

Bring up the docker-compose with the below command
$ docker-compose up -d
Check the processes with the command
$ docker-compose ps
Note: Use package yamllint to validate the docker-compose.yml file.
$yamllint docker-compose.yml
Login to mysql from Host:
mysql -h 127.0.0.1 -P 3306 -u user -p
mysql -h localhost -P 3306 --protocol=tcp -u user -p

4.Docker-Compose with Dockerfile

In the Docker Project folder create Dockerfile with content

FROM nginx:latest
MAINTAINER NAME EMAIL
RUN apt-get -y update && apt-get -y upgrade && apt-get install

You could then run the docker build command with that Dockerfile, like so:

$ docker build -t "webdev:Dockerfile" .

But we want to integrate that file into docker-compose.yml. Create a docker-compose.yml file which uses that Dockerfile, but also adds a database to the stack. This docker-compose.yml file might look like:

version: '3'
services:
web:
build: .
ports:
- "8080:80"
db:
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=demodb

Dockerfile in the same directory (the . indicates to run the build command in the current working directory). If we wanted to house our Dockerfile in a completely separate directory, it would be declared here. Say, for example, the docker-compose.yml file is in ~/dockerbuild and the Dockercompose file is in ~/nginxbuild, you could declare that with the line:

build: ~/nginxbuild

Run the docker-compose from the project directory

$ docker-compose up

So What do you take home?

  1. Create Dockerfiles to build the required images from base images. Make initial configuration on the new images. 
  2. Define complex stacks (consisting of individual containers) based on those Dockerfile images from within docker-compose.yml. 
  3. Deploy the entire stack with the docker compose command.

Subscribe to my newsletter

Leave a comment