End to End Docker

Sami Salih İbrahimbaş
7 min readApr 24, 2024

--

This story is about how to use Docker to create a complete development environment for a project.

Article Cover

Introduction

Docker is a tool that allows you to create, deploy, and run applications using containers. Containers are lightweight, standalone, and executable packages that contain everything needed to run an application, including the code, runtime, libraries, and dependencies.

In this story, I will show you how to use Docker to create a complete development environment for a project.

Setting up a Docker development environment

To set up a Docker development environment, you need to install Docker on your machine. You can download Docker from the official website and follow the installation instructions for your operating system.

Once Docker is installed, you can start using it to create containers for your project. You can use Docker Compose to define and run multi-container Docker applications. Docker Compose allows you to define a multi-container application in a single file and run it with a single command.

Building a Docker image for the project

To build a Docker image for your project, you need to create a Dockerfile in the root directory of your project. The Dockerfile contains instructions for building the Docker image, such as the base image, dependencies, and commands to run the application.

Here is an example of a Dockerfile for a Golang project:

# Dockerfile
# Use the official golang image as a base image
FROM golang:1.16
# Set the working directory in the container
WORKDIR /app
# Copy the source code to the container
COPY . .
# Build the Go application
RUN go build -o app
# Expose the port the application runs on
EXPOSE 8080
# Run the application
CMD ["./app"]

In this example, we are using the official golang image as the base image for our project. We set the working directory in the container to /app, copy the source code to the container, build the Go application, expose port 8080, and run the application.

You can build the Docker image for your project using the docker build command. You can run the Docker image using the docker run command.

Optimizing the Docker image for production

To optimize the Docker image for production, you can use multi-stage builds, minimize the number of layers, and use a smaller base image.

Multi-stage builds allow you to use multiple FROM instructions in a single Dockerfile. You can use one stage to build the application and another stage to run the application. This allows you to keep the final image small and reduce the attack surface.

You can minimize the number of layers in the Docker image by combining multiple commands into a single RUN instruction. This reduces the size of the image and speeds up the build process.

You can use a smaller base image for the Docker image to reduce the size of the image. For example, you can use the alpine image instead of the debian image to create a smaller image.

For more detailed examples, you can read my previous docker story.

Deploying the Docker image to a production environment

To deploy the Docker image to a production environment, you can use a container orchestration tool such as Kubernetes or Docker Swarm. These tools allow you to manage and scale the Docker containers in a production environment.

You can use Kubernetes to deploy the Docker image to a cluster of nodes. Kubernetes provides features such as load balancing, auto-scaling, and rolling updates to manage the containers in a production environment.

You can use Docker Swarm to deploy the Docker image to a cluster of nodes. Docker Swarm provides features such as service discovery, load balancing, and rolling updates to manage the containers in a production environment.

Defining a multi-container application using Docker Compose

Docker Compose allows you to define a multi-container application in a single file. You can define the services, networks, and volumes for your application in a docker-compose.yml file.

Here is an example of a docker-compose.yml file for a multi-container application:

version: '3'
services:
web:
build: .
ports:
- "8080:8080"
volumes:
- .:/app
depends_on:
- db
db:
image: postgres
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: app

In this example, we define two services: web and db. The web service builds the Docker image for the project, exposes port 8080, mounts the current directory to /app, and depends on the db service. The db service uses the official postgres image, sets the environment variables for the database, and creates a database named app.

You can run the multi-container application using the docker compose up command. You can stop the application using the docker compose down command.

Securing the Docker containers

To secure the Docker containers, you can follow best practices such as using a minimal base image, updating the base image regularly, and scanning the image for vulnerabilities.

You can use a minimal base image for the Docker containers to reduce the attack surface. For example, you can use the alpine image instead of the debian image to create a smaller image.

You can update the base image regularly to patch security vulnerabilities. You can use the docker pull command to pull the latest version of the base image and rebuild the Docker image.

You can scan the Docker image for vulnerabilities using a tool such as Clair or Trivy. These tools analyze the image for known vulnerabilities and provide a report of the findings.

Here is an example of scanning a Docker image using Trivy:

$ trivy image <image-name>

Monitoring and managing the Docker containers

To monitor and manage the Docker containers, you can use tools such as Prometheus, Grafana, and Docker Swarm.

Prometheus is a monitoring tool that collects metrics from the Docker containers and stores them in a time-series database. Grafana is a visualization tool that displays the metrics in dashboards.

Docker Swarm provides features such as service discovery, load balancing, and rolling updates to manage the containers in a production environment. You can use the docker service command to manage the containers in a Docker Swarm cluster.

Here is an example of managing a Docker service using Docker Swarm:

$ docker service ls
$ docker service scale <service-name>=<replicas>
$ docker service update - image <image-name> <service-name>

Secrets management in Docker

To manage secrets in Docker, you can use Docker secrets or a third-party tool such as HashiCorp Vault.

Docker secrets allow you to store sensitive information such as passwords, API keys, and certificates securely. You can create a secret using the docker secret create command and use it in a Docker service.

Here is an example of creating a secret in Docker:

$ echo "password" | docker secret create <secret-name> -

You can set a file as a secret using the docker secret create command:

$ docker secret create <secret-name> ./file.txt

Scaling the Docker containers

To scale the Docker containers, you can use a container orchestration tool such as Kubernetes or Docker Swarm.

Kubernetes provides features such as auto-scaling, rolling updates, and service discovery to manage the containers in a production environment. You can use the kubectl scale command to scale the containers in a Kubernetes cluster.

Docker Swarm provides features such as service discovery, load balancing, and rolling updates to manage the containers in a production environment. You can use the docker service scale command to scale the containers in a Docker Swarm cluster.

Here is an example of scaling a Docker service using Docker Swarm:

$ docker service scale <service-name>=<replicas>

Updating the Docker containers

To update the Docker containers, you can use a container orchestration tool such as Kubernetes or Docker Swarm.

Kubernetes provides features such as rolling updates, blue-green deployments, and canary releases to update the containers in a production environment. You can use the kubectl set image command to update the containers in a Kubernetes cluster.

Docker Swarm provides features such as rolling updates, service discovery, and load balancing to update the containers in a production environment. You can use the docker service update command to update the containers in a Docker Swarm cluster.

Here is an example of updating a Docker service using Docker Swarm:

$ docker service update - image <image-name> <service-name>

Or you can update the image’s port:

$ docker service update - publish-add <host-port>:<container-port> <service-name>

Troubleshooting common issues

To troubleshoot common issues with Docker, you can use tools such as Docker logs, Docker events, and Docker inspect.

Docker logs allow you to view the logs of a Docker container. You can use the docker logs command to view the logs of a container.

Docker events allow you to view the events of a Docker container. You can use the docker events command to view the events of a container.

Docker inspect allows you to view the details of a Docker container. You can use the docker inspect command to view the details of a container.

Here is an example of viewing the logs of a Docker container:

$ docker logs <container-id>

Here is an example of viewing the events of a Docker container:

$ docker events <container-id>

Here is an example of viewing the details of a Docker container:

$ docker inspect <container-id>

Best practices for using Docker in a development environment

To use Docker in a development environment, you can follow best practices such as using a Dockerfile, using Docker Compose, and using multi-stage builds.

You can use a Dockerfile to define the instructions for building the Docker image. The Dockerfile contains the base image, dependencies, and commands to run the application.

You can use Docker Compose to define a multi-container application in a single file. Docker Compose allows you to define the services, networks, and volumes for your application.

You can use multi-stage builds to optimize the Docker image for production. Multi-stage builds allow you to use multiple FROM instructions in a single Dockerfile to keep the final image small.

Conclusion

In this story, I showed you how to use Docker to create a complete development environment for a project.

I hope this story helps you get started with Docker and create a complete development environment for your project.

References

--

--