Skip to content

Reverse Proxy Examples

Reverse proxies are used to make hosted applications accessible to the internet, improving performance, scalability, security, and reliability. This document provides examples of reverse proxy configurations, including Nginx and Apache, to help you set up and optimize your applications.

Crafty Controller Websockets (WSS)

Crafty makes use of WSS. As such you may experience issues using reverse proxies without the proper configurations. These examples make clear what needs to be done for your reverse proxy to support WSS.

Examples

Config based on lewishill211/crafty-controller-https (Edits for 4.0 compatibility by pretzelDewey)

upstream crafty {
    server "<DOMAIN>";
}

server {
    listen 80;
    server_name <DOMAIN>;
    if ($host !~* ^<SUBDOMAIN>\.<EXAMPLE>\.com$ ) {
        return 444;
    }
    rewrite ^(.*) https://$host$1 permanent;
}

server {
    listen 443 ssl;
    server_name <DOMAIN>;
    if ($host !~* ^<SUBDOMAIN>\.<EXAMPLE>\.com$ ) {
        return 444;
    }
    ssl_certificate <CERTIFICATE_LOCATION>;
    ssl_certificate_key <KEYFILE_LOCATION>;
    location / {
        #This is important for websockets
        proxy_http_version 1.1;
        proxy_redirect off;

        # These are important for websockets.
        # They are required for crafty to function properly.
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        #End important websocket parts

        proxy_pass https://localhost:8443;

        proxy_buffering off;
        client_max_body_size 0;
        proxy_connect_timeout  3600s;
        proxy_read_timeout  3600s;
        proxy_send_timeout  3600s;
        send_timeout  3600s;
    }
}

Base config made by Justman10000 and Zedifus (Adapted for WSS by pretzelDewey)

Required 'mods' for this config

For this config you need to add the following mods:

mod_ssl
mod_rewrite
mod_http_upgrade
mod_wss

<VirtualHost _default_:80>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost _default_:443>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    ProxyPreserveHost On
    SSLProxyEngine On
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off

    # This is important for web sockets which are required by crafty to run!
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule .* "wss://127.0.0.1:8443%{REQUEST_URI}" [P]
    # End important for WSS

    SSLCertificateFile <CERT_LOCATION>
    SSLCertificateKeyFile <KEY_LOCATION>

    ProxyPass / https://127.0.0.1:8443/
    ProxyPassReverse / https://127.0.0.1:8443/
    ProxyRequests off
</VirtualHost>

NPM Add Host example
1. Click Hosts
2. Click Proxy Hosts
3. Click Add Proxy Host
4. Enter your domain name
5. Change the scheme to 'https'
6. Input Forward IP/port in accordance with your particular workflow.

SWAG is not a product produced by Arcadia Technology, if you have issues setting it up please reach out to the linuxserver.io team directly. -Zed

What is SWAG?

SWAG SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up a Nginx web server and reverse proxy with PHP support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.

SWAG has multiple plug-ins pre-installed for DNS Verification, these are used when requesting Let's Encrypt™ certs. They cover most DNS providers (azure, cloudflare, route53, duckdns), If you are unfamiliar with SWAG I would advise referring to their repository's documentation as it is fairly comprehensive.

SWAG Stack Example (Docker Compose)

File Structure
crafty-4/
| crafty/
| swag/
| .env
| docker-compose.yml
.env
TZ="Europe/London"
USER_ID=1000
GROUP_ID=1000
URL=myexampledomain.com
SUBDOMAINS="mcdash"
ONLY_SUBDOMAINS=true
EMAIL=[email protected]
Monolithic docker-compose.yml
version: "3"
services:
swag:
    image: linuxserver/swag
    container_name: swag
    cap_add:
    - NET_ADMIN
    networks:
    - swag
    environment:
    - PUID=${USER_ID}
    - PGID=${GROUP_ID}
    - TZ=${TZ}
    - URL=${URL}
    - SUBDOMAINS=${SUBDOMAINS}
    - VALIDATION=http
    - DNSPLUGIN=cloudflare #optional
    - PROPAGATION= #optional
    - DUCKDNSTOKEN= #optional
    - EMAIL=${EMAIL} #optional
    - ONLY_SUBDOMAINS=${ONLY_SUBDOMAINS} #optional
    - EXTRA_DOMAINS= #optional
    - STAGING=false #optional Set staging to true so you don't get rate limited by LetsEncrypt if you're having issues with cert gen
    volumes:
    - ./swag:/config
    ports:
    - 443:443
    - 80:80 #optional
    restart: unless-stopped

crafty:
    container_name: crafty_container
    image: registry.gitlab.com/crafty-controller/crafty-4:latest
    restart: unless-stopped
    depends_on:
    - swag
    environment:
    - TZ=Etc/UTC
    ports:
    - "8000:8000" # HTTP
    - "8443:8443" # HTTPS
    - "8123:8123" # DYNMAP
    - "19132:19132/udp" # BEDROCK
    - "25500-25600:25500-25600" # MC SERV PORT RANGE
    volumes:
    - ./crafty/backups:/crafty/backups
    - ./crafty/logs:/crafty/logs
    - ./crafty/servers:/crafty/servers
    - ./crafty/config:/crafty/app/config
    - ./crafty/import:/crafty/import
    networks:
    - swag
networks:
swag:
    name: swag
./config/nginx/proxy-confs/crafty.subdomain.conf
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name mcdash.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {
        include /config/nginx/resolver.conf;

        set $upstream_app crafty_container;
        set $upstream_port 8443;
        set $upstream_proto https;

        client_max_body_size 0;

        # Proxy Connection Settings
        proxy_buffering off;
        proxy_connect_timeout  3600s;
        proxy_read_timeout  3600s;
        proxy_send_timeout  3600s;
        send_timeout  3600s;
        proxy_http_version 1.1;
        proxy_redirect off;

        # Proxy Header Settings
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;

        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

Contributed by: noahlistgarten#7462 (Discord)

In the traefik config file, set insecureSkipVerify to true:
CLI: --serversTransport.insecureSkipVerify=true
(https://doc.traefik.io/traefik/routing/overview/#insecureskipverify)
On the Crafty container, the labels needed are:
- "traefik.enable=true"
# ^ Use traefik on this container
- "traefik.http.routers.crafty.rule=Host(<YOURCRAFTYDOMAIN.TLD>)"
# ^ Set the host URL for traefik
- "traefik.http.services.crafty.loadbalancer.server.port=8443"
# ^ Port that Crafty operates on is 8443
- "traefik.http.routers.crafty.tls=true"
# ^ Tells traefik you want to use SSL/TLS to connect to your Crafty instance
- "traefik.http.routers.listgartenphotography.tls.certresolver=<YOURTRAEFIKCERTRESOLVER>"
# ^ OPTIONAL: If you want traefik to handle TLS certificates instead of Crafty,
#             Use this label and put the name of your traefik cert resolver here.
- "traefik.http.services.crafty.loadbalancer.server.scheme=https"
# ^ Tell traefik to connect to Crafty via https instead of http
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto = https"
# ^ Enable websockets for Crafty

Trouble with WSS still?

Some AD blockers will block WSS connections. Try whitelisting the domain or disabling your ad blocker and see if that resolves the problem.