Hi there!
In this post, I will show you how to expose your site hosted in your PC/Raspberry Pi in your home. By the end of this tutorial, you should be able to access your site hosted in your home PC/Raspberry PI using your domain name.
Requirement
- Home Server / PC / Raspberry Pi (I’m using Linux server)
- A website
Tech that we will be using
- Docker - you need to install this first
- Caddy - a reverse proxy software, just like nginx but much simpler
- DDclient
- ufw - to open port
Steps
- First you need to serve your website, you should take note which port your web server is listening to. For example, my site is listening to port 5000
- Create a directory, let’s call it caddy, within that directory, you should have Caddyfile (to configure reverse proxy), config directory, data directory, and docker-compose.yml. These 3 are needed by Caddy
- Copy the following into your docker-compose.yml
services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80" # this will bind your server port 80 to caddy port 80
- "443:443" # this will bind your server port 443 to caddy port 443
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./data:/data
- ./config:/config
- Copy the following into your Caddyfile, this will reverse proxy any access to foobar.mydomain.com from the internet into your site that is hosted in your server that listens to port 5000
foobar.mydomain.com {
reverse_proxy my-public-ip-address:5000
}
- Install ufw (or any other firewall), allow inbound and outbound access to port 80 and 443. (Also 22 if you are SSH-ing to your server)
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 22
sudo ufw enable
- Go to your router admin page (usually 192.168.100.1), and port forward port 80 and 443 into your server’s IP address and port 80 and 443. This would mean when there is an incoming external traffic goes into your router via port 80 and 443, your router will forward this traffic to your server’s port 80 and 443 respectively.
- Go to your domain name DNS management console, enable Dynamic DNS, then create a new DNS record as follows
A + Dynamic DNS Record, your-subdomain, your public ip address
- Go to any DNS checker, check the A record of your domain name, it should point to your public ip address.
- If you see it, this means, whenever someone access your URL, their request will be forwarded to your public IP address, your router will receive this request, it will forward this request to your server, your server will then forward this request to your site hosted in port 5000 (example)
- In your caddy directory, run
docker compose up -d
, this will bring up your Caddy docker container. Caddy will request for an SSL certificate for your domain name and route all incoming request to your server for the selected domain name to your site server.
Dynamic DNS Configuration
If you are using Windows, skip this step and follow this step instead.
Lastly, you need configure Dynamic DNS, since the public IP address given by your ISP is dynamic and keeps on changing. You could have manually update your IP address in your DNS management setting page, but it’s better to automate this.
In your DNS setting page, you should be able to find Dynamic DNS password, which is needed to automate updating your IP address.
In your Home Server, install DDClient using this command sudo apt install ddclient
. Just go through the config page, don’t worry too much about the details because we will actually override the settings manually.
Once you have gone through the installation steps, update the ddclient config file, sudo vim /etc/ddclient.conf
and paste the followings. Please take note the following settings is for domain name hosted in Namecheap, your domain name provider should have different setting.
use=web, web=dynamicdns.park-your-domain.com/getip # don't change
protocol=namecheap # don't change
server=dynamicdns.park-your-domain.com # don't change
login=yourdomain.com
password=your dynamic dns password
yourhost
If your URL is foobar.example.com
and the password for your dynamic DNS is foobarbazban
, then it will be as follows
use=web, web=dynamicdns.park-your-domain.com/getip # don't change
protocol=namecheap # don't change
server=dynamicdns.park-your-domain.com # don't change
login=example.com
password=foobarbazban
foobar
Run the following commands to ensure ddclient is configured correctly and to auto startup ddclient.
sudo ddclient -verbose -noquiet -force
sudo ddclient -force
sudo systemctl start ddclient
sudo systemctl enable ddclient
If there is no error, ddclient will auto update your sub domain IP address whenever your public IP address changes.
Additional Tips
I have 2 router, 1 is Huawei ONT which was given by my ISP, and 1 is TP-Link Deco. My server (Raspberry Pi) is connected to Deco, and my Deco is connected to Huawei ONT. I had to port forward ports 80 and 443 twice.
In my Huawei ONT, I need to port forward port 80 and 443 to my Deco. I had to find out what is the private IP address assigned by my Huawei ONT to my Deco, in this case, it was 192.168.100.10. So in the ONT, I port forwarded port 80 and 443 to 192.168.100.10.
Then, in my Deco, I need to port forward port 80 and 443 to my Home server. Again, I had to figure out what is the private IP address assigned by my Deco to my Home server, in this case, it was 192.168.68.200. In Deco, I port forwarded port 80 and 443 to 192.168.68.200.
P/S
This website is not hosted in my Home server, it’s hosted in Vercel.