Skip to content

SSL & Certificate Configuration Guide

This guide covers how to configure SSL/TLS certificates for the Mdlwr application stack depending on your deployment environment (Public Internet with Let's Encrypt vs. Closed Intranet / Internal Network).


Scenario A: Public Internet Deployment (Let's Encrypt via Certbot)

If your server is connected to the public internet and uses a domain with public DNS records, you can use Certbot to generate a free, trusted SSL certificate.

1. Install Certbot on the Host Server

Log in to your VPS/server and install Certbot along with the Nginx plugin:

sudo apt update
sudo apt install certbot python3-certbot-nginx -y

2. Stop Nginx Container Temporarily

Free up port 80 so Certbot can successfully perform the domain ownership challenge:

cd /opt/mdlwr
docker compose stop nginx

3. Generate the SSL Certificate

Run the Certbot command (replace mdlwr.web.id with your actual domain):

sudo certbot certonly --standalone -d mdlwr.web.id
Follow the on-screen prompts to enter your email and agree to the terms.

4. Start the Docker Stack

Bring your containers back up:

cd /opt/mdlwr
docker compose up -d

Let's Encrypt certificates expire every 90 days. Set up a post-renewal hook script to automatically reload Nginx when certificates renew:

sudo mkdir -p /etc/letsencrypt/renewal-hooks/post
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
Add the following content:
#!/bin/bash
docker exec nginx nginx -s reload
Make the script executable:
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

Scenario B: Intranet / Isolated Network Deployment

If your server runs inside an internal corporate network (without internet access), public ACME authorities like Let's Encrypt will not work. Choose one of the following approaches:

  1. Request a Certificate: Ask your internal IT/Security team for an SSL certificate (.crt / .pem and .key) for your domain (e.g., mdlwr.web.id).
  2. Store Files: Create an SSL directory on your server and place the files there:
    sudo mkdir -p /opt/mdlwr/ssl
    # Place mdlwr.web.id.crt and mdlwr.web.id.key inside /opt/mdlwr/ssl/
    
  3. Update docker-compose.yml (Nginx volumes): Replace the Let's Encrypt volume path with your local folder:
    volumes:
      - ${MDLWR_BASE}/ssl:/etc/nginx/ssl:ro
    
  4. Update nginx.conf: Point Nginx to your internal certificate paths:
    ssl_certificate /etc/nginx/ssl/mdlwr.web.id.crt;
    ssl_certificate_key /etc/nginx/ssl/mdlwr.web.id.key;
    
  5. Client Trust: Ensure your company's Root CA is imported into client machines' trusted certificate stores to avoid security warnings.

Option 2: Self-Signed Certificate (Quick Setup for Testing)

If you do not have an internal CA server and need a quick solution:

  1. Generate the Certificate Directly on the Server:
    sudo mkdir -p /opt/mdlwr/ssl
    cd /opt/mdlwr/ssl
    sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
      -keyout mdlwr.web.id.key \
      -out mdlwr.web.id.crt \
      -subj "/C=ID/ST=West Java/L=Bekasi/O=Internal/CN=mdlwr.web.id"
    
  2. Map the Volume in docker-compose.yml:
    volumes:
      - ${MDLWR_BASE}/ssl:/etc/nginx/ssl:ro
    
  3. Configure nginx.conf:
    ssl_certificate /etc/nginx/ssl/mdlwr.web.id.crt;
    ssl_certificate_key /etc/nginx/ssl/mdlwr.web.id.key;
    

    ⚠️ Note on Self-Signed: Browsers will show a "Your connection is not private" warning on the first visit. Users will need to manually click Advanced -> Proceed to site to bypass it.