ini
files under /config/dns-conf/
/config/log/letsencrypt
to see why the auto-renewals failed.CERTPROVIDER=zerossl
to retrieve a cert from ZeroSSL instead. The only gotcha is that ZeroSSL requires the EMAIL
env var to be set so the certs can be tied to a ZeroSSL account for management over their web interface.https://domain.com
. However, you don't necessarily need to have it listen on port 443 on the host server. All that is needed is to have port 443 on the router (wan) somehow forward to port 443 inside the container, while it can go through a different port on the host.http
validation only. Same rule as above applies, and it's OK to go from 80 on the router to 81 on the host, mapped to 80 in the container.lsio
. We can create it via docker network create lsio
. After that, any container that is created with --net=lsio
can ping each other by container name as dns hostname.Keep in mind that dns hostnames are meant to be case-insensitive, however container names are case-sensitive. For container names to be used as dns hostnames in nginx, they should be all lowercase as nginx will convert them to all lowercase before trying to resolve.
linuxserver-test.com
and we would like our cert to also cover www.linuxserver-test.com
and ombi.linuxserver-test.com
. On the router, forward ports 80
and 443
to your host server. On your dns provider (if using your own domain), create an A
record for the main domain and point it to your server IP (wan). Also create CNAMES for www
and ombi
and point them to the A
record for the domain.docker network create lsio
, and then create the container:docker start swag
to start it.docker-compose up -d
docker logs swag -f
. After some initial initialization, we will see the validation steps. After all the steps, it should print Server ready
in the logs.https://www.linuxserver-test.com
and we'll see the default landing page displayed.linuxserver-test.com
and we would like our cert to also cover www.linuxserver-test.com
, ombi.linuxserver-test.com
and any other subdomain possible. On the router, we'll forward port 443
to our host server (Port 80 forwarding is optional).cloudflare
, cloudxns
, digitalocean
, dnsimple
, dnsmadeeasy
, google
, luadns
, nsone
, ovh
, rfc2136
and route53
. Your dns provider by default is the provider of your domain name and if they are not supported, it is very easy to switch to a different dns provider. Cloudflare is recommended due to being free and reliable. To switch to Cloudflare, you can register for a free account and follow their steps to point the nameservers to Cloudflare. The rest of the instructions assume that we are using the cloudflare dns plugin.A
record for the main domain and point it to our server IP (wan). We'll also create a CNAME for *
and point it to the A
record for the domain. On Cloudflare, we'll click on the orange cloud to turn it grey so that it is dns only and not cached/proxied by Cloudflare, which would add more complexities.docker network create lsio
, and then create the container:docker start swag
docker-compose up -d
docker logs swag -f
. After some init steps, we'll notice that the container will give an error during validation due to wrong credentials. That's because we didn't enter the correct credentials for the Cloudflare api yet. We can browse to the location /config/dns-conf
which is mapped from the host location (according to above settings) /home/aptalca/appdata/swag/dns-conf/
and edit the correct ini file for our dns provider. For Cloudflare, we'll enter our e-mail address and the api key. The api key can be retrieved by going to the Overview
page and clicking on Get your API key
link. We'll need the Global API Key
.docker restart swag
and again watch the logs. After successful validation, we should see the notice Server ready
and our webserver should be up and accessible at https://www.linuxserver-test.com
.linuxserver-test
so our url will be linuxserver-test.duckdns.org
. Then we'll need to make sure that the subdomain points to our server IP (wan) on the DuckDNS website. We can always use our DuckDNS docker image to keep the IP up to date. Don't forget to get the token for your account from DuckDNS. On the router, we'll forward port 443
to our host server (Port 80 forward is optional).docker network create lsio
, and then create the container:docker start swag
docker-compose up -d
docker logs swag -f
. We'll see some initialization and then we will see the validation steps. After all the steps, it should print Server ready
in the logs.https://www.linuxserver-test.duckdns.org
.https://linuxserver-test.duckdns.org
, we'll see a browser warning about an invalid ssl cert. But accessing it through the www
(or ombi
or any other) subdomain should work fine./config
which is mapped from the host location (set by above examples) /home/aptalca/appdata/swag
./config/www
./config/nginx/site-confs/default
. Don't delete this file, as it will be regenerated on container restart, but feel free to modify as needed. By default, it is listening on port 443, and the root folder is set to /config/www
, so if you drop a page1.html
into that location, it will be accessible at https://linuxserver-test.com/page1.html
.default
site config so it reads:docker restart swag
to reload the nginx config./config/www/wordpress
folder, we'll change the root directive in our SWAG default site conf to point there. We'll find the line in /config/nginx/site-confs/default
that reads root /config/www;
and change it to root /config/www/wordpress;
and restart SWAG.https://linuxserver-test.com/wp-admin/install.php
. We'll go ahead and enter mariadb
as the Database Host
address (we are using the container name as the dns hostname since both containers are in the same user defined bridge network), and also enter the Database Name, user and password we used in the mariadb config above (WP_database
, WP_dbuser
and WP_dbpassword
).https://linuxserver-test.com
.http
requests on port 80 enabled and auto redirected to https
on port 443, uncomment the relevant lines at the top of the default site config to read:/config/nginx/proxy-confs
folder as inactive sample files. To activate, one must rename a conf file to remove .sample
from the filename and restart the SWAG container. Any proxy conf file in that folder with a name that matches *.subdomain.conf
or *.subfolder.conf
will be loaded in nginx during container start.https://heimdall.linuxserver-test.com
):heimdall.*
will match this server block./
so it will match any subfolder or path at this address..htpasswd
to perform user/pass authentication before allowing access.proxy_pass https://heimdall:443;
and expect nginx to connect to Heimdall via its container name used as a dns hostname. Although it works for the most part, nginx has an annoying habit. During start, nginx checks all dns hostnames used in proxy_pass statements and if any one of them is not accessible, it refuses to start. We really don't want a stopped proxied container to prevent our webserver from starting up, so we use a trick.variable
instead of a dns hostname
, nginx doesn't check whether it's accessible or not during start. So here we are setting 3 variables, one named upstream_app
with the value of heimdall
, one named $upstream_port
, with the value of the internal heimdall port 443
, and one named $upstream_proto
with the value set to https
. We we use these variables as the address in the proxy_pass directive. That way, if the heimdall container is down for any reason, nginx can still start. When using a variable instead of hostname, we also have to set the resolver to docker dns in the previous line.$upstream_app
to an IP address instead: set $upstream_app 192.168.1.10;
https://linuxserver-test.com/todo
to https://linuxserver-test.com/todo/
(added forward slash at the end).https://linuxserver-test.com/todo/
will match this location block.$upstream_app
with the value mytinytodo
and tell nginx to use the variable as the address. Keep in mind that the port listed here is the container port because nginx is connecting to this container directly via the docker network. So if our mytinytodo container has a port mapping of -p 8080:80
, we still set $upstream_port
variable to 80
.Nginx has an interesting behavior displayed here. Even though we definehttp://$upstream_mytinytodo:80/
as the address nginx should proxy, nginx actually connects tohttp://$upstream_mytinytodo:80/todo
. Whenever we use a variable as part of the proxy_pass url, nginx automatically appends the definedlocation
(in this case/todo
) to the end of the proxy_pass url before it connects. If we include the subfolder, nginx will try to connect tohttp://$upstream_mytinytodo:80/todo/todo
and will fail.
https://ombi.linuxserver-test.com
.ombi
set up on our dns provider (a wildcard CNAME *
will also cover this) and it is pointing to our A
record that points to our server IP. If we are using the docker cli method, we also need to create the user defined bridge network (here named lsio
) as described above. We also need to make sure that port 443 on our router is forwarded to the correct port on our server.https://linuxserver-test.com
), we simply rename the file ombi.subdomain.conf.sample
under /config/nginx/proxy-confs/
to ombi.subdomain.conf
and we restart the SWAG container. Now when we browser to https://ombi.linuxserver-test.com
we should see the Ombi gui.nextcloud
set up on our dns provider (a wildcard CNAME *
will also cover this) and it is pointing to our A
record that points to our server IP. If we are using the docker cli method, we also need to create the user defined bridge network (here named lsio
) as described above. For DuckDNS, we do not need to create CNAMES, as all sub-subdomains automatically point to the same IP as our custom subdomain, but we need to make sure that it is the correct IP address for our server. We also need to make sure that port 443 on our router is forwarded to the correct port on our server.nextcloud.subdomain.conf.sample
under SWAG's /config/nginx/proxy-confs
folder and rename it to nextcloud.subdomain.conf
, then restart the SWAG container.https://nextcloud.linuxserver-test.duckdns.org
and we should see the Nextcloud set up page. We'll fill out the info, use the mariadb user ncuser
and the password we selected in the environment variable (ncpassword
in the above example) and we'll use mariadb
as the Database Host address (container name as dns hostname).nextcloud.subdomain.conf
file:If you followed the above directions to set it up for the first time, you only need to add the line'trusted_proxies' => ['swag'],
, otherwise nextcloud 16+ shows a warning about incorrect reverse proxy settings. By default, HSTS is disabled in SWAG config, because it is a bit of a sledgehammer that prevents loading of any http assets on the entire domain. You can enable it in SWAG'sssl.conf
.
https://linuxserver-test.com/plex
. We will initially set up Plex with host networking through its local IP and will connect to it from the same subnet. If we are on a different subnet, or if using a bridge network, we can use the PLEX_CLAIM
variable to automatically claim the server with our plex account.