Containerization
Docker (build, run, volumes, networks, compose)
Basic Commands
docker ps
- List running containersdocker ps -a
- List all containersdocker info
- Get Docker configurationdocker version
- Get Docker version
Image Commands
docker build -t <image>:<tag> .
- Build an image from a Dockerfiledocker login <repository>
- Authenticate with a remote repositorydocker push <image>:<tag>
- Push an image to a repositorydocker pull <image>:<tag>
-Pull an image from a repositorydocker images
- List locally available imagesdocker create <image>:<tag>
- Create a container from an imagedocker rmi <image>
- Delete an imagedocker save <image>
- Save an image as a tarballdocker search <image>
- Search for an image in a repository
Container Commands
docker inspect <container>
- View container detailsdocker stats <container>
- Display live resource usagedocker logs <container>
- View container logsdocker run <container>
- Run a containerdocker kill <container>
- Force stop a running containerdocker start <container>
- Start a stopped containerdocker stop <container>
- Gracefully stop a running containerdocker restart <container>
- Restart a containerdocker rm <container>
- Remove a containerdocker port <container>
- Show port mappingsdocker pause <container>
- Suspend container processesdocker unpause <container>
- Resume container processes
Network Commands
docker network ls
- List networksdocker network inspect <network>
- View network detailsdocker network create <network>
- Create a networkdocker network rm <network>
- Delete a networkdocker network connect <network> <container>
- Connect a container to a networkdocker network disconnect <network> <container>
- Disconnect a container from a network
Volume Commands
docker volume ls
- List volumesdocker volume inspect <volume>
- View volume detailsdocker volume create <volume>
- Create a volumedocker volume rm <volume>
- Delete a volume
Copy & Execution Commands
docker cp <container>:<source_path> <dest_path>
- Copy from container to hostdocker cp <source_path> <container>:<dest_path>
- Copy from host to containerdocker exec -ti <container> <command>
- Run a command inside a running container
Dockerfile Commands
FROM <image>:<tag>
- Base image for the containerCOPY <source> <destination>
- Copy files/directoriesADD <source> <destination>
- Copy files & extract archivesCMD ["command", "arg1"]
- Default command executed in containerENTRYPOINT ["command", "arg1"]
- Container's main commandLABEL key=value
- Add metadataENV key=value
- Set environment variablesEXPOSE <port>
- Declare exposed portsRUN <command>
- Run command during image buildWORKDIR <path>
- Set working directory
System & Diagnostics
docker system df
- Show Docker disk usagedocker system info
- Display system detailsdocker diff <container>
- Show modified files in a containerdocker top <container>
- Show running processes inside a container
General Best Practices for Dockerfiles:
- Minimize Layers - Combine RUN, COPY, and ADD commands to reduce layers and image size.
- Use Specific Versions - Always specify versions for base images (e.g., FROM python:3.9-slim).
- .dockerignore - Use .dockerignore to exclude unnecessary files (e.g., .git, node_modules).
- Multi-Stage Builds - Separate the build process and runtime environment to optimize image size.
- Non-root User - Always create and use a non-root user for security.
- Leverage Docker Cache - Copy dependencies first, so Docker can cache them for faster builds.
Dockerfile Examples with different Programming language
1. Python (Flask/Django)
FROM python:3.9-slim AS base
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the app files
COPY . .
EXPOSE 5000
# Run as a non-root user
RUN useradd -m appuser
USER appuser
CMD ["python", "app.py"]
Best Practices
- --no-cache-dir to prevent caching Python packages.
- Copy requirements.txt first to leverage Docker cache.
- Use a non-root user (appuser).
2. Node.js
FROM node:16-alpine AS build
WORKDIR /app
# Install dependencies
COPY package.json package-lock.json ./
RUN npm install --production
# Copy the app code
COPY . .
EXPOSE 3000
# Run as a non-root user
RUN addgroup --system app && adduser --system --ingroup app app
USER app
CMD ["node", "app.js"]
Best Practices
- Use --production to avoid installing devDependencies.
- Multi-stage builds for optimized images.
- Use a non-root user (app).
3. Java (Spring Boot)
FROM openjdk:17-jdk-slim AS build
WORKDIR /app
# Copy the jar file
COPY target/myapp.jar myapp.jar
EXPOSE 8080
# Run as a non-root user
RUN addgroup --system app && adduser --system --ingroup app app
USER app
CMD ["java", "-jar", "myapp.jar"]
Best Practices
- Multi-stage builds for separating build and runtime.
- Use -jdk-slim for smaller images.
- Non-root user (app).
4. Ruby on Rails
FROM ruby:3.0-alpine
# Install dependencies
RUN apk add --no-cache build-base
WORKDIR /app
# Install Ruby gems
COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test
# Copy the app code
COPY . .
EXPOSE 3000
# Run as a non-root user
RUN addgroup --system app && adduser --system --ingroup app app
USER app
CMD ["rails", "server", "-b", "0.0.0.0"]
Best Practices
- Install dependencies in one RUN statement.
- Avoid devDependencies in production.
- Use non-root user (app).
5. Go
FROM golang:1.16-alpine AS build
WORKDIR /app
# Copy and install dependencies
COPY go.mod go.sum ./
RUN go mod tidy
# Copy the app code and build
COPY . .
RUN go build -o myapp .
# Use a minimal base image for running
FROM alpine:latest
WORKDIR /app
# Copy the binary
COPY --from=build /app/myapp .
EXPOSE 8080
# Run as a non-root user
RUN addgroup --system app && adduser --system --ingroup app app
USER app
CMD ["./myapp"]
Best Practices
- Multi-stage build to separate build and runtime.
- alpine for smaller runtime images.
- Non-root user (app).
6. Angular (Frontend)
# Build stage
FROM node:16 AS build
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build --prod
# Production stage using nginx
FROM nginx:alpine
## # Copy build artifacts from the build stage
COPY --from=build /app/dist/ /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Best Practices
- Multi-stage build: separate build and serving phases.
- Use nginx:alpine for a minimal serving environment.
- Copy only production build files.
7. PHP (Laravel)
FROM php:8.0-fpm
# Install dependencies
RUN apt-get update && apt-get install -y libzip-dev && docker-php-ext-install zip
WORKDIR /var/www/html
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Install PHP dependencies
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts
# Copy application files
COPY . .
EXPOSE 9000
# Run as a non-root user
RUN useradd -ms /bin/ appuser
USER appuser
CMD ["php-fpm"]
Best Practices
- Use Composer for PHP dependency management.
- Avoid dev dependencies in production (--no-dev).
- Run PHP-FPM as a non-root user.
8. Best Practices for Security and Optimization:
- Minimize Image Size - Use smaller base images like alpine or slim, and multi-stage builds to reduce the final image size.
- Use a Non-root User - Always run applications as a non-root user to enhance security.
- Pin Versions - Avoid using the latest tag for images. Use specific versions to ensure predictable builds.
- Leverage Caching - Place frequently changing files (e.g., source code) after dependencies to take advantage of Docker's build cache.
- Avoid ADD Unless Necessary - Use COPY instead of ADD unless you need to fetch files from a URL or extract archives.
Docker Compose Commands
docker-compose up
- Start all services in the backgrounddocker-compose up -d
- Start services in detached modedocker-compose up --build
- Rebuild images before starting servicesdocker-compose down
- Stop and remove containers, networks, volumesdocker-compose down -v
- Remove volumes along with containersdocker-compose stop
- Stop running containers without removing themdocker-compose start
- Restart stopped containersdocker-compose restart
- Restart all containersdocker-compose ps
- List running containersdocker-compose logs
- Show logs from containersdocker-compose logs -f
- Follow container logsdocker-compose exec <service> <cmd>
- Execute a command inside a running containerdocker-compose run <service> <cmd>
- Run a one-time command inside a servicedocker-compose config
- Validate and view merged configurationdocker-compose version
- Show Docker Compose version
Docker Compose (docker-compose.yml) Example
version: '3.8'
services:
app:
image: my-app:latest
container_name: my_app
ports:
- "8080:80"
environment:
- NODE_ENV=production
volumes:
- ./app:/usr/src/app
depends_on:
- db
db:
image: postgres:latest
container_name: my_db
restart: always
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydatabase
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Key Directives
- version - Defines the Compose file format version
- services - Defines all application services
- image - Specifies the container image
- container_name - Names the container explicitly
- build - Specifies build context for Dockerfile
- ports - Maps container ports to host
- volumes - Mounts persistent storage
- environment - Passes environment variables
- depends_on - Specifies dependencies between services
- restart - Defines restart policy (always, unless-stopped, on-failure)
General Docker Compose Structure
version: '3'
services:
service_name:
image: <image-name> # The image to use
build: . # Path to the Dockerfile if you need to build the image
container_name: <name> # Container name (optional)
ports:
- "<host-port>:<container-port>" # Exposing ports
environment:
- VAR_NAME=value # Set environment variables
volumes:
- <host-path>:<container-path> # Mount volumes for persistent data
depends_on: - other_service # Define service dependencies
networks: - <network-name> # Assign the service to a network
Docker Compose Example Configurations
1. Python (Flask) + Redis Example:
version: '3'
services:
web:
build: ./app
ports:
- "5000:5000"
environment:
- FLASK_APP=app.py
- FLASK_ENV=development
volumes:
- ./app:/app
networks:
- app_network
redis:
image: "redis:alpine"
networks:
- app_network
networks:
app_network:
driver: bridge
2. Node.js (Express) + MongoDB Example:
version: '3'
services:
app:
build: ./node-app
ports:
- "3000:3000"
environment:
- MONGO_URI=mongodb://mongo:27017/mydb
depends_on:
- mongo
networks:
- backend
mongo:
image: mongo:latest
volumes:
- mongo_data:/data/db
networks:
- backend
networks:
backend:
driver: bridge
volumes:
mongo_data:
3. Nginx + PHP (Laravel) Example:
version: '3'
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
ports:
- "8080:80"
depends_on:
- php
networks:
- frontend
php:
image: php:8.0-fpm
volumes:
- ./html:/var/www/html
networks:
- frontend
networks:
frontend:
driver: bridge
Best Practices
- Use Versioning - Always specify a version for Docker Compose files (e.g., version: '3')
- Define Volumes - Use named volumes for persistent data (e.g., database storage)
- Environment Variables - Use environment variables for configuration (e.g., database connection strings)
- Use depends_on - Ensure proper start order for dependent services
- Custom Networks - Use custom networks for better service communication management
- Avoid latest Tag - Always use specific version tags for predictable builds
Advanced Options
Build Arguments:
- Pass information during the image build process
Health Checks:
- Add health checks to monitor service status
services:
web:
image: my-web-app
healthcheck:
test: ["CMD", "curl", "-f", ["http://localhost/health"](http://localhost/health)]
interval: 30s
retries: 3
Scaling Services:
- Scale services using the command