Bespaar tijd en frustraties met Docker en Docker Compose

Nick Spaargaren

11 januari 2022

Bespaar tijd en frustraties met Docker en Docker Compose

Bij de start van een traditioneel ontwikkelproces begin je met het installeren van programmeertalen en services op je lokale omgeving. Denk hierbij aan het installeren van php en mysql. Wanneer er na een bepaalde tijd een nieuwe collega in dienst komt, begint deze collega waarschijnlijk met een schone installatie en installeert in dit geval php en mysql. De nieuwe collega begint te programmeren aan een project en heeft allerlei nieuwe technische oplossingen bedacht. Geweldig, het systeem is een stuk sneller geworden en draait als een zonnetje!

Jij als ervaren ontwikkelaar komt er (na het pull-en van de nieuwe technieken) achter dat een ander deel van de applicatie niet meer werkt! Na 2 dagen zoeken waar het probleem ligt blijkt het te komen doordat de nieuwe collega een nieuwere versie van php heeft gebruikt. Wat nu, php upgraden of downgraden.. En daarbij vanzelfsprekend de code ombouwen.

Docker maakt je ontwikkelproces voor jou en je collega’s een stuk gemakkelijker en kan deze vervelende dingen voorkomen! Zet Docker in om je projecten makkelijk en afgeschermd van elkaar te laten draaien. Met Docker creëer je voor ieder project een eigen virtuele omgeving. Docker bundelt het project afzonderlijk met alle code en dependencies die nodig zijn om het project te laten werken. Zonder dat je deze op je eigen computer hoeft te installeren!

Met docker kan ik meerdere projecten met verschillende versies draaien

Docker

De docker omgevingen zijn eenvoudig deel- en inzetbaar omdat het alle tools bevat die je anders op elke ontwikkel- en productieomgevingen afzonderlijk moet installeren. Een voordeel hiervan is dat de ontwikkelomgeving, de sandbox, exact overeenkomt met die van een collega en/of server. De sandbox zorgt er ook voor dat er geen conflicten tussen lokale projecten optreden. Denk aan projecten met verschillende Node- en dependency versies. Een docker omgeving bestaat uit verschillende elementen;

  • Container (een actieve image)
  • Volumes (voor het delen van bestanden tussen de containers en je computer)
  • Network (voor communicatie tussen containers)

Image

Je begint met het maken van een Image van het project. Een image bestaat uit verschillende laagjes. Je kiest een basis, bijvoorbeeld Node versie 17, of PHP versie 8.1. Hier borduur je op voort. De configuratie van de container bepaal je in een Dockerfile:

FROM node:17-alpine
WORKDIR /app
COPY ./ /app
RUN yarn install
CMD ["yarn", "start"]

In de bovenstaande Dockerfile maken we gebruik van de Node image 17-alpine. Dit laagje downloaden we automatisch vanuit het docker hub en kunnen deze vervolgens inzetten in onze container. Dit laagje kan ook gedeeld worden tussen containers zodat deze niet meerdere keren in verschillende containers gedownload hoeft te worden. Vervolgens creëren we een folder waar we onze locale bestanden van het project in zetten. Met een ‘yarn install’ en ‘yarn start’ starten we het project binnen de container.

Vervolgens is de container te builden en te starten met de volgende commando’s binnen je project:

$ docker build -t mijn-app ./Dockerfile

Container starten

$ docker run --detach --publish 3000:8000 mijn-app

Het draaiende project kunnen we via het port 3000 (http://localhost:3000), het interne poort 8000 buiten de container benaderen.

Meerdere containers

Dit werkt! Een volledig afzonderlijke applicatie met een gelijke omgeving. Nu denk je er misschien al over om dit in te zetten in je eigen project. Op je lokale development omgeving en de server wil je waarschijnlijk meerdere containers draaien. Je project bestaat bijvoorbeeld uit meerdere services zoals een frontend, backend en api met database. Ga je gang, start meerdere containers en bekijk de actieve containers via “docker ps”. Maar dan merk je al snel, al die commando’s uitvoeren is een repetitief werkje. Daarom is er Docker Compose!

Docker Compose

Bijvoorbeeld in de root van je project kun je een docker-compose.yml bestand aanmaken. In dit bestand geef je mee welke dockerfiles gebuild en gedraaid moeten worden.

In dit voorbeeld staat er in de root van het project een /frontend en een /backend folder met ieder zijn eigen Dockerfile. Na het aanmaken van het docker-compose.yml in de root, build en start meerdere containers met de volgende commando’s:

Alle containers builden.

$ docker-compose build
$ docker-compose up --detach

Docker Network

Met het docker network kun je verschillende containers met elkaar laten communiceren. In het bovenstaande voorbeeld hebben we een front-end en een back-end draaien op verschillende poorten. Met Docker Network kun je deze aan elkaar knopen.

$ docker network create
$ docker run --net project_network --name project_backend --detach project_frontend

Wanneer je gebruikmaakt van het docker netwerk hoef je ook niet meer met lokale poorten te werken, zoals boven genoemd (bijv. http://localhost:3000). Je kunt hiervan in de plaats je container-naam gebruiken: http://frontend en http://backend.

Containers deployen naar productie

De Docker containers kun je ook deployen naar je server. Dit is perfect omdat zo je omgevingen exact gelijk zijn aan je lokale omgeving. Met multi-stage builds kun je in een keer alle containers builden voor je ontwikkel- en productieomgevingen. Voor een intro tot kubernetes kun je hier verder lezen.

Heb je meer vraag naar de technische werking of heb je hulp nodig met de implementatie? Enrise kan je ondersteunen! Voel je vrij om contact met ons op te nemen.