Rock64 Docker Setup: My way of totally disrespecting everything

Setting up and installing a linux install and fill it up with docker containers

19-11-2019 - 7 minutes, 58 seconds -

UPDATE 19.11.2019

Since my ubuntu docker service kept shutting down, I reworked this guide to use the debian version of the same rom. That includes installing docker yourself.. But hey, if it's about stability, it's damn worth it, as my docker service kept crashing every 5 minutes in the end. It was unbearable.

Home servers are fun and provide functionality in a small scale.

Whether you want to provide a Network Attached Storage (NAS) or a few microservers, single board chips or SBC like the Raspberry Pi offer exactly the right amount of computing power for our little projects. In my case, I own a Pine64, a Rock64 and a Raspberry Pi 3b+ where the Pine64 is just a simple PiHole, the RPi was supposed to be a media center and my Rock64 is my server for everything.

Why? Because it's the only SBC (that's cheap and until the RPi 4 released) that offers up to Gigabit ethernet, though it shares that with the USB Bus so it's not actually gigabit, but very close (80MB/s are common) Also it comes with 4GB of RAM and a Quad Core ARM Processor that clocks up to 1.2 to 1.3 GHz. Plenty fast for our applications!

So why not just install everything on the base system? The Rock64 isn't known for it's stability of the Linux Distribution. The one I'm using kernel panicked every now and then, so I had to do a complete reinstall to Ayufan's Rock64 Linux Build, specifically the minimal Debian buster version.

Okay, let's start.

Installing the OS

First, you obviously gotta download the OS itself. Just go to Ayufan's Rock64 Linux Build and head over to the releases and choose the one for your Rock64 and for your needs. If you're just using a MicroSD card, good! There's nothing more I need to tell you, there's plenty of guides how to burn an Image onto the MicroSD Card.

If you're using the eMMC Module though, it's not as simple. Either you use a complicated method partered with a MicroSD Card to flash the eMMC from an OS installed on the MicroSD, or you go the very easy way!

Aquiring the required cable

We need either an A Male to A Male USB Cable or (in my case) A Male to type C (thanks modern phones!).

Aquiring access to the eMMC

The Rock64 has a recovery mode built in that mounts the eMMC on any device that you attach it to via its USB-OTG port (the top one of the USB 2.0 ones) To get into that, we need to plug in the power cord while holding the recovery button until the white LED blinks 2 times (after about 5 seconds). When that happened, we can plug in the USB Cord into the USB OTG Port.

Flashing the eMMC

After that's done, you can check in your OS whether you got a USB Mass Storage Device connected. Note that in Windows it probably won't show up in explorer. To flash the eMMC Module, we just have to type

# unxz -dc  buster-minimal-rock64-0.9.14-1159-arm64.img.xz | pv | dd of=/dev/mmcblk0

where mmcblk0 might differ for you and the image obviously as well. PV is just a little program that shows how many bytes went through already, to have a rough estimation of when it's done, but it's not needed.

On success, we can boot the Rock64 for the first time and let the fun begin!

First boot

The standard login credentials are rock64 for both password and username. Upon logging in, it prompts you to change that immediately. After logging in again (per SSH, idk how it is if you're directly attached to the Rock64), I tend to change the root password, too. That's done by typing:

$ sudo su
# passwd

After that, I'd like to create a user that's not named rock64, so we go ahead and do just that!

# useradd -m wiped

The flag -m stands for "create a home directory" Obviously we want a password for that account as well.

# passwd wiped

Now, before everything else, we want to upgrade all packages since we're running an "out of date" system out of the box.

# apt update
# apt dist-upgrade

Installing necessary packages and optional ones that I prefer

So, I prefer the fish shell over bash together with oh-my-fish and tmux-zen. Don't worry, you don't need to click any of these links, I'll tell you how to install them in here. But first we need some requirements for my kind of setup, as we need to install docker, build a python module for certbot as well as certbot itself. As nginx will be running in a docker container, we won't need python-certbot-nginx. After that, we need to add ~/.local/bin to our path, since that's where docker-compose gets installed to. Enough talk, let's install those packages! (Taken directly from certbot's official website, Docker's documentation and modified)

# curl -fsSL | apt-key add -
# apt-key fingerprint 0EBFCD88
# add-apt-repository "deb [arch=arm64] $(lsb_release -cs) stable"
# apt update
# apt install fish tmux build-essential libssl-dev libffi-dev python3-pip python3-dev gcc python3-wheel python3-setuptools python3-cffi certbot docker-ce docker-ce-cli
# exit

To configure fish as the default shell, as well as adding the new user to the docker group and to the sudoers file, and then reboot, we need to run:

$ sudo chsh -s /usr/bin/fish wiped
$ sudo usermod -aG docker wiped
$ sudo vim /etc/sudoers # (Copy the root line and replace root with your username, it'll tell you you can't change a readonly file, exit with :wq!)
$ sudo reboot

The second boot

Log in to your newly created user account via SSH again. We first would like to install oh-my-fish, my preferred theme "l" and tmux-zen.

$ fish
$ curl -L | fish
$ omf install l
$ omf install tmux-zen

you can obviously install any theme that's listed here (previews)

You've done it! You've set up almost everything! Now obviously, we want to have SSL since it's 2019 everybody. Free SSL certificates (and encryption!) for everybody!

Installing docker-compose

Since we also want to use docker-compose, we need to install that, too. We should already have all the required packages:

$ pip3 install docker-compose

docker-compose gets installed into ~/.local/bin, where our PATH variable isn't set to, so we have to do that as well: $ vim ~/.config/fish/fish.config and insert

set -gx PATH ~/.local/bin $PATH

After a reboot it should be set.

Installing my provider's dns plugin

When we want to use wildcard certificates, we need to verify that we own the domain via a DNS challenge. These plugins do that for us. Unfortunately, my provider isn't officially listed, so we have to rely on 3rd party plugins like oGGy990's certbot-dns-inwx plugin! Thanks man, you are cool! If only you'd list all the required packages for python in your README!

The installation is pretty straight forward.

$ git clone
$ cd certbot-dns-inwx
$ python3 develop --no-deps

After that's done, we can edit the configuration file (that we need to create, even)

$ sudo vim /etc/letsencrypt/inwx.cfg

Where we paste the following configuration:

certbot_dns_inwx:dns_inwx_url           =
certbot_dns_inwx:dns_inwx_username      = your_username
certbot_dns_inwx:dns_inwx_password      = your_password
certbot_dns_inwx:dns_inwx_shared_secret = your_shared_secret optional

Note that

The shared secret is your INWX 2FA OTP code. It is shown to you when setting up the 2FA. It is not the 6 digit code you need to enter when siging in. If you are not using 2FA, simply keep the value the way it is.

- oGGy990

Change your username / password and if necessary your shared secret and make the file only readable by root

$ sudo chmod 0600 /etc/letsencrypt/inwx.cfg

Generating the SSL Certificate(s)

To finally generate the SSL Certificate, we just need to type

$ sudo certbot certonly -a certbot-dns-inwx:dns-inwx -d "sub.domain.tld" -d "*.wildcard.tld"

and it's done.

Coming back to Docker

Well.. before (at least I) we need to mount the external HDD that hosts my media as well as the microSD card that holds all my docker container data. Let's create the folders for those two

$ sudo mkdir /mnt/external
$ sudo mkdir /mnt/sdcard

To have them ready on boot, we can enter them into our /etc/fstab file. But first, we need to get the UUIDs of the partitions:

$ ls -l /dev/disk/by-uuid

which gives us an output like that:

total 0
lrwxrwxrwx 1 root root 10 Oct 19 09:46 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa -> ../../sda1
lrwxrwxrwx 1 root root 15 Oct 19 09:46 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb -> ../../mmcblk1p1
lrwxrwxrwx 1 root root 15 Oct 19 09:46 cccc-cccc -> ../../mmcblk0p6
lrwxrwxrwx 1 root root 15 Oct 19 09:46 dddddddd-dddd-dddd-dddd-dddddddddddd -> ../../mmcblk0p7

we then need to modify our /etc/fstab as following:

$ sudo vim /etc/fstab
LABEL=boot /boot/efi vfat defaults,sync 0 0
UUID=bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb /mnt/sdcard ext4 defaults 0 2
UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa /mnt/external ext4 defaults 0 2

To check if everything worked, we test it with

$ sudo mount -a

if that gives no errors and all the folders are mounted, we are all set and ready to go!

Starting the docker containers

This isn't a guide to set up docker completely, this is more a guide how to set up my docker container set that includes databases, nginx, php, jellyfin and a few other things. Setting that up is another blog entry / guide for another time. So anyways, time to start the containers! But first we need to start the docker service..

$ sudo systemctl start docker
$ sudo systemctl enable docker
$ cd /mnt/sdcard/Docker
$ docker-compose up

That's it! Done! Finito! I wait until everything has built and everything is ready to go.