Containers zijn handig. Ze hebben immers alles aan boord voor het correct functioneren van de applicatie. Daardoor kun je snel even iets uitproberen of makkelijk programmatuur inzetten die niet als pakket voor je distributie beschikbaar is. Ook voor de Raspberry Pi blijft het aanbod aan kant-en-klare containers groeien. Met HypriotOS heb je een draaiende Docker omgeving om hiermee meteen aan de slag te gaan. 

Serge Gielkens

De basis voor HypriotOS is een uitgekleed Raspbian besturingssysteem. Daarop is Docker geïnstalleerd. HypriotOS volgt Docker op de voet, zodat je altijd de meest recente versie hiervan hebt. Verder ben je als standaard gebruiker gekoppeld aan de groep docker. Daardoor heb je de juiste rechten om Docker commando’s uit te voeren en is geen sudo nodig.

Download van de site van HypriotOS het nieuwste image van dit besturingssysteem. Er is maar één versie en die is geschikt voor elke variant van de Raspberry Pi. Zet dit vervolgens op je microSD kaartje met een tool als Etcher. Als je de Raspberry Pi via een ethernetkabel met je netwerk verbindt, hoef je verder niets meer te doen. Voor wifi moet je nog een configuratiebestandje aanpassen.

Draadloze communicatie

Mount de boot-partitie van het microSD-kaartje. In ons geval is dat /dev/mmcblk0p1. Gebruik het commando lsblk om de juiste naam op jouw systeem te achterhalen.

sudo mount /dev/mmcblk0p1 <je_mount_dir>

Ga dan naar de directory <je_mount_dir> en open het bestandje user-data. Bij de sectie voor wifi-instellingen haal je het commentaarteken ‘#’ inclusief de spatie aan het regelbegin weg. Die spatie is echt belangrijk. De configuratie gebruikt namelijk het YAML-formaat, dat gevoelig is voor de mate van inspringing.

Vervang vervolgens bij ssid de string YOUR_WIFI_SSID door de netwerknaam van je router. Laat de aanhalingstekens staan. Het wachtwoord voor je draadloze netwerk stel je in bij psk. Edit hier de string YOUR_WIFI_PASSWORD. Laat ook hier de aanhalingstekens staan, tenzij je een versleutelde waarde invult. Die genereer je met het commando wpa-passphrase. Als laatste verander je de landcode achter country in nl voor de Nederlandse frequentiebanden.

Unmount dan weer de boot-partitie:

sudo umount /dev/mmcblk0p1

Eerste start

Schuif het microSD-kaartje in de Raspberry Pi. HypriotOS start automatisch een SSH-server op. Een scherm is dus niet nodig, maar de eerste keer wel handig om te controleren dat het systeem probleemloos opstart. Schakel de voeding in en wacht totdat HypriotOS de configuratie heeft afgerond. Hij stelt onder andere als hostnaam black-pearl in en voert de gebruiker pirate op met het wachtwoord hypriot. Doordat HypriotOS net als de huidige desktopsystemen Avahi gebruikt, hoef je geen IP-adres te weten om in te loggen:

ssh pirate@black-pearl.local

Controleer of de Docker service actief is:

docker info

In de uitvoer zie je bovenin dat het aantal containers nul is. Verifieer dat door:

docker container ls

Met dit commando zie je welke containers draaien. Inderdaad is er nu nog geen enkele actief. Daar gaan we meteen verandering in brengen.

Je eerste container

Als eerste kennismaking installeren we een eenvoudige container:

docker run -d -p 80:80 hypriot/rpi-busybox-httpd

Docker downloadt nu een container image met de naam hypriot/rpi-busybox-httpd. Het deel na de schuine streep is de eigenlijke naam van het image. Het deel ervoor geeft de repository aan. Deze repositories staan op de Docker Hub. Daar vind je ook images zonder repository naam. Dat zijn de officiële images van Docker.

Door het subcommando run start Docker de container meteen op. Dat gebeurt op de achtergrond door de optie -d. Met de optie -p regel je dat poort 80 van de container (tweede getal) benaderbaar is via poort 80 op je Raspberry Pi (eerste getal). Doe je dit niet, dan is de container van buitenaf ontoegankelijk.

Voer nogmaals het commando docker container ls uit. Die toont nu je eerste werkende container. In de kolom PORTS zie je dat verkeer op poort 80 van je Raspberry Pi inderdaad naar de zojuist gestarte container wordt doorgesluisd. Ga daarom in je webbrowser naar black-pearl.local. Hier zie je een eenvoudige webpagina als teken dat je Docker systeem correct functioneert.

What’s in a name?

In de uitvoer van het commando staat in de kolom NAMES een komische naam, in ons geval flamboyant_babbage. Deze maakt docker automatisch voor je aan. Hiernaar verwijs je om de container te beheren. Zo stop je hem met:

docker container stop flamboyant_babbage

Hoewel de container er nog is, laat docker container ls niets zien. Met de optie -a krijg je ook de gestopte containers:

docker container ls -a

Die komische naam is natuurlijk grappig, maar zegt verder weinig. Verander hem als volgt in mijn_container:

docker container rename flamboyant_babbage mijn_container

En start de container op onder zijn nieuwe naam:

docker container start mijn_container

Het is handiger om een nieuwe container meteen een duidelijke naam te geven. Dat doen we bij de tweede container.

Webinterface wel zo handig

Voor het beheer via de browser kiezen we Portainer.

Dat is zelf ook een container, die je als volgt installeert:

docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /mnt/portainer_data:/data portainer/portainer

Zoals beloofd geven we direct een zinnige naam met de optie –name. Door –restart=always start Docker de container automatisch na het booten op. Mocht Portainer om wat voor reden dan ook uitvallen, dan brengt Docker door diezelfde optie de container weer in de lucht.

Om containers te beheren moet Portainer praten met de Docker daemon. Voor de communicatie gebruikt Docker een socket: /var/run/docker.sock. Containers hebben echter geen toegang tot het bestandssysteem op de host. Daarvoor is de optie -v nodig. Dat staat voor volume. Met het eerste volume regel je dat Portainer via het socket in de container (naam na de dubbele punt) toegang heeft tot de Docker socket op de Raspberry Pi (naam vóór de dubbele punt).

Binnen de container plaatst Portainer in de directory /data zijn eigen configuratie. Die gegevens ben je kwijt bij het verwijderen van de container. Ook bij een update is het lastig om die informatie te behouden. Door het tweede volume koppel je de directory /mnt/portainer_data op de Raspberry Pi aan deze data-directory. De directory /mnt/portainer_data maakt docker automatisch aan. Als nu de container niet meer beschikbaar is, heb je nog altijd de applicatiegegevens achter de hand. Ook voor een backup is zo’n volume handig.

Ga in je webbrowser naar black-pearl.local:9000 om de webinterface van Portainer te openen. Maak allereerst een administrator aan. Daarna vraagt Portainer wat voor soort Docker omgeving je wil beheren. In dit voorbeeld is dat de lokale Docker installatie. Selecteer daarom Local. Druk tot slot op Connect linksonder, waarna het dashboard verschijnt.

BitTorrent client container

Portainer toont nu een lijst van Docker omgevingen. In ons geval is dat alleen de lokale installatie. Selecteer deze voor een overzicht van de aanwezige images, containers en volumes. Klik hier op Containers. Je krijgt dan in een lijst detailinformatie over de containers. Dat zijn er twee: de testcontainer mijn_container van HypriotOS en Portainer zelf.

Hieraan voegen we Transmission toe. Dat is een BitTorrent client met webinterface. Transmission biedt zelf geen container, maar op de site van Docker Hub vind je meerdere aanbieders. Wij kiezen voor het image linuxserver/transmission van LinuxServer.io. Klik op dat image voor nadere informatie over de installatie met het docker commando. Deze heb je namelijk nodig voor Portainer.

Ga weer terug naar Portainer en klik boven in de lijst van containers op Add container. Geef bij Name als naam mijn_torrent om een fantasienaam te vermijden. Bij Image tik je linuxserver/transmission in. De webinterface van Transmission luistert in de container op poort 9091. Die moeten we aan de buitenwereld bekend maken via de Raspberry Pi. Klik daartoe onderaan bij de sectie Network ports configuration op publish a new network port. Vul zowel bij host als bij container 9091 in. Het torrent verkeer daarentegen loopt over poort 51413. Doe daarom hetzelfde nogmaals en wel twee keer: een voor TCP en de ander voor UDP.

Het is handig als Transmission na een reboot van de Raspberry Pi vanzelf opstart. Ga daarvoor helemaal onderaan naar Advanced container settings. Selecteer hier bij Restart policy de optie Always. Als je een download binnen hebt, wil je daar natuurlijk bij kunnen. Dat regel je via een volume in het tabblad Volumes. Klik daar op map additional volume en tik bij container als directory /downloads in. Selecteer het type Bind en koppel bij host aan deze directory een map op de Raspberry Pi, bijvoorbeeld /mnt/downloads. Doe hetzelfde voor de directories /config en /watch. In de eerste staat de configuratie van Transmission. De tweede gebruikt hij om automatisch een download te starten, zodra je hierin een torrent bestandje plaatst.

Klik tenslotte op Deploy the container, net boven Advanced container settings. Wacht even totdat Portainer hiermee klaar is. Nu keer je weer terug naar het overzicht van de containers. Standaard verbiedt Transmission anonieme toegang tot de webinterface vanaf een andere host. Dat passen we aan via zijn configuratiebestand.

Stop eerst de container door mijn_torrent te selecteren en dan op Stop te klikken. Zo niet, dan ben je bij een herstart van Transmission je aanpassingen kwijt. Ga vervolgens op de Raspberry Pi naar /mnt/config. Verander daar in het bestandje settings.json de waarde bij rpc-host-whitelist-enabled in false. Dit moet je wel met sudo uitvoeren. Breng dan Transmission weer tot leven door in Portainer op Start te drukken en ga naar black-pearl.local:9091 om je eerste download te starten.

En verder

Ga nu zelf met containers aan de slag. Kijk rond op Docker Hub en probeer uit wat je interessant lijkt. Dat is immers het voordeel van containers. Het enige waar je op moet letten, is dat het image geschikt is voor de ARM-processor. Maar dat toont Docker Hub duidelijk.

Wist je dat Babbage echt heeft bestaan? Hij stond aan de wieg van de computer!