How can I run WebCit behind Apache or Nginx on port 80 / 443?

WebCit contains its own built-in HTTP/HTTPS service. If you are already running an external web server such as Apache or Nginx on standard HTTP (port 80) and HTTPS (port 443) ports, you cannot bind WebCit to the same port on the same IP address.

The standard solution is to run WebCit on an alternate internal port (for example, port 2000 or 8080) and configure your front-end web server as a reverse proxy. This allows users to access Citadel securely over standard web ports.

All WebCit application paths and resources are organized under the /ctdl/ path prefix.

Option 1: Dedicated Virtual Host (Recommended)

The cleanest setup is dedicating a specific hostname (such as citadel.example.com or mail.example.com) to WebCit and proxying the entire site.

Apache VirtualHost

Ensure mod_proxy and mod_proxy_http are enabled. In your Apache configuration:

<VirtualHost *:80>
    ServerName citadel.example.com
    Redirect permanent / https://citadel.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName citadel.example.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/citadel.example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/citadel.example.com.key

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:2000/
    ProxyPassReverse / http://127.0.0.1:2000/

    RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>

Nginx Server Block

In your Nginx configuration (e.g. /etc/nginx/sites-available/citadel):

server {
    listen 80;
    server_name citadel.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name citadel.example.com;

    ssl_certificate /etc/ssl/certs/citadel.example.com.crt;
    ssl_certificate_key /etc/ssl/private/citadel.example.com.key;

    location / {
        proxy_pass http://127.0.0.1:2000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        client_max_body_size 50m;
    }
}

Option 2: Subdirectory on an Existing Website

If you want WebCit to share an existing domain name with other content, this is straightforward because WebCit routes live under /ctdl/.

Apache Subdirectory

<Location /ctdl/>
    ProxyPass http://127.0.0.1:2000/ctdl/
    ProxyPassReverse http://127.0.0.1:2000/ctdl/
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
</Location>

Nginx Subdirectory

location /ctdl/ {
    proxy_pass http://127.0.0.1:2000/ctdl/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    client_max_body_size 50m;
}

Preserving Client IP Addresses

When running behind a reverse proxy, WebCit sees incoming connections originating from 127.0.0.1 unless configured to read forwarded headers. Ensure you run WebCit with the -f option so that it honors the X-Forwarded-For header sent by Apache or Nginx. This ensures user session tracking, audit logs, and "Who is online" displays report the actual client IP address.