# How to Set Up Custom SSL Certificates in the Nginx Reverse Proxy for HTTPS on LMForge

> Secure your LMForge deployment with custom SSL certificates on Nginx reverse proxy. Learn how to enable HTTPS by mounting certificates and configuring nginx.conf for secure connections.

- Repository: [Haohao/lmforge-end-to-end-llmops-platform-for-multi-model-agents](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Mount your certificate and key into the `llmops-nginx` container, expose port 443 in [`docker-compose.yaml`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker-compose.yaml), and add an SSL server block to [`nginx.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/nginx.conf) to enable HTTPS termination.**

The LMForge platform provides an end-to-end LLMOps environment for multi-model agents, with the `llmops-nginx` service acting as the primary reverse proxy for the UI and API services. By default, this Nginx container only listens on port 80, but you can configure custom SSL certificates to secure communications over HTTPS by updating the volume mounts and configuration files in the repository.

## Prepare the SSL Certificate Files

Before modifying the container configuration, you must obtain the certificate files and place them in the correct directory structure within the repository.

### Obtain and Place Certificates

Acquire a certificate file (`fullchain.pem`) and its corresponding private key (`privkey.pem`) from a trusted Certificate Authority such as Let’s Encrypt, or generate a self-signed pair for internal testing. Place these files inside `docker/nginx/certs/` so they can be mounted into the container at runtime.

### Security Considerations

**Never commit the private key to version control.** Add the certificates directory to your `.gitignore` file to prevent accidental exposure:

```gitignore
docker/nginx/certs/*

```

## Mount Certificates and Expose HTTPS Port

Update the `llmops-nginx` service definition in [`docker/docker-compose.yaml`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/docker-compose.yaml) to bind-mount the certificates directory and expose port 443.

Add the volume mount for the certificates and the port mapping:

```yaml
llmops-nginx:
  image: nginx:latest
  restart: always
  container_name: llmops-nginx
  volumes:
    - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    - ./nginx/proxy.conf:/etc/nginx/proxy.conf
    - ./nginx/conf.d:/etc/nginx/conf.d
    - ./nginx/certs:/etc/nginx/certs   # Mount SSL certificates

  depends_on:
    - llmops-ui
    - llmops-api
  ports:
    - "80:80"
    - "443:443"                         # Expose HTTPS port

```

## Configure the HTTPS Server Block in Nginx

Edit [`docker/nginx/nginx.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/nginx.conf) to add a new server block that listens on port 443 with SSL enabled, pointing to the mounted certificate files.

Add the following server block within the `http` context, typically after the existing port 80 configuration:

```nginx
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    include /etc/nginx/conf.d/*.conf;

    # HTTPS reverse-proxy configuration

    server {
        listen 443 ssl http2;
        server_name _;

        # SSL certificate paths (mounted from ./nginx/certs)

        ssl_certificate     /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        # Modern TLS configuration

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # Proxy to UI service

        location / {
            proxy_pass http://llmops-ui:3000;
            include /etc/nginx/proxy.conf;
        }

        # Proxy to API service

        location /api/ {
            proxy_pass http://llmops-api:5001;
            include /etc/nginx/proxy.conf;
        }
    }
}

```

### SSL Security Settings

The configuration above enforces **TLS 1.2 and TLS 1.3** only, disables weak ciphers, and prefers server ciphers for stronger security posture. These settings align with modern best practices for securing LLM operations platforms.

### Proxy Configuration

The `include /etc/nginx/proxy.conf` directive references the shared proxy headers file located at [`docker/nginx/proxy.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/proxy.conf), ensuring consistent header forwarding for both HTTP and HTTPS traffic.

## Optional HTTP-to-HTTPS Redirect

To force all traffic to HTTPS, modify the existing port 80 server block to return a permanent redirect:

```nginx
server {
    listen 80;
    server_name _;
    return 301 https://$host$request_uri;
}

```

Place this block before or alongside the HTTPS server block in [`docker/nginx/nginx.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/nginx.conf).

## Restart and Verify

Apply the configuration changes by rebuilding and restarting the Nginx container:

```bash
docker compose up -d --build llmops-nginx

```

Verify HTTPS functionality by accessing `https://<your-domain>` and confirming the certificate is valid in your browser. Check container logs with `docker logs llmops-nginx` if connections fail.

## Summary

- **Store certificates** in `docker/nginx/certs/` and exclude them from Git to protect private keys.
- **Mount the certs directory** into `/etc/nginx/certs` via [`docker-compose.yaml`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker-compose.yaml) and expose port 443.
- **Configure SSL** in [`docker/nginx/nginx.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/nginx.conf) with `listen 443 ssl http2`, specifying `ssl_certificate` and `ssl_certificate_key` paths.
- **Proxy traffic** to `llmops-ui:3000` and `llmops-api:5001` using the shared [`proxy.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/proxy.conf) settings.
- **Redirect HTTP to HTTPS** optionally by returning 301 from the port 80 server block.

## Frequently Asked Questions

### Where do I place my SSL certificates in the LMForge repository?

Place your `fullchain.pem` and `privkey.pem` files inside the `docker/nginx/certs/` directory. This location is bind-mounted to `/etc/nginx/certs` inside the `llmops-nginx` container, allowing Nginx to read the certificates at runtime.

### Can I use Let's Encrypt certificates with this Nginx setup?

Yes. Obtain your certificates using Certbot or another ACME client, then copy the resulting `fullchain.pem` and `privkey.pem` (or `privkey.pem` symlinked from `/etc/letsencrypt`) into `docker/nginx/certs/`. Ensure you set up a renewal hook to restart the container when certificates update, or mount the live Let's Encrypt directory directly if running Nginx on the host.

### How do I redirect all HTTP traffic to HTTPS?

Add a `return 301` directive to the existing port 80 server block in [`docker/nginx/nginx.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/nginx.conf). The directive `return 301 https://$host$request_uri;` forces browsers to permanently redirect all HTTP requests to the HTTPS endpoint before reaching the application backend.

### What file controls the proxy headers for HTTPS connections?

The [`docker/nginx/proxy.conf`](https://github.com/haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents/blob/main/docker/nginx/proxy.conf) file contains the common proxy header settings. Both the HTTP and HTTPS server blocks include this file via `include /etc/nginx/proxy.conf;`, ensuring consistent `X-Forwarded-For`, `X-Forwarded-Proto`, and other headers regardless of the protocol used.