Docker from zero to survive

Dany Paredes - Nov 2 '21 - - Dev Community

Be ready to deploy your apps with Docker is a one of higher-demand knowledge today, and this article will guide you (and me ) from zero to survive with Docker.

The guide key features are:

  • Install and run docker
  • Create and build images
  • Mount volumes
  • Create networks
  • Publish in dockerhub
  • Use Docker-compose.

After reading the docker official documentation, we understood that Docker gives us the freedom to run our applications everywhere, language and framework-agnostic, and unlock the following points.

  • Easy way to deliver an application.
  • Make easy setup sandbox for development.
  • No version conflicts and environment consistency.
  • Easy to know the dependencies and requirements of our apps.

Install Docker and Run

The Docker provides an installer for Windows and Mac; for Linux, you need to write some commands. All steps are on the official docker website https://docs.docker.com/engine/install/ubuntu/ or use the following command scripts.

It works in Ubuntu 20 or higher.

sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" -y
sudo apt update
sudo apt install docker-ce -y
sudo usermod -aG docker ${USER}
su - ${USER}
id -nG
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
docker ps
Enter fullscreen mode Exit fullscreen mode

If everything works, test your Docker running the following command from terminal Docker run hello-world.

    docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    2db29710123e: Pull complete 
    Digest: sha256:37a0b92b08d4919615c3ee023f7ddb068d12b8387475d64c622ac30f45c29c51
    Status: Downloaded newer image for hello-world:latest
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
Enter fullscreen mode Exit fullscreen mode

The command, get the image, and run it! If you get the message, you are ready for the next step about Docker images.

Docker Images

A Docker image is like a box. It can bring one or multiple services, apps, databases, web servers, cache, etc.

For example, if you want a webserver like Nginx, Docker pulls and runs an image with an Nginx server ready, so you don't need to install Linux, install Nginx, configure ports, etc.

If you already worked with git, it sounds familiar typing; Docker pull nginx, Docker finds in your machine for the image, if not then gets from Dockerhub.

Dockerhub is like GitHub for Docker.

dany@dany:~$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
Enter fullscreen mode Exit fullscreen mode

Docker provides more commands to work with images like docker images lists all images in our machine.

dany@dany:~$ docker images
REPOSITORY TAG           IMAGE ID       CREATED         SIZE
nginx      latest        87a94228f133   2 weeks ago     133MB
Enter fullscreen mode Exit fullscreen mode

Remove our images. We use docker rmi imageid or name.

dany@dany:~$ docker rmi nginx
Untagged: nginx:latest
Untagged: nginx@sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36
Deleted: sha256:87a94228f133e2da99cb16d653cd1373c5b4e8689956386c1c12b60a20421a02
Enter fullscreen mode Exit fullscreen mode

Sometimes, our image is linked with a container and needs to use -f to force remove it.

We are ready to run our containers!

Running Containers

We have the nginx image in our machine, and then Docker helps us start the nginx and try to access the port provided by nginx; in short, it is like telling Docker.

Hey Docker, please run nginx using port x and translate port x to port y from nginx; the command version is docker run -p 8080:80 nginx.

The container start and show the logs into the terminal.

docker run  -p 8080:80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 
Enter fullscreen mode Exit fullscreen mode

Ready, from the browser, go to http://localhost:8080, next step build our image.

The Dockerfile

Building an image for Docker requires a particular file, "The Dockerfile" it contains all commands to Docker build, like code, and use docker build compiler and build the Docker image.

The Dockerfile is a yml, with a few commands most used instructions:

FROM The image where we want to start. e.g., FROM node:alpine.

LABEL add extra information, e.g., LABEL author=" Dany."

ENV declare variables, e.g., ENV NODE_ENV=production.

WORKDIR The location in the container. e.g. WORKDIR /var/www.

COPY Copy files to the container, e.g., COPY index.html /var/www.

RUN Executes the command in the container, e.g., RUN npm install.

EXPOSE Open a port to communicate with the container, e.g., EXPOSE 8080.

ENTRYPOINT The command to start the container. e.g ENTRYPOINT [./app.sh ]

Now, we have an idea of the main keywords, let's build an image with the following points.

  • Create bases of a node:alpine, it comes with node.
  • Define our name as the author
  • Declare an environment variable
  • Install the HTTP-server npm package.
  • Set a working directory
  • Copy an index.html file into the container.
  • Run entry project, the HTTP-server.

Build our Image

Create a file app.dockerfile

FROM        node:alpine
LABEL       author="Dany  Paredes"
ENV         production=false
WORKDIR     /var/www
COPY        index.html  .
RUN         npm  install  http-server  -g
EXPOSE      8080
ENTRYPOINT  ["http-server"]
Enter fullscreen mode Exit fullscreen mode

Create a file index.html with content like "Hello from Docker" in the same directory of the app.dockerfile.

<h1>Hello! from docker!!</h1>
Enter fullscreen mode Exit fullscreen mode

Build the image using the Docker build command and using -t flag to tell the name of our image and -f flag to tell which docker file to use.

Skip use -f if the docker file name is Dockerfile.

docker build -t webdockerize -f app.dockerfile .
Sending build context to Docker daemon  3.072kB
Step 1/8 : FROM node:alpine..
Successfully built 437881e62fa2
Successfully tagged blog:latest
 ---> c0fc1c9c473b
Enter fullscreen mode Exit fullscreen mode

Docker built the blog image. Next, list the docker-images, and the webdockerize is in our list.

dany@dany:~/Documents/dockriz$ docker images
REPOSITORY    TAG     IMAGE ID       CREATED         SIZE
webdockerize  latest  437881e62fa2   5 minutes ago   176MB
Enter fullscreen mode Exit fullscreen mode

Ready to run the image with the command docker run and using the ports 8080.

docker run -p 8088:8080 webdockerize
Starting up http-server, serving ./
http-server version: 14.0.0
Available on:
  http://127.0.0.1:8080
  http://172.17.0.2:8080
Hit CTRL-C to stop the server
Enter fullscreen mode Exit fullscreen mode

Our webserver is running. Go to http://localhost:8088, and it shows the hello docker page.

Container with Volumes

To access the container to the local directory or use files from our machines, we use our machine directory as part of the container instead of copying files to the images.

Docker with the flag -v (volumes) allows the container map host directory as part of the container. Close similar to the ports; the volume works the same way, -v external directory: internal directory.

docker run -p 8088:8080 -v /home/dany/Documents/dockriz/app:/var/www danywalls/webdockerize
Enter fullscreen mode Exit fullscreen mode

Use ${PWD} if you want to take the current directory.

Playing with the containers.

The container is ready, maybe run one or two instances, know which containers are running, get into the container or watch the output like logs; Docker provides a solution for each situation.

List active containers, docker ps -a.

docker ps -a
ID  IMAGE  COMMAND CREATED     STATUS       PORTS     NAMES
8a21256f7f3f   nginx     "/docker-entrypoint.…"   5 seconds ago   Exited       dazzling_ganguly
Enter fullscreen mode Exit fullscreen mode

To get into the container shell, use the command docker exec -it containerid. It will give access to the container shell to play with it.

docker exec -it 34bb0840ddb5 sh
/var/www # ls
index.html
Enter fullscreen mode Exit fullscreen mode

Get the output log from the container using docker logs container.

docker logs 8a21256f7f3f
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
Enter fullscreen mode Exit fullscreen mode

We can learn more about available commands running Docker --help or check out the docker guides https://docs.docker.com/go/guides/.

Docker Network

Sometimes we need to run multiple containers of the same or other images and talk together, like an app with API or database. We can have a container with a database and another with the web app.

We use a bridge network to communicate between containers, and Docker allows us to use the docker network command.

To create a network using docker network create and the driver to use (you have multiple types), my example is bridge focus to communicate my containers between them.

docker network create --drive bridge danynetwork
Enter fullscreen mode Exit fullscreen mode

Other handy commands are:

  • docker network ls get the list of network
  • docker network rm network name remove a network

Read more about network drivers https://docs.docker.com/network/#network-drivers

Run our container in specific network use --net and network name.

docker run -d --net=danynetwork -p 3050:3000 danywalls/webdockerize
Enter fullscreen mode Exit fullscreen mode

Dockerhub

Dockerhub is like the GitHub for our docker images. Create an account at https://hub.docker.com/, and login into the terminal with the command docker login, add your credentials, and our Docker is ready to store our images.

Run again to build with the flag -t and your username/name of the image.

docker build -t danywalls/webdockerize -f app.dockerfile .
Enter fullscreen mode Exit fullscreen mode

Next, push the image using docker push and the last build image with tagged with your username.

dany@dany:~/Documents/dockriz$ docker push danywalls/webdockerize:latest
The push refers to repository [docker.io/danywalls/webdockerize]
2d6ed4627650: Pushed 
e9522abed4c4: Pushed 
a40075dcb1c2: Pushed 
bdfe600c60fd: Mounted from library/node 
e9b39456535c: Mounted from library/node 
d61ddabe4e93: Mounted from library/node 
e2eb06d8af82: Mounted from library/node 
latest: digest: sha256:e6fbc3dbf6bba15cf312d12ee6600bd4f27a2f49e05f105dc1a54c05550a68c5 size: 1783
Enter fullscreen mode Exit fullscreen mode

Remove the local image using docker rmi.

docker rmi danywalls/webdockerize:latest 
Untagged: danywalls/webdockerize:latest
Untagged: danywalls/webdockerize@sha256:e6fbc3dbf6bba15cf312d12ee6600bd4f27a2f49e05f105dc1a54c05550a68c5
Enter fullscreen mode Exit fullscreen mode

Get the image from dockerhub using the docker pull command.

docker pull danywalls/webdockerize:latest
latest: Pulling from danywalls/webdockerize
Digest: sha256:e6fbc3dbf6bba15cf312d12ee6600bd4f27a2f49e05f105dc1a54c05550a68c5
Status: Downloaded newer image for danywalls/webdockerize:latest
docker.io/danywalls/webdockerize:latest
Enter fullscreen mode Exit fullscreen mode

Docker Compose

All steps before commands, we can simplify using docker-compose.

Docker-Compose helps us define services using a YAML file, build multiple images, start and stop services and have everything in a single file.

Basic docker-compose commands:

  • docker-compose build: take all services and build the images.
    • docker-compose up start all containers.
  • docker-compose down stop all containers.

Read more about docker-compose https://docs.docker.com/compose/

The docker-compose.yml

Some docker key areas.

  • version: '3.x' the version of files
  • services: the declaration of our containers
  • networks: define the network between containers.
  • depends_on: define a container dependency.

Create a file docker-compose.yml it, in the services area,
declare two containers, 'web' and 'API.'

images: tell where we get from local file or dockerhub.
ports: the expose port network: to add the container into a network.
depends_on: if our container requires another before starting.

The docker-compose.yml looks like this:

version: '3.0'
services:
  web:
    image: danywalls/webdockerize
    ports:
      - '8080:8080'
    networks:
      - danynetwork
    depends_on:
      - api
  api:
    image: danywalls/apijson
    ports:
      - '3000:8080'
    networks:
      - danynetwork
networks:
  danynetwork:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode

Next, start our containers using docker-compose up.

 docker-compose up
Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/
Creating dockriz_api_1 ... done
Creating dockriz_web_1 ... done
Enter fullscreen mode Exit fullscreen mode

The web and API work if you stop all the containers and network with the flag stop.

docker-compose stop
Enter fullscreen mode Exit fullscreen mode

Done!

That's it! Hopefully, give you a bit of help with Docker about basic commands with Docker, deploy our apps, create our images, communicate between using networks and simplify the process using docker-compose.

If you enjoyed this post, share it!

Helpful links
https://typeofnan.dev/how-to-stop-all-docker-containers/
https://www.docker.com/sites/default/files/d8/2019-09/docker-cheat-sheet.pdf

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .