Prerequisites
- This guide assumes that you using Docker and Docker compose to manage your self hosted services, Caddy can be installed without Docker but ddns-updater have to be replaced with another service.
How will this work?
- I'm glad you asked, we will use two containerized tools. The first is ddns-updater which will update your A records (subdomains) when your ip has changed, so your domains will always point to your server.
- The second is Caddy a reverse proxy which will forward a request for a subdomain to a port on your machine and it will give you automatic HTTPS.
Why do i need a reverse proxy?
- You may ask why do you need a reverse proxy if you know the port of your service and have a domain from which you can access it?
- Due to the automatic HTTPS your traffic will be encrypted, without SSL (HTTPS) everyone on your WIFI network and your ISP can read your traffic.
- You only need to open two ports on your router 443 (HTTPS), 80 (HTTP).
- You can do a lot of additional things between the client sending a requests for a site and and sending a response using a middleware for example, you can do additional authentication for an unprotected site with a caddy plugin.
Setting up the domain and subdomains
- First you have to get a domain, you can get a free domain on Freenom but I don't recommend it. Many people reported on Reddit that they domain's were removed.
- You can get a free sub domain with DuckDNS, in this case you can setup your sub domains in a form of "sub sub domain", for example if you clam the mydomain.duckdns.org subdomain, your service would be located at service.mydomain.duckdns.org, but i haven't tried this option but people on Reddit reported success with it.
Manage domain with Dynamic DNS service
- This service can manage your domain, your domain provider will provide you with an API key or token which ddns-updater can use to update the domain.
- Please check if your provider is on the supported list for ddns-updater.
- It also provides a web UI from you can see the status of you domains.
Setting up ddns-updater
- Docker compose setup:
Dynamic-dns:
image: qmcgaw/ddns-updater
container_name: dynamic-dns
restart: unless-stopped
privileged: true
volumes:
- /your/path/:/updater/data
ports:
- 8000:8000
- The configuration stored in the config.json in the specified data folder.
- Every subdomain has an entry in the settings list with the domain provider, the domain, the sub domain and the api key.
{
"settings":[
{
"provider":"namecheap",
"domain":"domain.cc",
"host":"sub",
"password":"apikey",
"provider_ip":true
}
]
}
SAetting up Caddy
- Docker compose setup:
caddy:
container_name: caddy
image: caddy:latest
restart: always
ports:
- 443:443/tcp
- 80:80/tcp
volumes:
- /your/path/caddy_config:/config:rw
- /your/path/site:/srv:rw
- /your/path/caddy_data:/data:rw
- /your/path/Caddyfile:/etc/caddy/Caddyfile:rw
- Configuration stored in the Caddyfile, for every subdomain you need to define a reverse_proxy ip:port, you can write comments with hashtags:
sub.example.cc {
encode gzip # forward header
log {
output file /data/monitor.log {
roll true # Rotate logs, enabled by default
roll_size_mb 5 # Set max size 5 MB
roll_gzip true# Whether to compress rolled files
roll_local_time true # Use localhost time
roll_keep 2 # Keep at most 2 log files
roll_keep_days 7 # Keep log files for 7 days
}
}
reverse_proxy ip:port
}
Example with Namecheap domain provider
- if you want to create a self hosted netflix with the Jellyfin thats on the 8096 port with a domain from Namecheap
- Create an A record for the subdomain for the service, for example jellyfin.mydomain.com on your domain providers dashboard, in Namecheap navigate to Account->Dashboard->Domain List->Manage->Advanced DNS. The "Type" enter 'A + Dynamic DNS Record' for "Host" enter the sub domain-> 'jellyfin', and Value is the your ip, set the TTL (update interval for the record) to Automatic
- Add an entry to the settings list in the config.json for the ddns updater:
{
"provider":"namecheap",
"domain":"mydomain.com",
"host":"jellyfin",
"password":"apikey",
"provider_ip":true
}
- Add an entry in the Caddyfile:
jellyfin.mydomain.com {
encode gzip # forward header
log {
output file /data/jellyfin.log {
roll true # Rotate logs, enabled by default
roll_size_mb 5 # Set max size 5 MB
roll_gzip true# Whether to compress rolled files
roll_local_time true # Use localhost time
roll_keep 2 # Keep at most 2 log files
roll_keep_days 7 # Keep log files for 7 days
}
}
reverse_proxy 192.168.0.101:8096
}
- Enjoy!