Tags voor dit FAQ item:
Cloud Servers docker

Help ons door dit artikel te beoordelen!

Score van 4 sterren, gebaseerd op 8 beoordelingen

Een ontwikkel omgeving opzetten met Docker Compose

Laatste bijgewerkt: 02/06/2016

In dit artikel bekijken we hoe je concreet met Docker aan de slag kan voor het opzetten van een development omgeving voor bijvoorbeeld ontwikkeling en deployment van een web applicatie.
Vervolgens kan je met het geschreven yml bestand snel deze omgeving activeren op een Kinamo cloud server met behulp van de Docker Engine.

Als je meer informatie wil over hoe je Docker Engine kan installeren op een Kinamo cloud server, lees dan zeker ons artikel over CentOS 7 en Docker containers!

Docker maakt gebruik van "images" om containers te starten. Een image bevat een minimale linux omgeving en voert meestal één specifieke functie uit: een web server, database server...

Met behulp van Docker Engine kan je Docker "Containers" draaien. 
Een docker container is in vele opzichten vergelijkbaar met een "kant en klare" virtuele machine: je kan bestanden aanmaken, verwijderen en aanpassen. Er is echter een groot - en niet onbelangrijk - verschil: zodra je een docker container stopt, gaan de aanpassingen verloren.
Bij een virtuele machine kan men na een "power off" gewoon opnieuw opstarten met de laatste "state" van je aanpassingen.
Waarbij je voor installatie van een virtuele machine begint vanaf een ISO, installatie cd, ... kan je eenvoudig een docker image gebruiken als startpunt voor het opbouwen van een docker container.

Docker images zijn dus een soort templates waarmee je aan de slag kan. Aan de hand van deze images kan je een docker omgeving opbouwen.
Om er voor te zorgen dat de gegevens in je databank of de configuratie van je webserver behouden blijven moet je volumes aan je containers koppelen vanuit de host.
Voor veel software, frameworks of programmeertalen zijn er officiële docker images. Het enige dat je nog moet doen is je eigen data of code toevoegen om snel met je project van start te gaan.

Wanneer je meerdere containers gaat gebruiken binnen een project is het niet altijd even eenvoudig om de volledige docker aangedreven omgeving aan de praat te krijgen. De configuratie van elke individuele container, het koppelen van volumes aan je container enz wordt een omslachtige taak.

Om dit probleem op te lossen is er Docker Compose.
Met Docker Compose kan je een multi-container applicatie definiëren. Met één commando kan je daarna de nodige services starten en de hele omgeving opzetten!

In dit artikel bekijken we hoe je eenvoudig een werkomgeving kan opbouwen met Docker Compose.

In dit artikel gebruiken we Docker Compose om een omgeving op te zetten met twee docker containers: een webserver met Apache en PHP en een database server met MySQL. Dit is een frequent terugkerend scenario en opent de deur voor tal van experimenten met Wordpress, PHP frameworks enz. We gebruiken voor onze installaties de officiële images van de Docker Hub.

Het onderstaande project is uit te voeren op Windows, Mac of Linux. De installatie van Docker op Linux kan u hier raadplegen.
Als je voorkeur uitgaat naar Windows of Mac dan biedt Docker toolbox een oplossing.

We starten met het opzetten van een container voor de webserver. Als image voor de webserver gebruiken we één van de officiële PHP images "php:5.6-apache".
Dit is een handige keuze omdat ook Apache geinstalleerd is in de image.

Helaas zijn niet alle php extensies geïnstalleerd die we nodig hebben, met out-of-the-box images kan dit vaak voorvallen. Om straks verbinding met de database te kunnen maken hebben we de mysqli extensie nodig. Deze kunnen we toevoegen door op basis van de image uit de Docker Hub een eigen image te bouwen. We gebruiken met andere woorden de image uit de Docker Hub als startpunt voor onze eigen image.

Als eerste stap maken we een map aan waarin we alle bestanden voor de webserver zullen plaatsen. We geven de map de naam "php" omdat het om een php image gaat.
In deze map maken we een nieuw bestand aan met de naam "Dockerfile".

Een "Dockerfile" is een tekstbestand waarin de commando's staan om een Docker image te bouwen. In de dockerfile voor onze php image zetten we het volgende:

FROM php:5.6-apache

RUN docker-php-ext-install mysqli

Bij FROM geven we aan welke image we als basis willen gaan gebruiken.

Met RUN voeren we een commando uit dat ervoor gaat zorgen dat de mysqli extensie geïnstalleerd wordt. Dit commando is een feature van het php base image, welke het mogelijk maakt om op een eenvoudige manier meer extensies te activeren. Lees steeds grondig de documentatie van de images na die je wenst te gebruiken, vaak beschikken ze over eigen commando's om de basis image uit te breiden.

Voor de test onze webserver maken we ook een PHP infopagina. Maak in de 'php' map een nieuwe map aan met de naam 'www'. In deze map plaatsen we alle bestanden die door de webserver aangeboden moeten worden.

Maak een nieuw bestand aan met de naam index.php en plaats er de volgende code in:

<?php
phpinfo();
?>

Tenslotte gaan we onze nieuwe image maken en de container uitvoeren. Hiervoor maken we gebruik van Docker Compose.
Maak in de top map van het project een bestand aan met de naam docker-compose.yml. Dit mag het volgende bevatten:

version: '2'

services:
php: build: php ports: - "80:80" - "443:443" volumes: - ./php/www:/var/www/html

Op de eerste regel schrijven we de naam voor onze container 'php'.

Bij build schrijven we de naam van de image die we gaan gebruiken. Wij wensen een nieuwe image te bouwen aan de hand van onze net ontwikkelde Dockerfile.
Wij schrijven hier 'php'. Dit is de map waarin de Dockerfile staat die gebruikt moet worden voor de image.

Onder 'ports' plaatsen we de mapping van de poorten. Voor onze webserver willen we de poorten 80 en 443 beschikbaar maken. We koppelen de poorten van de container aan die van de host, bijvoorbeeld "host poort:container poort". Een concreet voorbeeld: als de firewall verkeer toelaat op poort 80 voor de cloud server, dan is de host poort "80" en kan u deze in de docker container mappen op bijvoorbeeld poort 80.

De laatste stap, maar een van de belangrijkste: we koppelen een volume aan de container.
De lijn './php/www:/var/www/html' wil concreet zeggen dat we de "/php/www" map op de host linken aan de map "/var/www/html" in onze container. Zonder deze stap ben je ALLE data in de docker container kwijt, mocht je deze herstarten, daar er voor de docker container géén locatie buiten de container zou zijn om bestanden fysiek op te slaan.

Als we nu het commando docker-compose up uitvoeren zal de image gebouwd en daarna uitgevoerd worden. Als we dan met een browser naar het IP adres van de Kinamo cloud server met docker engine surfen krijgen we de phpinfo pagina te zien.

De MySQL basis image die we gaan gebruiken uit de Docker Hub heeft geen extra configuratie nodig. We moeten dus geen nieuwe image maken.

Het volstaat om de nodige parameters toevoegen aan docker-compose.yml.
Voeg de onderstaande regels toe na de definitie van de php container.

  db:
    image: mysql:5.7
    volumes:
     - /var/lib/mysql
    environment:
     - MYSQL_ROOT_PASSWORD=hunter2
     - MYSQL_DATABASE=database

Bij de MySQL container koppelen we ook een volume voor de MySQL data. In plaats van een map te koppelen aan de container maken we nu gebruik van een Docker volume. De performance hiervan is namelijk beter.
Om een Docker volume aan te maken geven we dus enkel de map van de container mee waarvoor het volume gemaakt moet worden.
In mensentaal: de map "/var/lib/mysql" in de container zal gelinked worden met een default map die docker zal toewijzen op de host.
Aan de hand van het docker inspect commando kan je op de host het volume lokaliseren.

De parameters opgegeven in "environment" zijn image afhankelijk, in dit geval zijn er enkele variabelen die gaan bepalen welke waarde doorgegeven wordt aan de docker container, bijvoorbeeld het root wachtwoord voor de database, en de database naam.

Om er voor te zorgen dat de PHP container en de MySQL container kunnen communiceren gaan we ze aan elkaar koppelen.
Dit doen we met een kleine aanpassing aan docker-compose.yml.

version: '2'

services:
php: build: php ports: - "80:80" - "443:443" volumes: - ./php/www:/var/www/html links: - db db: image: mysql:5.7 volumes: - /var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=hunter2 - MYSQL_DATABASE=database

Bij de configuratie voor de PHP container voegen we het onderdeel 'links' toe.
We stellen in dat er een verbinding moet gelegd worden met de MySQL container.

Om de verbinding te testen passen we ons index.php bestand aan.

<?php

mysqli_connect("db", "root", "hunter2") or die(mysqli_error());
echo "Connected to MySQL<br />";

?>

Als we nu docker-compose up uitvoeren dan worden de twee containers gestart en aan elkaar gekoppeld. Wanneer we nu surfen naar het de webserver dan krijgen we het bericht 'Connected to MySQL' te zien.

Als je wil dat de omgeving in de achtergrond blijft draaien dan voer je docker-compose up -d uit.

Nu kan je met de ontwikkel omgeving aan de slag.
Je kan een applicatie ontwikkelen door code toe te voegen in de 'www' map. De volume mapping zorgt er voor dat die data ook bewaard wordt op de host in de map "/php/www".
Dankzij Docker Compose kan jouw werkomgeving eenvoudig opgezet worden op andere machines en uiteindelijk ook in een productie omgeving... En aangezien de omgeving opgebouwd is uit geisoleerde containers zijn er geen problemen meer door verschillen in configuratie of software versies!