Skip to main content

Working with Containers and Orchestration

1. Running Nginx in Docker

Example: Basic Nginx Container

docker run --name my-nginx -d -p 8080:80 nginx:latest
Option Values Description
--name my-nginx Name of the container
-d true Run in detached mode
-p 8080:80 Map host port 8080 to container port 80
nginx:latest nginx:latest Docker image to use
Note: The container will start Nginx and serve the default page on http://localhost:8080.

Example: Custom Nginx Configuration

docker run --name custom-nginx -d -p 8080:80 -v /host/nginx.conf:/etc/nginx/nginx.conf nginx:latest
Option Values Description
-v /host/nginx.conf:/etc/nginx/nginx.conf Mount custom config file to container
Warning: Ensure the custom config file has proper permissions and syntax to avoid container startup issues.

2. Creating Custom Nginx Image

Example: Basic Dockerfile for Nginx

FROM nginx:latest
COPY ./html /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Directive Description Usage
FROM Sets base image for the build FROM nginx:latest
COPY Copies files from host to container COPY ./html /usr/share/nginx/html
EXPOSE Documents ports to be published EXPOSE 80
CMD Specifies default command to run CMD ["nginx", "-g", "daemon off;"]
Note: The daemon off; directive is required to keep the Nginx process running in the container.

Example: Multi-stage Build for Nginx

# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Final stage
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

3. Mounting Configuration

Directive Description Example
location Defines how to handle requests based on the URI
location / {
    root /var/www;
}
root Specifies the root directory for resolving the URI root /var/www;
alias Replaces the matched location with a new path
location /images/ {
    alias /var/www/images/;
}

Example: Mounting Configuration in Docker

docker run -d \
  --name nginx-container \
  -v /host/nginx.conf:/etc/nginx/nginx.conf \
  -v /host/html:/usr/share/nginx/html \
  nginx:latest
Note: Ensure proper file permissions and paths when mounting configuration files in containerized environments.

4. Using Environment Variables

Variable Description Default Value Usage
NGINX_PORT Port to listen on for HTTP requests 80 Set via env in Docker or Kubernetes
NGINX_SSL_PORT Port to listen on for HTTPS requests 443 Used when SSL is enabled in config
NGINX_WORKER_PROCESSES Number of worker processes to spawn auto Can be set to 1, auto, or a specific number
NGINX_WORKER_CONNECTIONS Max number of connections per worker 768 Adjust based on server capacity and expected load

Example: Setting Environment Variables in Docker

docker run -e NGINX_PORT=8080 -e NGINX_SSL_PORT=8443 nginx:latest

Example: Using Environment Variables in Nginx Config

server {
    listen ${NGINX_PORT};
    root /usr/share/nginx/html;

    location / {
        try_files $uri $uri/ =404;
    }
}

5. Configuring Health Checks

Directive Description Values Notes
health_check Enables health checks for upstream servers on | off Default: off
health_check_interval Interval between health checks Time value (e.g., 5s, 1m) Default: 5s
health_check_timeout Timeout for health check requests Time value (e.g., 1s, 30s) Default: 1s
health_check_port Port to send health check requests to Integer (e.g., 80, 8080) Default: 80
health_check_path Path to send health check requests to String (e.g., /health) Default: /
health_check_expect Expected response status code Integer (e.g., 200, 204) Default: 200

Example: Basic Health Check Configuration

upstream backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;

    health_check;
}

server {
    listen 80;

    location / {
        proxy_pass http://backend;
    }
}

Example: Advanced Health Check with Custom Path and Timeout

upstream api {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;

    health_check interval=10s timeout=5s port=3000 path=/health expect=200;
}

server {
    listen 80;

    location /api {
        proxy_pass http://api;
    }
}
Note: Health checks are supported in Nginx Plus only. For open-source Nginx, alternative methods like external monitoring tools or custom scripts must be used.

6. Deploying on Kubernetes

Property Description Example
nginx.ingress.kubernetes.io/rewrite-target Specifies the target path for URL rewrites /
nginx.ingress.kubernetes.io/proxy-body-size Sets the maximum allowed body size of the client request 10m
nginx.ingress.kubernetes.io/ssl-redirect Enforces HTTPS redirect for all HTTP requests true

Example: Ingress Configuration

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

Example: Service Configuration

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
Note: Ensure that the Nginx Ingress Controller is installed in your Kubernetes cluster before deploying these configurations.

7. Using Nginx Ingress Controller

The Nginx Ingress Controller is a Kubernetes controller that manages external access to services in a cluster, typically using HTTP and HTTPS routes. It acts as a reverse proxy and load balancer, routing traffic to the appropriate backend services.

Property Description Default Value Notes
controller.image.repository Repository for the Nginx Ingress Controller image nginx/nginx-ingress
controller.image.tag Tag for the Nginx Ingress Controller image 2.4.0 Latest stable version as of 2026
controller.service.type Kubernetes service type to expose the controller LoadBalancer Can be NodePort or ClusterIP
controller.config.client-max-body-size Maximum allowed body size of client request 1m Can be adjusted for larger uploads

Example: Basic Ingress Configuration

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

Example: Ingress with TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-tls-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
    - example.com
    secretName: example-tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 443
Note: Ensure that the TLS secret is created in the same namespace as the Ingress resource.

Key Features

  • Supports HTTP and HTTPS routing
  • Provides SSL/TLS termination
  • Supports path-based and host-based routing
  • Can be configured with custom annotations for advanced features

8. Configuring ConfigMaps

Property Value Description
configMap.name nginx-config Name of the ConfigMap resource in Kubernetes
configMap.key nginx.conf Key within the ConfigMap that holds the Nginx config
configMap.data { "nginx.conf": "events { ... } http { ... }" } Configuration data stored in the ConfigMap

Example: Mounting ConfigMap in Nginx Deployment

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {
      worker_connections 1024;
    }
    http {
      server {
        listen 80;
        location / {
          return 200 'Hello from Nginx!';
        }
      }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: config-volume
        configMap:
          name: nginx-config
Note: Ensure the ConfigMap key matches the expected file name in your Nginx container (e.g., nginx.conf).
Warning: Changes to ConfigMaps do not automatically update running pods. You must restart the pods or use a rolling update strategy to apply changes.

9. Implementing Rolling Updates

Example: Nginx Config for Rolling Updates

# Define upstream with multiple servers
upstream backend {
    server 10.0.1.10:8080 weight=1;
    server 10.0.1.11:8080 weight=1;
    server 10.0.1.12:8080 weight=1;
}

# Main server block
server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
Directive Description Values Notes
upstream Defines a group of servers backend Used for load balancing
server Defines a server in the upstream group 10.0.1.10:8080 Can include weight, max_fails, fail_timeout
proxy_pass Specifies the address of the proxy server http://backend Can be a URL or named location
Note: For rolling updates, ensure that the upstream servers are updated in a way that does not disrupt ongoing requests.
Warning: If servers are replaced without proper handling, it may cause downtime or request loss.

Rolling Update Strategy

  • Update one server at a time
  • Ensure health checks are in place
  • Use weighted load balancing to control traffic distribution

10. Setting Resource Limits

Directive Description Values Notes
limit_req Rate limiting for requests zone=name; rate=rate Defines a rate limit zone and rate
limit_req_zone Defines a rate limit zone key=string; zone=name:size; rate=rate Configures a zone for rate limiting
limit_conn Connection limiting zone=name; conn=number Limits concurrent connections per zone
limit_conn_zone Defines a zone for connection limits key=string; zone=name:size Configures a zone for connection limits

Example: Rate Limiting Configuration

http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s;

    server {
        listen 80;
        location /api/ {
            limit_req zone=api burst=5 nodelay;
            proxy_pass http://backend;
        }
    }
}

Example: Connection Limiting Configuration

http {
    limit_conn_zone $binary_remote_addr zone=conn:10m;

    server {
        listen 80;
        location / {
            limit_conn conn 10;
            proxy_pass http://backend;
        }
    }
}

11. Using Nginx in Docker Compose

Example: Basic Nginx Docker Compose Setup

version: '3.8'
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./html:/usr/share/nginx/html
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
Property Description Values
image Base image to use for the Nginx container nginx:latest
ports Port mapping from host to container "80:80"
volumes Mounts local directories or files into the container ./nginx.conf:/etc/nginx/nginx.conf
networks Networks the service connects to app-network
Note: Ensure nginx.conf exists in the project directory or Docker will fail to start.

Example: Nginx with Reverse Proxy Configuration

version: '3.8'
services:
  nginx:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - api
      - frontend

  api:
    image: node:alpine
    command: npm start
    working_dir: /app
    volumes:
      - ./api:/app
    ports:
      - "3000:3000"

  frontend:
    image: node:alpine
    command: npm run build
    working_dir: /app
    volumes:
      - ./frontend:/app
    ports:
      - "4200:4200"

Key Points for Nginx in Docker Compose

  • Use nginx:latest or a specific version tag for stability.
  • Map port 80:80 to expose Nginx on the host.
  • Mount custom config files or HTML content using volumes.
  • Use depends_on to ensure dependent services are up before Nginx.
  • Define custom networks for better service isolation and communication.

12. Implementing Sidecar Patterns

Pattern Description Use Case Example
Log Aggregation Sidecar Separate container for collecting logs from the main application Centralized logging in microservices
container {
  image: "app:latest"
  ...
}
container {
  image: "fluentd:latest"
  ...
}
Service Discovery Sidecar Container that handles service discovery and registration Dynamic service registration in orchestration platforms
container {
  image: "consul:latest"
  ...
}
Proxy Sidecar Container that acts as a reverse proxy or load balancer Handling traffic routing and TLS termination
container {
  image: "nginx:latest"
  ...
}

Example: Sidecar Configuration in Kubernetes

apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
  - name: main-app
    image: myapp:latest
    ports:
    - containerPort: 8080
  - name: sidecar-logger
    image: fluentd:latest
    volumeMounts:
    - name: logs
      mountPath: /var/log/app
  volumes:
  - name: logs
    emptyDir: {}
Note: Sidecar containers share the same network namespace and can communicate via localhost.

Sidecar Benefits

  • Decouples application logic from infrastructure concerns
  • Enables reuse of common functionality across services
  • Supports dynamic configuration changes without restarting main app

Was this article helpful?