Self-hosted server (raspberry pi)
Intro
The goal of this post is to show my Pi setup. I use a Raspberry 4 4GB mainly as a self-hosted server with Nextcloud to replace Google Drive.
1
This setup does not need access to a router
Since I want to boot from a SSD I have to change the priority order, since pi by default expects an SD card. For that, we can use pi imager to change bootloader to boot from usb. The pi will update just by connecting the SDD.
Now we can install the actual OS image in the SSD (documentation here). Dont forget to enable ssh. If its not enabled you can add a empty file named ssh in the SSD boot folder. I prefer to use bulleye, since it allows to configure the wifi connection via the wpa_supplicant.conf file in boot folder. Bookworm uses NetworkManager, but can also be configured in /etc/NetworkManager/system-connections/wifi.nmconnection
.
Wifi connection
The pi imager asks for the wifi settings, so this step is no necessary. But I like to configure the Pi to be able to connect to multiple Wifi, just in case. On the SSD, inside the boot folder, create a file named wpa_supplicant.conf with your Wifi config as in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=BR
# home wifi
network={
ssid="wifi"
psk=""
key_mgmt=WPA-PSK
}
# eduroam
network={
ssid="eduroam"
key_mgmt=WPA-EAP
eap=PEAP
phase2="auth=MSCHAPV2"
identity="username@ufrgs.br"
password=""
}
Pi config
With that the Pi is ready to boot, so connect the SSD on the Pi and try to ssh into it. Now run
1
2
sudo apt update
sudo apt upgrade
with that we should be able to ssh using the hostname set in the OS installation (inside the same network). To be sure, or if you were not able to ssh using localhost name, install avahi daemon
1
2
3
sudo apt-get install avahi-daemon
sudo systemctl start avahi-daemon
sudo systemctl enable avahi-daemon
If you are using WSL on windows and cannot use hostname only inside WSL, you need to change (or create if doesnt exists) .wslconfig and write
1
dnsTunneling=false
Docker Compose
For the services on Pi we will install docker compose (see documentantion here) using the debian setup.
Now just create a folder and a docker compose file and thats it. We just have to modify the compose file to what we need.
1
2
mkdir containers
touch docker-compose.yml
Docker Compose file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# run these
# docker compose pull && docker compose up -d
# commands inside container folder: docker compose exec folder_name command
version: "3.8"
# ----------------------
x-bb-common: &common
networks:
- internal
restart: unless-stopped
# deploy:
# resources:
# limits:
# cpus: "3"
# memory: 2560M
# ----------------------
networks:
internal:
external: false
driver: bridge
services:
db:
image: mariadb:10.6
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
<<: *common
# --- Nextcloud
nextcloud:
container_name: nextcloud
image: nextcloud
ports:
- 8080:80
volumes:
- nextcloud:/var/www/html
#- /home/lucasflores/nextcloud:/var/www/html/
#- /home/lucasflores/nextcloud_data:/var/www/html/data
#- /nextcloud_data:/var/www/html/data
#- ./data:/var/www/html/data
links:
- db
environment:
- MYSQL_PASSWORD=
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_HOST=db
#- NEXTCLOUD_DATA_DIR=/var/www/html/data
<<: *common
# --- ZeroTier
zerotier:
image: zyclonite/zerotier
container_name: zerotier-one
devices:
- /dev/net/tun
network_mode: host
volumes:
- '/var/lib/zerotier-one:/var/lib/zerotier-one'
cap_add:
- NET_ADMIN
- SYS_ADMIN
restart: unless-stopped
# --- pihole
pihole:
container_name: pihole
hostname: skynet
image: pihole/pihole:latest
# For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
ports:
- "53:53/tcp"
- "53:53/udp"
# - "67:67/udp" # Only required if you are using Pi-hole as your DHCP server
- "8081:80/tcp"
environment:
TZ: "Europe/Berlin"
WEBPASSWORD: "password"
DNSMASQ_LISTENING: all
# Volumes store your data between container upgrades
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
# https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
# cap_add:
# - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
<<: *common
volumes:
nextcloud:
db:
Services
ZeroTier
ZeroTier is the responsible for the communication between devices. To have access to the Pi services we have to install it in all devices that we want to grant access (see documentantion here).
if using wsl on windows, install zerotier on wsl terminal
1
2
curl -s https://install.zerotier.com | sudo bash
sudo zerotier-cli join 9ecbaef5759219ad
Inside the ZeroTier website we have to create a network and then connect all devices to it. The good thing about ZeroTier is that we can set static Ip’s for all devices. Once the device is connected it must be approved in zerotier website.
Nextcloud
I was not able to change the storage folder for nextcloud. So Its important to know that the files are, by default, in
1
/var/lib/docker/volumes/containers_nextcloud/_data/data/username/files/
So, to make a backup of the files I run
1
2
3
sudo rsync -avPn /var/lib/docker/volumes/containers_nextcloud/_data/data/username/files/ /home/user/nextcloud_backup
sudo rsync -chavzP --rsync-path="sudo rsync" --stats lucas@piip:/home/user/nextcloud_backup/ /home/nextcloud_backup
to backup inside pi and to backup to another machine, respectively. Im currently having some problems with file permissions with the backup ones, but you always can make a copy and change that.
Pihole
Pihole works as an ad blocking application. We just have to add the adlist to be blocked manually in the ip:port interface (Steveblack adlist is a famous one). After that change DNS server assignment to manual and put Pi ip. Now everything passes through pi and are filtered according to the adlist that we configured.
1
2
For some reason using the zerotier Pi ip does not work.
Creating a subnet (advanced-manage routes) in zerotier with router pi ip (destination) and zerotier pi ip (via) should work but its not right now.