Install Kiwi TCMS OSS and Apply a Trusted SSL Certificate (Two Options)

Kiwi TCMS is a powerful open-source test management system built on Django and MariaDB. In this guide, we’ll install Kiwi TCMS using Docker on Ubuntu 24.04, enable HTTPS, and configure it to auto-start using systemd.


Prerequisites

  • Ubuntu 24.04 server
  • DNS: kiwi.maksonlee.com managed by Cloudflare
  • Docker + Compose plugin: Install Docker on Ubuntu 24.04
  • Port 443 open (port 80 is not required)

Install required packages:

sudo apt update
sudo apt install -y certbot python3-certbot-dns-cloudflare
sudo add-apt-repository ppa:vbernat/haproxy-3.2 -y
sudo apt-get install haproxy=3.2.\*
sudo systemctl enable --now haproxy

  1. Clone Kiwi TCMS OSS Repository
git clone https://github.com/kiwitcms/Kiwi.git
sudo mv Kiwi /opt/kiwi
cd /opt/kiwi

This gives you the official docker-compose.yml file. Kiwi listens on ports 8080 and 8443 internally and maps them to 80 and 443 by default.


  1. Run Kiwi Initial Setup

Start the container stack:

docker compose up -d

Then run the initialization:

docker exec -it kiwi_web /Kiwi/manage.py initial_setup

You’ll be prompted to:

  • Create the admin user
  • Set the domain (e.g. kiwi.maksonlee.com)
  • Assign default roles

  1. Cloudflare Token & Certbot Credentials
  • Generate Cloudflare Token
    • Go to: Cloudflare API TokensCreate Token
    • Use the “Edit zone DNS” template:
      • Permissions:
        • Zone → DNS → Edit
      • Zone Resources:
        • Include → maksonlee.com
    • Click Create Token, copy the value.
  • Create cloudflare.ini
vi ~/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN

Set strict permissions:

chmod 600 ~/.secrets/certbot/cloudflare.ini

  1. Issue Let’s Encrypt Cert via DNS-01
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d kiwi.maksonlee.com

  1. Apply HTTPS Certificate

You can secure Kiwi TCMS via HTTPS using either of the following options:

Option 1 – Use HAProxy for SSL Termination

In this setup, Kiwi listens on 127.0.0.1:8443, and HAProxy terminates HTTPS at the host level.

  • Limit Kiwi to localhost

Create docker-compose.override.yml:

services:
  web:
    ports: !override
      - "127.0.0.1:8443:8443"

Restart Docker Compose:

docker compose down
docker compose up -d
  • Combine your TLS cert
sudo mkdir -p /etc/haproxy/certs/
sudo bash -c "cat /etc/letsencrypt/live/kiwi.maksonlee.com/fullchain.pem /etc/letsencrypt/live/kiwi.maksonlee.com/privkey.pem > /etc/haproxy/certs/kiwi.maksonlee.com.pem"
sudo chmod 600 /etc/haproxy/certs/kiwi.maksonlee.com.pem
  • Configure HAProxy

Edit /etc/haproxy/haproxy.cfg:

frontend https-in
    bind *:443 ssl crt /etc/haproxy/certs/kiwi.maksonlee.com.pem
    mode http
    default_backend kiwi_backend_https

backend kiwi_backend_https
    mode http
    server kiwi 127.0.0.1:8443 ssl verify none

Reload HAProxy:

sudo systemctl restart haproxy

Option 2 – Mount Certs into the Kiwi Container

This lets Kiwi’s internal NGINX handle HTTPS.

  • Copy and secure your certs
sudo mkdir -p /opt/kiwi/ssl
sudo cp /etc/letsencrypt/live/kiwi.maksonlee.com/fullchain.pem /opt/kiwi/ssl/localhost.crt
sudo cp /etc/letsencrypt/live/kiwi.maksonlee.com/privkey.pem /opt/kiwi/ssl/localhost.key
sudo chmod 644 /opt/kiwi/ssl/localhost.crt
sudo chmod 600 /opt/kiwi/ssl/localhost.key
sudo chown -R $USER:$USER /opt/kiwi
  • Create override:
services:
  web:
    volumes:
      - /opt/kiwi/ssl/localhost.crt:/Kiwi/ssl/localhost.crt:ro
      - /opt/kiwi/ssl/localhost.key:/Kiwi/ssl/localhost.key:ro
  • Restart Kiwi
docker compose down
docker compose up -d

SSL Integration Comparison

FeatureHAProxy (Re-Encrypt)Mounting Certs into Container
Public HTTPS Support✅ Yes✅ Yes
SSL Termination Outside App✅ Clean separation❌ Handled inside container
Requires Container Changes❌ No✅ Yes (bind certs manually)
Auto-updates Compatible✅ Yes⚠️ Must remount after rebuild
Performance⚠️ Slight CPU cost✅ Slightly better
Best for Production (multi-service)✅ Yes✅ Good for single app only

  1. Enable Auto-Start with systemd

You can use systemd to start Kiwi automatically on boot.

  • Create service file
sudo vi /etc/systemd/system/kiwi.service

Paste:

[Unit]
Description=Kiwi TCMS Docker Compose Application
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
WorkingDirectory=/opt/kiwi
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
RemainAfterExit=yes
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
  • Enable and start
sudo systemctl daemon-reload
sudo systemctl daemon-reexec
sudo systemctl enable --now kiwi.service
  • Confirm it works after reboot
sudo reboot

Then check:

docker ps
systemctl status kiwi

  1. Auto-Renew Deploy Hook

Create a deploy hook:

sudo vi /etc/letsencrypt/renewal-hooks/deploy/reload-haproxy.sh

Paste:

#!/bin/bash
cat "$RENEWED_LINEAGE/fullchain.pem" "$RENEWED_LINEAGE/privkey.pem" > /etc/haproxy/certs/kiwi.maksonlee.com.pem
systemctl reload haproxy

Make it executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-haproxy.sh

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top