Self-Hosting Tutorial: Leveraging Proxies for Efficiency and Security - A Guide with 3 Examples
Video
Transcript
Hello, this is channel Easy Self Host. In this video, we are going to talk about http proxy.
First on why I'm always using the http proxy for every self-hosted web service.
Then I'm going to show you how to easily use http proxy to achieve these benefits
with multiple popular proxy choices. Let's get started with why we should use http proxy for
our self-hosted applications. The number one benefit of using a proxy is definitely for the
ease to manage our services with domain-based routing. We usually run a bunch of apps on one
server. If we just expose them onto the server's IP, each app will need a dedicated port number.
So we end up with a ton of ports to remember. Plus it makes your browser's address bar look
super cluttered since they will only hide the standard ports of 80 and 443. Using a domain
name can help that you don't need to memorize the IP address but you are still going to deal
with the port numbers. When we use a proxy server, it's the only one exposed to the server's external
IP sticking to the standard port number. It can route different domains to different apps. So you
get to give each app its own easy to remember subdomain. One great thing about domains is that
you don't pay extra for creating subdomains. The second benefit is the simplicity to protect all
your self-hosted applications with encryption. And you won't see the unsafe sign for your self-hosted
sets on your browser anymore. Once you configure the HTTPS setting for your proxy server, all your
applications get encryption. So you don't need to configure HTTPS for each of your apps and many of
them don't even support that. What's even better is that many modern proxies offer integration with
free certificate provider like Letsencrypt so you can get certificates automatically. And some of
them even integrate with common DNS providers like Cloudflare. So even if your server is running in
your home network, you can still get certificates automatically. I'll show you some examples later
in the video. The third benefit is that you can add access control on your proxy server. I have a video
about setting up Authelia on the proxy server for authentication. You can check it out if you want
to do this. Many applications don't have login support so you can protect them with this method.
And there are other apps like File Browser that lets you use proxy-based authentication instead of
their own login. So now you have a single sign-on system that gives you an uniform experience among
multiple apps. These are the three most relevant benefits for self-hosting. There are more common
benefits like better performance since proxies have the compression and caching capabilities.
And also proxies have their logs that you can get insights on who access what. Then I'll show you
how to use three popular proxy servers for your self-hosted applications. In these examples, I'll
show you how to do domain-based routing and how to set up HTTPS easily with Letsencrypt and your
domain's DNS provider. You will need a domain name for these examples and you can reference my first
tutorial on how to get a domain. The three proxies I'm going to show you are Caddy, Traefik, and
Nginx. Each of them has their own unique features and there are also trade-offs. Besides the three,
I also had a video about Nginx Proxy Manager which is a graphic UI based proxy service
powered by Nginx. Now let's get started with Caddy. Caddy is my personal choice for its simple
and elegant configurations and its relatively simple integration with DNS providers. Now let's
get started with setting up Caddy for two self-hosted applications here using Docker Compose.
For the Caddy image, I'm using the image built by myself. I'll get into this later why I'm not using
the official image. For the port section, we're exposing port 80 and 443 for HTTP and HTTPS.
Note that we are not exposing ports for our two applications since Caddy will reach them using
the Docker network within the server. For the volume section, we're using a volume to store the
data generated by Caddy. The data will include the certificates and logs which are worth persisting.
We're also mounting the Caddy config file to the container. I'm going to show you the configuration
in a moment. I'm also setting an environmental variable DNS_PROVIDER_TOKEN. This is for Caddy
to get certificates through DNS challenge. I'm using Cloudflare as my domain DNS provider.
To get this token, you can go to your profile in Cloudflare. In the API tokens tab, click create
token and choose edit zone DNS. Here in zone resources, choose to include the domain you want
to get a certificate. Then you can keep clicking continue to create a token. At this page, make
sure to copy your token since you won't be able to access it after closing this window.
Back to the Docker compose file, you should put your token after the equal sign here.
Then let's go take a look at the Caddy config file. Like I said, the Caddy config is easy to
write and understand. We can group all the subdomains together. For each subdomain, we
define a rule to proxy a subdomain to a Docker service with a port number. And on the top, we
define our TLS setting which is used to get certificates. Here my setting is to get it with
the DNS challenge through Cloudflare. And then I provide my API token set in the environment.
Caddy support DNS providers through its plugin system. And to add plugin to Caddy, you need to
compile Caddy with the plugin code. This is not very user friendly since people who don't know
how to code will find this confusing. That's why I have my personal Caddy image built with a list
of popular DNS provider plugins. I'm using the official recommended way to build the plugin.
I host this image on GitHub and you can just use it by specifying this image in your Docker
compose file. Now we can go to the command line to start Caddy and our applications.
Let's first go to the directory that has our Docker compose file. And then run the command
docker compose up -d. Now everything is up and running. Before we go to test our applications
in the browser, make sure that your DNS points your subdomains to the server IP. You can either
do this in your public DNS provider or modify the local DNS server if you are using PiHole
or AdGuard Home. After that we can type the domain name for our application. Here I'm entering the
domain name for VaultWarden. I'll also test the domain name for memos. So they both work and we
can notice that HTTPS is enabled. That's all for using Caddy. Now let's move on to use Traefik to
do the same thing. Traefik has a feature that it can monitor your Docker services so it can handle
proxy rules automatically. Using this you can have the proxy rules configured in the Docker compose
file and it's super convenient. For Traefik we can use the official image because it has popular
DNS integration built-in. We can configure the Traefik server using the commands. The first
argument is for enabling the admin panel but we actually don't need it here. The second argument
is required since it lets Traefik to monitor the Docker services. The third argument is to let
Traefik not connect to the services that don't enable Traefik. So it means we need to explicitly
enable Traefik in our service setting. The entry point arguments define the HTTP and HTTPS port.
We just set it to the standard ports. The rest of the arguments configure how to get certificate
using the DNS challenge. As you can see I set the provider to Cloudflare and I also set my email to
receive notifications for certificates. Then for every proxy server we need to expose port 80 and
other providers will have different names. For the volume section it's important that we mount the
Docker socket to the container so Traefik can monitor the Docker services. Also the ACME volume
is for storing certificates. Moving on to the application services the difference is that we
need to add a label section to add the proxy setting. The first argument enables Traefik to
proxy to this service. The second argument configures the domain name we want to use.
The third argument lets Traefik to use HTTPS for this service. The last argument tells Traefik to
get a certificate using the config we provide in the Traefik arguments. And it's the similar for
other services. I'm going to skip the command line part and the testing part as it's the exact
same with the Caddy example. Now let's try doing the same with Nginx, the most popular proxy server
in the world. But personally I'll recommend you to not use it for self-hosting because its
configuration is hard to get right without experience and there's no built-in support for
automatically getting certificates. The Docker compose for application services is the same
with the Caddy example since we'll have a dedicated configuration file for Nginx.
The Nginx service uses the official image. It also exposes the standard ports and it mounts
the configuration file and a volume to read certificates. What is different is that I add
a depends on section. This is a hack I create to automatically get certificates in this example.
So we'll have another container Certbot to get certificates and refresh it regularly.
It uses the official Certbot image with support for Cloudflare DNS. I customize the container's
entry point to get a certificate for my domain name and refresh it regularly. This uses the