Hoe docker-compose cross-platform maken (Mac, Windows, Linux)

Docker is een cross-platform tool, maar in de praktijk blijkt dezelfde docker-compose configuratie niet vlekkeloos op zowel MacOS, Windows als Linux te werken. In deze blog leg ik uit hoe je er voor kan zorgen dat je docker-composer configuratie cross-platform te gebruiken is.

De bestanden voor deze blog (inclusief docker-compose.yml) is cross-platform te gebruiken en is gehost op Github.

Docker-compose op MacOS

Ik maak zelf gebruik van Docker containers op MacOS. Hoewel het zeker uitdagingen heeft (waaronder performance problemen), werkt het goed. Er zijn geen toegangsfouten of permissie aanpassingen nodig om de normale Docker installatie te gebruiken. Goed om te weten: op MacOS gebruiker Docker Hyperkit om een virtuele Linux machine te draaien. Docker draait binnen deze virtuele machine.

Docker-compose op Windows

Als je Docker Desktop gebruikt (zonder Windows container), dan zal je waarschijnlijk geen fouten tegenkomen. Één van onze klanten gebruikt een oude Windows 7 installatie (welke EOL is) en heeft Docker Toolbox. Voor Docker Desktop heb je Windows 10 of later nodig. De reden waarom ik dit noem is omdat Docker Toolbox soms fouten heeft met het delen van de volumes. Als je een oudere Windows versie hebt, dan is het aan te raden om je installatie te updaten.

Docker-compose op Linux

Tot nu toe gaat het vrij goed. Echter, op Linux kan het lastiger zijn om Docker te draaien. Dat is opmerkelijk omdat Docker eigenlijk op Linux draait. Wat performance betreft draait het ook veel beter omdat je geen virtualisatie overhead hebt. Echter, met Linux kan je tegen permissie fouten aanlopen. Als je een proces onder een andere user id hebt lopen, dan kan het zijn dat dit proces geen toegang krijgt of met de verkeerde rechten de bestanden wegschrijft. Dit wordt beter uitgelegd door thaJeztah.

Om dit probleem op te lossen, legt thaJeztah uit dat je de permissies van de bestanden en folder goed moet zetten. Dit is niet een goede oplossing als je developed, want dan moet je na elke aanpassing de permissies goedzetten.

Laten we aannemen dat je onder de gebruiker ubuntu draai met de user id 1000 (je kan dit vinden door de commando id uit te voeren). De oplossing van István Döbrentei’s is om de processen binnen de container met dezelfde user id uit te voeren. Dat kan door de volgende commando in een dockerfile toe te voegen:

				
					RUN usermod -u 1000 www-data
				
			

In dit geval nemen we aan dat de gebruiker ubuntu altijd onder de gebruiker id 1000 werkt. Maar, als je het op een andere server of werkplek uitrolt, dan kan de id verschillen.

Verder moet je ontdekken welke gebruikersnaam in de Docker container wordt gebruikt.

Hoe maak je docker-compose cross-platform geschikt

In deze blog zet ik als voorbeeld een PHP + Apache + MySQL installatie neer met Docker. Hier hebben we het volgende voor nodig:

  • mysql:5.7.22
  • php:7.4-apache

MySQL – bepaal de gebruiker

Deze image heeft geen ps commando, waardoor het achterhalen van de lopende processen lastiger gaat. Je kan dit installeren als procps package, maar in dit geval kan gokken ook werken. De gebruikersnaam is letterlijk mysql.

PHP – bepaal de gebruiker

Vaak draaien webservers met de gebruikersnaam www-data. Voor de zekerheid starten we de image en kijken we welke gebruikersnaam gebruikt wordt. Als je de machine start, dan ontvang je een id van de container.

				
					docker run -d php:7.4-apache
bbab0180d4f2d010ec25247bf0e4eec9f12c8c80fdbbf4be06b3a73bfd81a42b
				
			

Gebruik de id in de exec commando om de processen te achterhalen. Gebruik rm om de machine te verwijderen.

				
					# docker exec -it bbab0180d4f2d010ec25247bf0e4eec9f12c8c80fdbbf4be06b3a73bfd81a42b ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.2  83304 24336 ?        Ss   10:28   0:00 apache2 -DFOREG
www-data    16  0.0  0.0  83328  6864 ?        S    10:28   0:00 apache2 -DFOREG
www-data    17  0.0  0.0  83328  6864 ?        S    10:28   0:00 apache2 -DFOREG
www-data    18  0.0  0.0  83328  6864 ?        S    10:28   0:00 apache2 -DFOREG
www-data    19  0.0  0.0  83328  6864 ?        S    10:28   0:00 apache2 -DFOREG
www-data    20  0.0  0.0  83328  6864 ?        S    10:28   0:00 apache2 -DFOREG
root        27  0.0  0.0   7640  2672 pts/0    Rs+  10:29   0:00 ps aux

# docker stop bbab0180d4f2d010ec25247bf0e4eec9f12c8c80fdbbf4be06b3a73bfd81a42b
# docker rm bbab0180d4f2d010ec25247bf0e4eec9f12c8c80fdbbf4be06b3a73bfd81a42b
				
			

Nu weten we zeker dat het de gebruiker www-data is. Je kan deze tip voor vrijwel elke docker image gebruiken.

Maak het cross-platform Dockerfile bestand

Eerst maken we de docker files. Voordat we dat doen, maak de volgende folders:

  • docker
  • docker/mysql
  • docker/php
  • mysql_data
  • public

In de dockerfile die we aanmaken gebruiken we de originele images, maar met twee toevoegingen. Eerst definiëren we het argument dat user_id de waarde 1000 heeft.

Vervolgens voeren we usermod uit. Deze veranderd het id van de gebruiker binnen de container naar 1000. Het idee hierachter is dat de bestanden dezelfde id’s krijgen als de gebruiker in de host (in dit geval ubuntu). Hierdoor krijg je dus niet de permissie fouten.

docker/mysql/Dockerfile

				
					FROM mysql:5.7.22
MAINTAINER Daniel Koop

ARG user_id=1000
RUN usermod -u $user_id mysql
				
			

docker/php/Dockerfile

				
					FROM php:7.4-apache
MAINTAINER Daniel Koop

ARG user_id=1000
RUN usermod -u $user_id www-data
				
			

Het docker-compose.yml bestand

De docker-compose.yml die ik gebruik oogt zoals een normaal bestand. Het verwijst naar de dockerfiles, de poorten, de volumes en afhankelijkheid. In dit voorbeeld neem ik aan dat je al bekend bent met hoe docker-compose.yml werkt. Zo niet, dan raad ik vsupalov’s blog blog aan over de docker-compose bestanden.

Bij de dockfile hadden we de optie voor het meegeven van een argument voorbereid. Dit argument kunnen we in de docker-compose.yml meegeven, zodat per installatie éénvoudig de gebruiker id aangepast kan worden.

Om het argument mee te kunnen geven moet de build regel veranderd worden. Wat normaal het volgende zou zijn voor PHP:

				
					build: ./docker/php
				
			

wordt het volgende:

				
					build:
  context: ./docker/php
  args:
    user_id: ${USER_ID}
				
			

Doe dit voor elke container:

docker-compose.yml

				
					version: '3'
services:
  web:
    build:
      context: ./docker/php
      args:
        user_id: 1000
    image: wedevelopcoffee/php-74-apache
    container_name: php
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - mysql
    volumes:
      - "./public:/var/www/html"
  mysql:
    build:
      context: ./docker/mysql
      args:
        user_id: ${USER_ID}
    image: mrkoopie/mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=testdb
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=user
      - MYSQL_PASSWORD=pass
    volumes:
      - "./mysql_data:/var/lib/mysql"
				
			

Hoe draai je cross-platform docker-composer

Het draaien van docker-compose werkt zoals normaal:

				
					docker-compose up
				
			

Als je de images al hebt gebuild voordat je de aanpassingen hebt gemaakt, dan moet je de –build vlag toevoegen. Dit is alleen nodig als je de Dockerfile(s) of userid aanpast.

				
					docker-compose up --build
				
			

Waar kan ik mijn container draaien?

Je kan je Docker container publiekelijk draaien op onze high-performance SSD servers. Voor slechts € 3.95 per maand kan je al je virtuele machine draaien. Start vandaag met Docker op je virtuele server.

Conclusie

Je docker installatie is nu cross-platform geschikt! Je kan het bestand verder flexibel maken door een .env bestand te gebruiken. Ook hiervoor heeft Vsupalov.com een goed artikel.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *