Using HAProxy for TLS Termination in a Docker Container

  ·   3 min read

In today’s cloud-native environments, securing communication between clients and servers is paramount. TLS termination is a common practice where the decryption of incoming TLS connections is handled by a load balancer, offloading this task from backend servers. HAProxy, a reliable and high-performance open-source load balancer, is an excellent choice for this task. In this article, we’ll explore how to set up HAProxy for TLS termination using Docker and Docker Compose.

Why HAProxy?

HAProxy is a widely-used open-source software that provides high availability, load balancing, and proxying for TCP and HTTP-based applications. It is known for its reliability, performance, and extensive feature set, making it a popular choice for handling TLS termination.

Setting Up HAProxy in Docker

Running HAProxy in a Docker container allows for easy deployment and management. We’ll use Docker Compose to define and run a multi-container Docker application. Below is a step-by-step guide to setting up HAProxy for TLS termination.

Prerequisites

  • Docker and Docker Compose installed on your system.
  • A domain name with a valid TLS certificate and key. You can obtain a free certificate from Let’s Encrypt.

Directory Structure

Create a directory structure for your HAProxy setup:

haproxy-docker/
├── docker-compose.yml
├── haproxy/
│   ├── haproxy.cfg
│   ├── certs/
│       ├── your_domain.crt
│       └── your_domain.key

Docker Compose File

Create a docker-compose.yml file to define the HAProxy service:

version: '3.8'

services:
  haproxy:
    image: haproxy:latest
    container_name: haproxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
      - ./haproxy/certs:/usr/local/etc/haproxy/certs:ro
    restart: unless-stopped

HAProxy Configuration

Create a haproxy.cfg file with the following content to configure HAProxy for TLS termination:

global
    log stdout format raw local0
    maxconn 4096
    tune.ssl.default-dh-param 2048

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5000ms
    timeout client  50000ms
    timeout server  50000ms

frontend https-in
    bind *:443 ssl crt /usr/local/etc/haproxy/certs/your_domain.pem
    default_backend servers

backend servers
    server server1 127.0.0.1:8080 maxconn 32

Preparing the Certificate

Combine your certificate and key into a single .pem file:

cat your_domain.crt your_domain.key > haproxy/certs/your_domain.pem

Running HAProxy

Navigate to the haproxy-docker directory and start the HAProxy service using Docker Compose:

docker-compose up -d

This command will start the HAProxy container, listening on ports 80 and 443. HAProxy will handle incoming TLS connections, decrypt them, and forward the traffic to the backend server defined in the configuration.

Conclusion

By using HAProxy for TLS termination, you can offload the computational overhead of decrypting TLS traffic from your backend servers, improving performance and simplifying your infrastructure. Running HAProxy in a Docker container provides flexibility and ease of management, making it a great choice for modern DevOps environments.

For further reading and resources, consider exploring the following:

By following this guide, you should have a functional HAProxy setup for TLS termination, ready to secure your web applications.