Getting Started with Docker
Published: 2024-01-26 06:55:39

In this article, you will learn about Docker, its main principles, benefits and usage.

### Overview of Docker

Docker is an open-source platform for simplifying application development, deployment, and management using containers.

Docker Containers are lightweight and portable packages containing an application's code, dependencies, and configuration. They run in isolation, ensuring consistent execution across environments.

Why use Docker?

#### Portability 
Docker containers can be used to run the same application on different machines without any modifications, which makes it easier to move applications between development, testing and production environments.

#### Isolation 
Docker containers are isolated in nature, each container runs in its isolated environment with its own file system, network protocol and process space, and this provides a level of security and isolation. This solves the problem of conflict with other applications or dependencies.

#### Scalability
Docker containers are easily scalable, meaning that one can easily scale the containers that are running the applications by horizontally adding more containers with them when demand increases.

#### Efficiency 
Docker containers are efficient, meaning that containers are lightweight, and consume fewer resources, which means more containers can easily run on the same underlying hardware.

### Docker Images

Docker images are made up of multiple layers and each layer adds something specific to the final image, making it more efficient and reusable. For example, one layer might contain the base operating system, another will install your application's dependencies and a third might add your application code.

###Dockerfile

Dockerfile is a file that contains instructions for what to include in an image, from base operating systems to application code and configuration. 

> Commands:

- `FROM` (establishing base image)
- `COPY` (duplicating files from local to the container)
- `ARG` (pass arguments)
- `ENV` (environment variable)
- `RUN` (run a shell command)
- `EXPOSE` (open port from container to virtual network)
- `CMD` (execute a command) 
- `WORKDIR` (sets where copied files should be placed.)

To build an image from the **Dockerfile**, use this command

```bash
docker build <path> 
// docker build .
```

**Good Practice**

- Copy the dependencies 1st and then copy the rest of the files.

```Dockerfile
COPY package.json ./
RUN npm install
COPY . ./
```

### .dockerignore

The .dockerignore is a file used for specifying the files and directories that should not copied when using the `COPY` command. It is similar to .gitignore

### Docker Network

A Docker network allows containers to communicate with each other and with the outside world. It's like a mini-internet for your Docker containers, where they can have their IP addresses and DNS names and talk to each other without interfering with the network on your host machine.

There are different types of Docker networks, each with its purpose:

####Bridge network 
This is the default network that containers are attached to unless you specify otherwise. It's like a shared Wi-Fi network in the building, where all the containers can see and talk to each other.

####Overlay network
This is a more advanced type of network that allows containers to be connected across multiple hosts. It's like a private VPN for the building, where only authorized containers can access each other.

####Macvlan network: 
This type of network gives containers direct access to the host machine's network. It's like giving a tenant in the building a direct phone line to the outside world.

```bash
docker network create <network-name>
```

### Docker Volumes

A Docker volume is a separate filesystem managed by Docker, independent of the container's temporary storage.

Docker volumes offer several benefits:

- Ensures important data survives container restarts and migrations.
- Enables collaboration and data access between multiple containers.
- Simplifies data backups and container deployments.
- Keeps container data separate from the host machine's filesystem.

```bash
docker run -v /path/in/container
```

**Named Volume**
We can also name the volume otherwise it will generate the ID and be hard to track

```bash
docker run -v <volume name>:</path in container> <image name>
docker run -v myvolume:/src/public nginx
```

### Bind Mounting

Bind Mounting is a technique for sharing data between the host machine and a container. In the context of monitoring, it's often used to expose container metrics and logs to an external monitoring tool running on the host.

```bash
docker run -v <path to your local system>:<container path>
docker run -v /app/content:/usr/share/nginx/html  nginx
docker run -v $(pwd):/user/html nginx
```
 In compose, we don't have to give the `pwd`
 
 ```yaml
     volumes:
      - ./:/usr/share/nginx/html:ro
      - ./app:/usr/share/nginx/html/app:ro 
 ```

### Docker Compose

Docker Compose is used for running multi-container Docker applications and configuring relationships between containers. 

```yaml
services:  # containers. same as docker run
  servicename: # a friendly name. this is also the DNS name inside the network
    image: # Optional if you use to build:
    command: # Optional, replace the default CMD specified by the image
    environment: # Optional, same as -e in docker run
    volumes: # Optional, same as -v in docker run
  servicename2:

volumes: # Optional, same as docker volume create

networks: # Optional, same as docker network create
```

Sample:

```yaml
services:
  mongo:
    container_name: mongo
    image: mongo:4.0
    volumes:
      - mongo-db:/data/db
    networks: 
      - my-net
      
volumes:
  mongo-db: # named volume
  
networks:
    my-net:
        driver: bridge
```

If any container depends on another container

```yaml
depends_on:
  - mysql-primary
```

## Docker Swarm

Docker Swarm is an orchestration tool for managing a group of Docker hosts (physical or virtual machines) as a single. It lets you deploy, scale and manage containerized applications across multiple nodes.

Docker Swarm is not enabled by default, here is how to enable it;

```bash
docker swarm init
```

### Docker service

Docker service is the core concept of deploying and managing containerized applications within Docker Swarm. It defines how your application runs across a cluster of Docker hosts.

### Docker Stacks

Docker stacks are the powerhouses of deploying and managing multiple interconnected services within a Docker Swarm cluster.

Here we don't use `build:` object and there is new `deploy:` specific to swarm to like replicas, and secrets.

```yaml
    deploy:
      replicas: 3
```
We deploy stack files with this command

```bash
docker stack deploy -c file.yml <stackname>
```

### Docker Secrets

Docker Swarm supports secrets. Secrets are the guardians of sensitive data like passwords, API keys, database credentials, and other sensitive credentials bits. We can pass ENV variables like SSH keys, Usernames, passwords etc.

We can create Docker secrets though CLI `external:`

```bash
echo "<password text>" | docker secret create psql-pw -
```

or

Create a file with a password and then pass the path in the stack `file:`

```yaml
services:
    postgres:
      image: postgres
      secrets:
        - post-pass
        - post-user
      environment:
          POSTGRES_PASSWORD_FILE: /run/secrets/post-pass
          POSTGRES_USER_FILE: /run/secrets/post-user
      
secrets:
    post-pass:
      external: true
    post-user:
        file: ./post-user.txt
```
### Docker Healthcheck

Docker health checks ensure your containers are running smoothly and performing their tasks as expected, preventing headaches and downtime.

```dockerfile
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
```