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.

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.
This post is licensed under CC BY 4.0 by the author.