Working with Containers and Orchestration
1. Running Nginx in Docker
| 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 | |
| root | Specifies the root directory for resolving the URI | root /var/www; |
| alias | Replaces the matched location with a new path | |
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:latestor a specific version tag for stability. - Map port
80:80to expose Nginx on the host. - Mount custom config files or HTML content using
volumes. - Use
depends_onto 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 | |
| Service Discovery Sidecar | Container that handles service discovery and registration | Dynamic service registration in orchestration platforms | |
| Proxy Sidecar | Container that acts as a reverse proxy or load balancer | Handling traffic routing and TLS termination | |
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.