Post

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. I dont think this step is necessary but if the OS is not booting could be that.

Now we can install the actual OS image in the SSD (documentation here). I prefer to use OS Lite 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. Dont forget to enable ssh. If its not enabled you can add a empty file named ssh in the SSD boot folder.

Wifi connection

The pi imager asks for the wifi settings, so this step is not 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. If you are in the same network from the Pi you should be able to ssh using the hostname set in the OS installation.

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
# 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=
      - MYSQL_PASSWORD=
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
    <<: *common

  # --- Nextcloud
  nextcloud:
    container_name: nextcloud
    image: nextcloud
    ports:
      - 8080:80
    volumes:
      - /home/flores/nextcloud_data:/var/www/html
    links:
      - db
    environment:
      - MYSQL_PASSWORD=
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db
    <<: *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



volumes:
  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

The web interface for Nextcloud is http://ip:8080/apps/files/files where the ip, in my case, is the zerotier ip that I set or the hostname.

The line in the docker compose file that changes where the data is stored is - /home/flores/nextcloud_data:/var/www/html.

Some usefull commands for Nextcloud:

1
2
sudo rsync -avP /home/user/nextcloud_data/data/user/files/ /path/nextcloud_backup 
sudo rsync -chavzP --rsync-path="sudo rsync" --stats user@ip:/path/nextcloud_backup/ /path/nextcloud_backup

to backup inside pi and to backup to another machine, respectively.

To send files from your machine to the server you can use

1
2
sudo rsync -chavzP --rsync-path="sudo rsync" --stats /path/nextcloud_backup/ user@ip:/home/user/nextcloud_data/data/lucasflores/files/
docker exec -u www-data nextcloud php /var/www/html/occ files:scan --all

The last command makes Nextcloud scan for new files. Running that command is needed for the new files to appear in the web interface.

Pihole (work in progress)

I need to thank Saumil Shah for the introduction to Raspberry Pi and its wonders. If not for him, this post would not be possible.

This post is licensed under CC BY 4.0 by the author.