Personal Cloud Infrastructure
Minimal effort, maximum personal cloud infrastructure⌗
Introduction⌗
I never really enjoy blogs with paragraphs of philosophical explanations of why one should use the presented solution so I’ll get down to business right away and address some of the philosophy later.
Goal⌗
To create as much high quality personal (cloud) infrastructure with as little effort as possible.
I’ll focus on getting Nextcloud running as minimum viable personal cloud infrastructure (MVPCI). The methods used to get Nextcloud running are easily extended to other services as well, I’ll present some examples later on.
Hardware⌗
I recently bough new-home server hardware, the goal was to strike a balance between power and power consumption. These are the specs:
Part | Model | Price | Date purchased |
---|---|---|---|
CPU | Intel Core i3-9100 Boxed | €122.32 | 2020-12-15 |
Motherboard | Fujitsu D3644-B | €157.45 | 2020-12-15 |
RAM | Crucial CT2K8G4DFS824A | €57.45 | 2020-12-15 |
Power Supply | be quiet! Pure Power 11 400W | €53.91 | 2020-12-15 |
SSD | Samsung 970 EVO 1TB | €125 | 2020-12-15 |
Case | Fractal Design Define R3 | €93.50 | 2010-12-23 |
Total | €609.63 | ||
The URLs link to tweakers.net’s price comparison section, this is a popular comparison site for hardware in the Netherlands. I didn’t include any cables, since the motherboard is for OEMs, it does not come with any but I had them lying around from my previous server build. |
Tools⌗
Linux⌗
I’ll use Ubuntu Desktop because I can get it up and running within about 10 min and so far it has worked flawlessly on any hardware I tried it on (and indeed it works perfectly with the hardware mentioned above). Ubuntu Desktop presents a desktop so I can easily open some terminals and drag some files around and use VNC to do the same after I stowed the server away in the basement. But since we are going to use Docker Compose, it really does not matter which distribution you choose; after you booted it, everything will be the same as described here.
Docker Compose⌗
When I first tried to use Docker for my personal infrastructure, I concluded that it make things more complicated. When I first heard the term Docker Compose, I thought “hmm, another layer of complexity”, but no, Docker Compose = Docker for Dummies. One can simply write down (in Yaml) what services one wants and Docker Compose will download them down and make them run.
Traefik proxy⌗
Traefik is a reverse proxy and can seamlessly integrate Let’s Encrypt to get you valid certificates for your (sub) domains. It can be fully configured from within a Docker Compose yaml file and allows you to run multiple services in the same port, routing requests based on the contacted (sub) domain.
VSCode (optional)⌗
Whenever I work on a server, I use VSCode with the remote-ssh plugin, then I can open files on the remote server and start using them in a ssh session directly. I highly recommend it. Does require you apt install openssh-server
on the server.
Building your personal infrastructure⌗
Getting the Linux Server up and running⌗
Pick whatever GNU/Linux distribution that you prefer, and install it on your hardware.
Install Docker and Docker Compose⌗
Both Docker and Docker Compose are best installed not from your distributions repositories (unless you run Arch maybe) but using direct methods. First we install Docker (instructions optimized for Ubuntu 20.04) (source: digitalocean.com/community/tutorials), run the following commands in succession, see the source for more details
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
sudo usermod -aG docker ${USER}
su - ${USER}
Verify that you can use docker by issuing the following command, you should see a version number printed
docker --version
Now we install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/
docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Verify that you can use docker-compose by issuing the following command, you should see a version number printed
docker-compose --version
Running Nextcloud⌗
Make a new directory, the name is not important, I usually use “docker”
mkdir docker
Open a text file called docker-compose.yaml
and paste the following content into it:
version: "3.9"
services:
traefik:
image: traefik:latest
container_name: traefik
command:
- --log.level=DEBUG
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.mytlschallenge.acme.tlschallenge=true
- --certificatesresolvers.mytlschallenge.acme.email=you@email.nl
- --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json
- --serversTransport.insecureSkipVerify=true
ports:
- 80:80
- 443:443
- 8888:8080
volumes:
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
nextcloud_db:
container_name: nextcloud_db
image: mariadb
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- ./cloud.yourdomain.nl/db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=your_MYSQL_ROOT_PASSWORD
- MYSQL_PASSWORD=your_MYSQL_PASSWORD
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
nextcloud_app:
container_name: nextcloud_app
image: nextcloud
restart: always
depends_on:
- nextcloud_db
volumes:
- ./cloud.yourdomain.nl/nextcloud:/var/www/html
environment:
- MYSQL_PASSWORD=your_MYSQL_PASSWORD
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_HOST=nextcloud_db
labels:
- traefik.enable=true
- traefik.http.routers.nextcloud_app-http.entrypoints=web
- traefik.http.routers.nextcloud_app-http.rule=Host(`cloud.yourdomain.nl`)
- traefik.http.routers.nextcloud_app-http.middlewares=nextcloud_app-https
- traefik.http.middlewares.nextcloud_app-https.redirectscheme.scheme=https
- traefik.http.routers.nextcloud_app.entrypoints=websecure
- traefik.http.routers.nextcloud_app.rule=Host(`cloud.yourdomain.nl`)
- traefik.http.routers.nextcloud_app.tls=true
- traefik.http.routers.nextcloud_app.tls.certresolver=mytlschallenge
But before we can use this we need to do some things.
- Make sure you have a valid A record for your (sub) domain pointing to the IP address of your server.
- Set port-forwarding on you router such that requests on ports 80 (http) and 443 (https) point to the IP address of your server. It’s best if you also give it a fixed IP address within your network.
- Replace the following values in the yaml text:
- you@email.nl: your email address
- your_MYSQL_ROOT_PASSWORD: A mysql root password, it can be whatever you want
- your_MYSQL_PASSWORD: The password for the nextcloud mysql user, make up a nice one
- cloud.yourdomain.nl: Set the domainname you made an A record for, pointing to your server
Save the modified file. Now we are ready to pull down and start Nextcloud by issuing:
docker-compose up -d
You will see the containers being pulled down. When they are started, visit your Nextcloud install on https://cloud.yourdomain.nl.