Docker: Image Creation, Management, and Registry
Tags: docker, kubernetes, devops, beginners
Published: 2023-06-25 22:29:57

## Docker Images
A Docker image is a self-contained bundle that includes all the necessary software required to run a container. It serves as an executable package, encapsulating the application code, dependencies, and system libraries, ensuring consistency and portability across different environments.

Run a container using an image:

```
 docker run <IMAGE>
```
Download an image:

```
 docker pull <IMAGE>
 docker image pull <IMAGE>
```
Docker utilizes a layered file system for its images and containers. Each layer within the file system contains only the modifications and differences from the preceding layer, allowing for efficient storage and sharing of resources. 
View file system layers in an image: 

```
 docker image history <IMAGE>
```

## The Components of a Dockerfile
A Dockerfile is a file that provides instructions for building a Docker image. It contains a series of directives that define the steps and configuration needed to create the image.

An example of Dockerfile:

```
# Use the official Nginx base image
FROM nginx:latest

# Set an environment variable
ENV MY_VAR=my_value

# Copy custom configuration file to container
COPY nginx.conf /etc/nginx/nginx.conf

# Run some commands during the build process
RUN apt-get update && apt-get install -y curl

# Expose port 80 for incoming traffic
EXPOSE 80

# Start Nginx server when the container starts
CMD ["nginx", "-g", "daemon off;"]

```
Build an image:

```
 docker build -t TAG_NAME DOCKERFILE_LOCATION
```

Dockerfile directives:

- **FROM:** Specifies the base image to use for the Docker image being built. It defines the starting point for the image and can be any valid image available on Docker Hub or a private registry.
- **ENV:** Sets environment variables within the image. These variables are accessible during the build process and when the container is running.
- **COPY or ADD:** Copies files and directories from the build context (the directory where the Dockerfile is located) into the image. COPY is generally preferred for simple file copying, while ADD supports additional features such as unpacking archives.
- RUN: Executes commands during the build process. You can use RUN to install dependencies, run scripts, or perform any other necessary tasks.
- **EXPOSE:** Informs Docker that the container will listen on the specified network ports at runtime. It does not actually publish the ports to the host machine or make the container accessible from outside.
- **CMD or ENTRYPOINT:** Specifies the command to run when a container is started from the image. CMD provides default arguments that can be overridden, while ENTRYPOINT specifies a command that cannot be overridden.
- **WORKDIR:** Sets the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY, or ADD instructions.
- **STOPSIGNAL:** Sets a custom signal that will be used to stop the container process.
- **HEALTHCHECK:** Sets a command that will be used by the Docker daemon to check whether the container is healthy

A multi-stage build in a Dockerfile is a technique used to create more efficient and smaller Docker images. It involves defining multiple stages within the Dockerfile, each with its own set of instructions and dependencies.

An example Dockerfile containing multi-stage build defination:
```
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app

# Copy and restore project dependencies
COPY *.csproj .
RUN dotnet restore

# Copy the entire project and build
COPY . .
RUN dotnet build -c Release --no-restore

# Publish the application
RUN dotnet publish -c Release -o /app/publish --no-restore

# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .

# Expose the required port
EXPOSE 80

# Set the entry point for the application
ENTRYPOINT ["dotnet", "YourApplication.dll"]
```

## Managing images

Some key commands for image management are:

List images on the system:

```
docker image ls
```
List images on the system including intermediate images:

```
docker image ls -a
```
Get detailed information about an image:

```
docker image inspect <IMAGE>
```
Delete an image:

```
docker rmi <IMAGE>
docker image rm <IMAGE>
docker image rm -f <IMAGE>
```
An image can only face deletion if no containers or other image tags reference it. But force deletion of an image, even if gets referenced by something else. 
Find and delete dangling or unused images:

```
docker image prune
```

## Docker registries
Docker Registry serves as a centralized repository for storing and sharing Docker images. Docker Hub is the default, publicly available registry managed by Docker.
By utilizing the registry image, we have the ability to set up and manage our own private registry at no cost.

Run a simple registry:

```
docker run -d -p 5000:5000 --restart=always --name registry registry:2
```
Upload an image to a registry:

```
docker push <IMAGE>:<TAG>
```

Download an image from a registry:

```
docker pull <IMAGE>:<TAG>
```

Login to a registry:

```
docker login REGISTRY_URL
```
There are two authentication methods for connecting to a private registry with an untrusted or self-signed certificate:

- **Secure:** This involves adding the registry's public certificate to the /etc/docker/certs.d/<registry public hostname> directory.
- **Insecure:** This method entails adding the registry to the insecure-registries list in the daemon.json file or passing it to dockerd using the --insecure-registry flag.

By leveraging the power of Docker, developers and organizations can streamline application deployment, improve scalability, and enhance overall software development processes. With the knowledge gained from this comprehensive overview, you're well-equipped to harness the full potential of Docker images and drive innovation in your containerized workflows.