# Working With Dockerfiles and Images ## 1. Understanding Dockerfiles A Dockerfile is a text file containing instructions to build a Docker image. It automates the process of creating a consistent environment for your application. Key Dockerfile instructions: - FROM: Specifies the base image - RUN: Executes commands in the container - COPY/ADD: Copies files from host to container - WORKDIR: Sets the working directory - ENV: Sets environment variables - EXPOSE: Declares ports to be exposed - CMD/ENTRYPOINT: Specifies the command to run when the container starts ## 2. Creating a Dockerfile Example Dockerfile for a Python application: ```dockerfile FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000 CMD ["python", "app.py"] ``` ## 3. Building Docker Images To build an image from a Dockerfile: `docker build -t myapp:v1 .` This command builds an image named "myapp" with the tag "v1" using the Dockerfile in the current directory. ## 4. Managing Docker Images List images: `docker images` Remove an image: `docker rmi myapp:v1` Tag an image: `docker tag myapp:v1 myapp:latest` ## 5. Pushing and Pulling Images Push an image to a registry: `docker push username/myapp:v1` Pull an image from a registry: `docker pull username/myapp:v1` ## 6. Multi-stage Builds Multi-stage builds allow you to use multiple FROM statements in your Dockerfile. This is useful for creating smaller production images: ```dockerfile # Build stage FROM golang:1.16 AS builder WORKDIR /app COPY . . RUN go build -o myapp # Production stage FROM alpine:3.14 COPY --from=builder /app/myapp /usr/local/bin/ CMD ["myapp"] ``` ## 7. Best Practices - Use specific base image tags (e.g., python:3.9-slim instead of python:latest) - Minimize the number of layers by combining RUN commands - Use .dockerignore to exclude unnecessary files - Set appropriate permissions for files and directories - Use environment variables for configuration - Don't run containers as root unless necessary ## 8. Docker Image Inspection Inspect image details: `docker inspect myapp:v1` View image history: `docker history myapp:v1` ## 9. Optimizing Docker Images - Use smaller base images when possible (e.g., alpine-based images) - Remove unnecessary dependencies and files - Use multi-stage builds to separate build and runtime environments - Leverage build cache by ordering Dockerfile instructions efficiently ## 10. Working with Docker Registries - Docker Hub: Public and private repositories - Amazon Elastic Container Registry (ECR) - Google Container Registry (GCR) - Azure Container Registry (ACR) To use a private registry, log in first: `docker login myregistry.azurecr.io` ## 11. Image Scanning and Security Use tools like Docker Scan, Clair, or Trivy to scan images for vulnerabilities: `docker scan myapp:v1` ## 12. Docker Image Versioning Use semantic versioning for your images: - Major version: myapp:1 - Minor version: myapp:1.2 - Patch version: myapp:1.2.3 Always tag your images with a specific version and avoid using only the "latest" tag in production. ## 13. Dockerfile Linting Use tools like Hadolint to check your Dockerfile for best practices and potential issues: `hadolint Dockerfile` This guide covers the essentials of working with Dockerfiles and images. As you become more comfortable with these concepts, you can explore advanced topics like Docker Compose for multi-container applications and Docker Swarm or Kubernetes for container orchestration.