Configuring a Reverse Proxy With LinuxServer’s SWAG, Cloudflare, and a Custom Domain
Reverse proxies are helpful for any server administrator who’d like the ability to securely access content outside of their home network while minimizing the risk of exposing their services via port forwarding.
In a previous guide, I explained how one can accomplish this through an NGINX container called NGINX Proxy Manager that simplifies the process by providing an intuitive web UI to manage proxies. Since then, I’ve personally made the switch to LinuxServer’s SWAG container (Secure Web Application Gateway), which has a slightly steeper learning curve due to the lack of web UI but comes pre-installed with some advanced features like Authelia, Organizr’s ServerAuth, and Fail2Ban that are much easier to implement than NGINX Proxy Manager.
What We’ll Need
Below is a list of the services and applications I’ll be referencing in this guide. By default, the guide is catered towards Linux-based systems and I’ll assume you already have Unraid or docker-compose installed and the basics configured. The only cost associated with the services below is the custom domain, which shouldn’t cost more than $5–10 on an annual basis.
- A custom domain
- A Cloudflare account (the free account is fine for what we’ll need)
- An application you’d like to access externally
- Access to the Community Applications plug-in if you’re using Unraid
- Access to your router’s settings
Purchasing a Domain and Configuring It in Cloudflare
The first step in the process is purchasing a domain to connect to Cloudflare’s DNS services, which will allow us to link the IP address of our server to our custom domain. If you haven’t already, go ahead and purchase a custom domain name. I typically purchase through NameCheap, but there are a variety of other good options to choose from as well.
Once you’ve done that, follow my quick guide on configuring Cloudflare as a DNS host and then move on to the next section to begin setting up the SWAG container itself.
Now that our domain and DNS records have been configured correctly, navigate to the Community Applications plug-in in Unraid and install the Docker container “SWAG”, or keep reading for a docker-compose example for non-Unraid users.
Below are the relevant fields/environment variables we’ll need to consider before we can install SWAG:
- HTTP Port: Defaults to ‘80’. If you’re using Unraid, the system already uses port 80, so we’ll need to assign a different port for the time being. I’ve used ‘280’ instead.
- HTTPS Port: Defaults to ‘443’. If you’re using Unraid, the system already uses port 443, so we’ll need to assign a different port for the time being. I’ve used ‘2443’ instead.
- Email: The e-mail address that will be registered for the Let’s Encrypt certificates and notified of expiration dates, etc.
- Domain Name / URL: The base domain that you’re going to be using for your proxies. If I want to set up a subdomain for Plex at plex.chasemack.com, I’m going to enter ‘chasemack.com’ for this variable.
- Subdomains: SWAG requires a list of subdomains that you intend on using for your applications, which should already be entered into Cloudflare as CNAME records. List all of them here separated by commas but no spaces.
- Only Subdomains: Defaults to false. Leave as is unless you don’t plan to use subdomains for your proxies.
- Validation: Change to DNS, which we’re leveraging Cloudflare for
- DNS-Plugin: Enter ‘cloudflare’
- Appdata Config Path (or ‘config’ volume to mount if using docker-compose): Enter the path you’d like SWAG to save its configuration files to.
Leave everything else as-is for the time being and click “Apply” to install if you’re using Unraid.
If you’re using docker-compose, see below for an example from the LSIO team of a properly-configured YML file and then use ‘docker-compose up swag -d’ to build the container once you’ve entered your own configuration settings.
Forwarding HTTP/HTTPS to SWAG in Your Router’s Settings
SWAG should now be installed and listening for external web requests on the ports you specified in your container configuration. Next, we’ll need to update our router’s settings to forward all HTTP/HTTPS traffic to these ports on our server.
The tricky part about this step is that every router’s configuration tools look different, so I can’t provide exact steps on how to do this. The concept is the same regardless of your router — you’ll want to log into your router’s settings and find the port forwarding section. From there, forward HTTP and HTTPS traffic to the custom ports assigned during installation.
For this guide, I’m using the Verizon Fios router I have installed at my house as an example. Here’s what the configuration looks like after updating the port forwarding settings:
My router is now configured to route any incoming HTTP traffic from port 80 to port 280 on my server (which has an internal IP address of 192.168.121.161), and then the same for HTTPS traffic (port 443 to port 2443).
If you’re not on Unraid and were able to utilize ports 80 and 443, forward to those ports on your server instead.
On the server (192.168.121.161), SWAG is listening for traffic on those same ports and after completing the next section, will redirect it to the application being requested.
Save and exit your router’s settings.
Configuring Subdomains in SWAG
The process to configure subdomains and subfolders from here on out is fairly straightforward, even without a simple web interface like the one provided by NGINX Proxy Manager.
To begin, navigate to the config folder you mapped during setup (should be in AppData for Unraid users). From there, open ‘nginx’ and then ‘proxy-confs’.
In this folder, we’ll find sample configurations for most of the common applications that the LinuxServer team believes users typically set up:
To configure a subdomain for a given application, find its sample file (note the SAMPLE file extension), open it in a text editor (I typically use Notepad++), and then save the file as application.conf, removing the ‘.sample’ file extension:
If you’re having trouble with the extension not saving correctly, open a blank document, copy and paste the text from the sample configuration file, and then save the file in the ‘proxy-confs’ folder with the ‘.conf’ file extension.
Occasionally, you may need to tweak the settings inside the file to get things to work properly.
For example, you may want to use a subdomain other than the application’s name. To do this, update the application name at the top of the file after ‘server_name’. In the example below, I’ve configured a ‘git.tech-e.com’ subdomain in Cloudflare, so I’ve changed the configuration file for Gitea to point to ‘git.*’ instead of ‘gitea.*’:
Another important setting to monitor within the configuration files is the name of the application being referenced, which may not always match the name of the application running on your server.
The best example of this type of scenario is Bitwarden’s password manager, which is commonly utilized through a fork now called VaultWarden. If you’ve installed VaultWarden and try to set up a reverse proxy using the Bitwarden .conf file, you’ll need to replace every instance of ‘bitwarden’ when referenced next to the text ‘$upstream_app’.
Otherwise, SWAG will look for a container called ‘bitwarden’ when it tries to forward traffic to the appropriate application and return an error.
Leave the ports as-is by default, which are usually correctly configured for the various applications found in the ‘proxy-confs’ folder. (Note that they should typically match the internal ports used by the application — not the ports you might have exposed during installation, unless SWAG is on a separate network.)
Configuring Subfolders in SWAG
If you’d prefer to utilize subfolders in SWAG (www.chasemack.com/gitea instead of gitea.chasemack.com), the process is almost identical with one exception.
Similar to the subdomain setup, find the application’s subfolder.conf SAMPLE file, open it, and save it as a .conf file.
By default, the LinuxServer team uses the application’s name as the subfolder path. You can update this to your own value by replacing every instance of ‘/application’ with the value you’d like to use (just be careful not to remove/add any forward slashes).
In my example, I’d like Gitea to be accessed at ‘chasemack.com/git’ instead of ‘chasemack.com/gitea’, so I’m going to update all of the ‘/gitea’ references below to ‘/git’:
(Note that you shouldn’t change the application name next to any instances of ‘$upstream_app’, as this should match the name of the container installed on your server and not the custom value you’d like to use for its URL.)
Next is where the subfolder exception comes in — in order for the application to work properly with a subfolder’d URL, you’ll need to change a setting within the application itself — typically called the ‘Base URL’ — before your proxy will work.
Fortunately, the LinuxServer team includes comments at the top of each application’s subfolder .conf file with instructions on which setting to change within the application to accommodate a subfolder proxy:
If you’ve set your subfolder path to something different (‘/git’ instead of ‘/gitea’), make sure you enter the custom path in the application’s settings and not the default LinuxServer recommendation.
Final Steps and Review
Once you’ve saved your application SAMPLE files as .conf files and have updated application names/subfolder paths/etc. as necessary, you’ll need to restart the SWAG container for them to take effect (you’ll need to do this any time you make a change to SWAG’s settings).
If you followed the steps above correctly, your reverse proxy should now work correctly by navigating to the new subdomain/subfolder.
If you’d like to add subdomains in the future, the steps are as follows:
- Add a CNAME record in Cloudflare
- Find the application’s SAMPLE .conf file and save it as a .conf file
- Restart SWAG
What if SWAG doesn’t have a sample file for my application?
You’ll eventually notice the SWAG container doesn’t come with a .conf file for every application. To combat this, they’ve included template subdomain/subfolder files that you can use to begin building a .conf file for the desired application:
In most instances you can just update the container name (next to $upstream_app), ports, and subdomain/subfolder references, and everything should work out okay, but it isn’t always that simple.
What I usually do is a quick Google search for “<name of application> NGINX configuration” and search the results for someone who might have already asked the question and received the proper configuration text.
Additionally, most applications typically include various proxy configuration files for different web servers (NGINX, Traefik, Caddy, etc.) in their documentation, so that’s another place to look (SWAG utilizes NGINX).
SWAG’s capabilities extend far beyond what has been covered in this guide, but it’s a great place to start in terms of creating your initial proxies to begin accessing your applications externally and securely.
If you’ve followed this guide, please ensure you’ve secured all applications with some sort of authorization (enable username/password to log in, etc.) and then stay tuned for future guides on securing SWAG and your proxies even further.
Have any questions or comments about the content in this guide? Feel free to reach out to the author on reddit with any feedback or for additional help concerning these topics.