This article is to document how I managed to set up a personal cloud with raspberry pi 4B and mapped it to my own domain through Fast Reverse Proxy. Note this article is mainly for my own reference, so certain very detailed steps I will skip when it is obvious to me.
An update on 2024-12-23, I accidentally breaked the SD card on my pi, and now have to use usb drive to boot up.
What I have?
- Raspberry Pi 4B with
- Argon ONE V2 Case for Raspberry Pi 4
- Connected to power via smart switch
- A VPS with public IP address
- I choose cheapest one as not any real intensive jobs were run there
- My own domain (zhengzhicheng.com)
Setup Overview
The following diagram shows it maps the incoming traffic to the my local Raspberry pi through the VPS.
FRP and caddy are the main tools used in VPS, serving different purposes. Caddy is used to
- Automatically obtain and renew TLS/SSL certificates for my site via Let’s Encrypt
- Work as a reverse proxy to forward client requests from port 443 to port 8080
FRP is used to
- Work as a reverse proxy to expose my local service (nextcloud) at pi to the Internet via public ip address offered by VPS
Argon Case and Smart Switch are used to
- remotely power on and off the pi to save electrical bills
Steps
Step 1 => Pi setup
Setup my Raspberry Pi 4B with argon case and plugged them into a smart plug so that I can remotely power on my Pi only when needed to avoid unnecessary electric charges
OS installation I used Raspberry Pi Imager to install raspberry lite OS into my pi, I choose not to install any desktop environment because I am using it as a server and don’t want to waste extras resources for the GUI. Just make sure ssh is enabled when using the software to create the install medium so that I can ssh into it immediately after the set up.
Install necessary tools
- Docker and docker-compose
- Tmux (Optional but I can’t work on command line without it!)
Mount hard disk during start up
- Check disk uuid by running
sudo blkid - Add a line to
/etc/fstabwithUUID=your-disk-uuid /mnt/ssd1 brtfs defaults 0 2(my ssd is formatted with btrfs) - Test if it works by running
sudo mount -a
- Check disk uuid by running
Test!
Step 2 => Nextcloud setup
- Create a Docker Compose file
version: '3'
services:
db:
image: mariadb:latest
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: tbc
MYSQL_DATABASE: tbc
MYSQL_USER: tbc
MYSQL_PASSWORD: tbc
app:
image: nextcloud:latest
restart: always
ports:
- 8080:80
volumes:
- /mnt/ssd1/nextcloud_data:/var/www/html
environment:
MYSQL_PASSWORD: tbc
MYSQL_DATABASE: tbc
MYSQL_USER: tbc
MYSQL_HOST: tbc
depends_on:
- db
volumes:
db_data:
nextcloud_data:
Run
docker compose up -don the directory where the docker-compose.yml is located, and check if nextcloud instance is up at http://pi_ip_address:8080Create a frpc configuration file
frpc.tomlserverAddr = "207.148.119.198" serverPort = 7000 [[proxies]] name = "nextcloud" type = "tcp" localIP = "127.0.0.1" localPort = 8080 remotePort = 8080 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000Then run
frps -c frps.tomland test if nextcloud instance is accessible at my domainLastly, create systemd service to start frps and docker compose automatically after pi boots up
Step 3 => Domain and vps setup
Add DNS record for my site in Alibaba cloud’s console to resolve it to the public ip address
Setup Caddy Since my site is bought from Alibaba cloud, I need to compile a caddy binary with alidns support, luckily there is already such a module in Github https://github.com/caddy-dns/alidns So I can just do
xcaddy build --with github.com/caddy-dns/alidnsCreate a Caddyfile with following configuration
nc.zhengzhicheng.com { reverse_proxy localhost:8080 tls { dns alidns { access_key_id {env.ALIYUN_ACCESS_KEY_ID} access_key_secret {env.ALIYUN_ACCESS_KEY_SECRET} } } }Run caddy
caddy run --config Caddyfile
Set up FRP Server Service side configuration This is minimal, just one line
bindPort = 7000is enough, also can change to other ports, just make sure it is aligned with client side port. Then runfrps -c frps.tomlAfter tested and if it working, create systemd service to start frps and caddy automatically after system boots up
Mistakes I made
- If using firewall tools such as
ufw, remember to unblock port 22 for ssh connection, otherwise you can’t ssh to pi afterwards- After I stupidly installed
ufwon vps and rebooted without unblocking port 22, I can’t ssh to my pi anymore. And since I installed server version without gui, I have to manually mount my sd hard (where the raspberry pi lite os is installed) to another Linux machine and modifyufwconfig file on the rootfs to enable port 22 again
- After I stupidly installed
- Get a VPS with address that can be accessed even within corporate
network
- This is generally not a good idea but currently I take notes during work a lot, and not able to sync it to personal cloud immediately really frustrates me(maybe just my problem)
- I forgot to test this before doing the configuration on my first vps and ended up doing the same thing again after I found out it does not work!
- Maybe I should automate these steps in a script in the future
Conclusion
After all is done, when I need to access my files in the code, I can just open my phone app to switch on the raspberry pi and wait a few minutes, and then switch it off when I am done. Even though it seems a bit troublesome, but I think it’s better than keeping it on 24/7 and pay the extra eletrical bills. This functionality provided by this setup is very little but it satisfy my current need, a personalized webdav server. I plan to upgrade to a NAS in the future when I got the budget.