Ga naar hoofdinhoud

MySQL instellen en configureren in Docker

Leer hoe je een MySQL-database instelt en configureert binnen Docker-containers. De tutorial behandelt concepten zoals verbinden met MySQL-servers, het draaien van MySQL-clients om verbinding te maken met containers, enzovoort.
· 12 min lezen

Verken met AI

MySQL is de populairste relationele databasetool, met een marktaandeel van meer dan 40%. Vergeleken met concurrenten als PostgreSQL (16%) en Oracle Database (11%) zien die cijfers er erg goed uit.

MySQL is populair omdat het simpel én krachtig is. Dit zijn de beste features:

  • Relationeel: volgt het relationele model en gebruikt SQL om databases te beheren.
  • Open-source (GNU-licentie): geliefd bij de community. Bedrijven zijn er ook dol op.
  • Schaalbaar: kan alles aan van kleine applicaties tot enterprise-niveau.
  • Veilig: biedt gebruikersauthenticatie, toegangsbeheer en versleuteling.
  • Hoge prestaties: bekend om snelheid en efficiëntie bij complexe queries en grote datavolumes.
  • Replicatie en back-up: opties voor gegevensreplicatie en back-ups, waardoor disaster recovery-strategieën mogelijk zijn.

MySQL in Docker-containers gebruiken is een match made in the clouds. Als je eerder met Docker hebt gewerkt, gelden alle voordelen ook voor MySQL-Dockercontainers:

  • Isolatie en consistentie: de MySQL-instantie is geïsoleerd van andere software en afhankelijkheden, waardoor mogelijke conflicten worden voorkomen
  • Versiebeheer: met Docker kun je je volledige softwarestack, inclusief MySQL, van versies voorzien. Zo kun je je omgeving op elk moment reproduceren, wat ontwikkeling en testen vergemakkelijkt.
  • Schaalbaarheid en resourcebeheer: met Docker kun je je MySQL-applicatie opschalen door eenvoudig meer resources zoals geheugen of CPU toe te wijzen.
  • Afhankelijkheidsbeheer: Docker kapselt je MySQL-instantie in, zodat je verschillende versies kunt beheren zonder je lokale machine te verstoren.

Het belangrijkste van alles: je MySQL-applicatie werkt overal, niet alleen op je eigen computer.

Wil je MySQL vergelijken met de op één na populairste concurrent? Bekijk dan onze uitgebreide vergelijking PostgreSQL vs. MySQL.

Vandaag leer je de basis van het draaien van MySQL in combinatie met Docker. Aan de slag!

Vereisten

Omdat dit artikel draait om MySQL-Dockercontainers, zijn er een paar vereisten om mee te kunnen doen:

  • Toegang tot de command line/terminal: je hebt een lokale omgeving met terminaltoegang nodig. Als je in een Jupyter-omgeving zoals Colab zit, stap dan nu over.
  • Een draaiende Docker-instantie: je moet Docker Desktop al geïnstalleerd hebben (instructies in onze Docker for Data Science-tutorial). Als het volledig operationeel is, zie je linksonder in de interface een groene babywalvis:

image2.png

en het commando docker --help werkt zonder fouten in de terminal.

  • Basiskennis van Docker: ook al leg ik alle gebruikte commando’s uit, met basisbegrip van Docker haal je veel meer uit dit artikel.
  • SQL: hetzelfde geldt voor SQL — ik leg geen SQL-commando’s uit, omdat dat ons van het hoofdonderwerp afleidt. Als je SQL een beetje is weggezakt, kun je de belangrijkste onderwerpen herhalen in deze SQL-cursus.

De officiële MySQL Docker-image downloaden

We beginnen met het downloaden van de officiële MySQL Docker-image met het volgende commando:

$ docker pull mysql:latest

docker pull vereist de naam en versie van de image met de syntax image:version. Met het sleutelwoord latest download je de meest recente stabiele release.

Bezoek je de pagina van de officiële MySQL-image op Docker Hub, dan zie je veel andere versies voor verschillende doeleinden.

image3.png

Zo download je bijvoorbeeld v8.2:

$ docker pull mysql:8.2

Zodra je de image hebt gedownload, staat deze tussen je bestaande Docker-images:

image4.png

Docker-images kun je ook via de terminal opvragen:

$ docker images

image5.png

Onthoud: Docker-images zijn blauwdrukken voor het bouwen van containers. Net zoals een blauwdruk je in staat stelt een huis te bouwen, bevat een Docker-image alle instructies en componenten om een draaiende instantie van een applicatie of service te maken.

Als je uit een OOP-achtergrond komt, denk dan aan Docker-images als classes. Net zoals je met één class meerdere objecten kunt maken, kun je met Docker-images meerdere containers aanmaken.

Een MySQL-servercontainer draaien en beheren

Laten we nu onze eerste container maken van de mysql-image. Dit is het commando dat we gebruiken:

$ docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -d mysql
  • run: maakt een nieuwe container of start een bestaande
  • --name CONTAINER_NAME: geeft de container een naam. De naam moet leesbaar en kort zijn. In ons geval is de naam test-mysql.
  • -e ENV_VARIABLE=value: de -e-tag maakt een omgevingsvariabele die binnen de container toegankelijk is. Het is cruciaal om MYSQL_ROOT_PASSWORD te zetten zodat we later SQL-commando’s vanuit de container kunnen uitvoeren. Zorg dat je je sterke wachtwoord ergens veilig bewaart (niet in je hoofd).
  • -d: staat voor detached; met de -d-tag draait de container op de achtergrond. Als je deze tag weglaat, blijft het commando logs printen totdat de container stopt.
  • image_name: het laatste argument is de naam van de image waaruit de container wordt gebouwd. In dit geval is dat mysql.

Als het commando een lange onbegrijpelijke string (de container-ID) retourneert, is de container gestart. Je kunt de status checken met docker ps:

image6.png

Onthoud: een Docker-container is een krachtige emulator van een besturingssysteem. Behalve MySQL draaien kun je in de container elke taak uitvoeren die je normaal in de terminal van je computer zou doen.

Om toegang te krijgen tot de terminal binnen je container, gebruik je het volgende commando:

$ docker exec -it container_name bash

Dit start een bash-sessie.

Lokaal verbinden met de MySQL-servercontainer

Alle MySQL-containers starten een MySQL-server die alles bevat om databases te maken en beheren met SQL. Om verbinding te maken met de server, leveren containers ook een MySQL-client waarmee we SQL-queries kunnen uitvoeren. De client is gewoon een chique naam voor het mysql-terminalcommando. Laten we het gebruiken binnen de terminal van test-mysql:

1. Open de bash-terminal van test-mysql:

$ docker exec -it test-mysql bash

2. Verbind met de client als root-gebruiker:

$ mysql -u root -p
Enter password: ...
mysql>

We gebruiken de -u-tag om de gebruikersnaam (root) te specificeren en voegen de -p-tag toe om bij de prompt het wachtwoord in te voeren.

image1.gif

Het is ook mogelijk om buiten de container met de MySQL-server te verbinden. Je kunt bijvoorbeeld vanaf je hostmachine de MySQL-client handmatig op je systeem installeren.

Voor Windows kun je de instructies volgen in de officiële MySQL-installatiehandleiding.

Voor Mac kun je Homebrew gebruiken:

$ brew install mysql

Voor Linux of WSL2 (mijn keuze) kun je sudo gebruiken:

$ sudo apt update
$ sudo apt install mysql-client

Stop en verwijder na de installatie de container als deze draait:

$ docker stop test-mysql
test-mysql
$ docker rm test-mysql

Vervolgens starten we de container opnieuw door een poort van de container te mappen naar een poort op onze lokale machine:

$ docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -p 3307:3306 mysql

Dit commando doet het volgende:

  • -p 3307:3306: Mappt poort 3306 van de container (de standaardpoort voor MySQL) naar je lokale poort 3307. Dit betekent dat al het verkeer naar je lokale poort 3307 wordt doorgestuurd naar poort 3306 van de container en dat je MySQL-server op die poort bereikbaar is.
  • -d: Draait de container opnieuw in detached-modus.
  • --name test-mysql: Hergebruikt dezelfde containernaam "test-mysql".
  • -e MYSQL_ROOT_PASSWORD=strong_password: Stelt opnieuw het root-wachtwoord in voor de MySQL-server.
  • mysql: Specificeert de Docker-image die moet worden gedraaid, namelijk de officiële MySQL-image.

Nadat de terminal een nieuwe ID voor de container weergeeft, kunnen we de poortkoppelingen controleren:

$ docker port test-mysql
3306/tcp -> 0.0.0.0:3307

Gelukt! Nu kun je vanaf je lokale machine met de server op poort 3307 verbinden via de mysql-client:

$ mysql --host=127.0.0.1 --port=3307 -u root -p
Enter password:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.2.0 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates…

De MySQL-container configureren

Je kunt MySQL-containers voor talloze instellingen configureren met een configuratiebestand. Meestal wordt het bestand opgeslagen in een van de volgende mappen van de container:

  • /etc/mysql/
  • /etc/mysql/conf.d
  • /etc/mysql/mysql.conf.d

De mappen verschillen per image. Maar de standaard bestandsnaam en extensie voor een configbestand is my.cnf. Als het bestand in geen van de bovenstaande mappen bestaat, betekent dit dat de container een aangepast configuratiebestand vereist. Dat is het geval voor onze test-mysql-container:

$ ls /etc/mysql/conf.d/ # Returns no output

In zulke situaties moeten we de volgende zorgvuldige stappen zetten:

1. Stop en verwijder de container:

$ docker stop test-mysql; docker rm test-mysql

2. Maak lokaal (op je machine) een leeg configuratiebestand aan:

$ sudo mkdir -p /etc/docker/test-mysql # Create a dir
$ sudo touch /etc/docker/test-mysql/my.cnf # Create a config file inside dir

3. Start de container opnieuw door de twee lege .cnf-bestanden te koppelen:

$ docker run \
   --name test-mysql \
   -v /etc/docker/test-mysql:/etc/mysql/conf.d \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -d mysql

We gebruiken een nieuwe tag: -v, kort voor volume. Met deze tag kun je mappen koppelen tussen de container en de lokale machine. In computertaal heet dit mounten.

In het bovenstaande commando mounten we dus de lokale map /etc/docker/test-mysql naar de map /etc/mysql/conf.d van de container. Dit koppelt de inhoud van beide mappen. Alle wijzigingen in een van beide mappen worden in beide weerspiegeld.

Met mounten kunnen we het bestand my.cnf op onze lokale machine bewerken om de configuraties van Docker-containers te wijzigen. En het mooiste is dat de aangepaste configuraties op onze lokale machine blijven bestaan, zelfs nadat de container is gestopt of verwijderd. Ze zijn herbruikbaar.

Welke configuraties kunnen we na deze stap aanpassen? Het antwoord hangt af van je usecase. We behandelen ze hieronder.

Wil je Docker-gecertificeerd worden? Bekijk onze gids voor het behalen van een Docker-certificering!

Welke opties moet je configureren?

Hoewel de standaardconfiguratie voor MySQL-Dockercontainers in veel scenario’s volstaat, is het verstandig bepaalde instellingen aan te passen om prestaties, veiligheid en resourcegebruik te optimaliseren. Dit zijn enkele van de meest aangepaste configuratie-opties:

Prestaties

  • innodb_buffer_pool_size: bepaalt hoeveel geheugen wordt toegewezen aan de InnoDB buffer pool, die vaak geraadpleegde data cachet voor snellere toegang. Dit verhogen kan de prestaties verbeteren bij read-zware workloads, maar verbruikt ook meer geheugen.
  • query_cache_size: bepaalt de grootte van de querycache, die eerder uitgevoerde queries opslaat voor snellere heruitvoering. Dit verhogen kan helpen bij repetitieve queries, maar kost meer geheugen en is mogelijk niet effectief bij dynamische queries.
  • thread_pool_size: bepaalt het maximale aantal gelijktijdige verbindingen dat de server aankan. Pas deze waarde aan op basis van je verwachte verkeersbelasting om resources te optimaliseren en knelpunten te voorkomen.

Beveiliging

  • bind-address: beperkt de MySQL-server tot luisteren op specifieke netwerkinterfaces, waardoor toegang vanuit onbevoegde bronnen wordt beperkt.
  • mysql_bind_host: zorgt ervoor dat de MySQL-server aan specifieke IP-adressen kan binden in plaats van op alle interfaces te luisteren.
  • validate_password_policy: activeert strengere wachtwoordvereisten voor betere beveiliging.

Resourcegebruik

  • max_connections: bepaalt het maximale aantal gelijktijdige verbindingen. Het aanpassen van deze waarde kan resource-uitputting voorkomen en zorgen voor efficiënte serverwerking.
  • innodb_file_per_table: slaat elke InnoDB-tabel op in een apart bestand, wat de prestaties mogelijk verbetert maar meer opslagruimte vraagt.
  • innodb_io_capacity: stelt de geschatte IOPS (Input/Output Operations Per Second) voor het opslagsysteem in, zodat de engine het bufferpoolgebruik en schijfoperaties kan optimaliseren.

Andere veelvoorkomende aanpassingen

  • character_set_server: stelt de standaardtekenset voor de server in, voor consistente codering en verwerking van data.
  • collation_server: bepaalt de standaardcollatie voor sorteren en vergelijken van tekstgegevens.
  • log_bin: schakelt binair loggen van serveractiviteit in, wat nuttig kan zijn voor troubleshooting en replicatie.

Om de volledige lijst met configuratie-opties te zien, kun je het volgende commando draaien:

$ docker run -it --rm mysql:tag --verbose --help

Je kunt het .cnf-bestand bewerken met elke teksteditor. Dit is de syntax die je moet volgen:

[mysqld]
max_connections=200
other_params=value
...

Hoe bewaar je data die is opgeslagen in de MySQL Docker-container

Het blijvend opslaan van data in je MySQL-containers is om veel redenen cruciaal:

  • Datapersistentie: wanneer je een container stopt of verwijdert, gaat alle data verloren, inclusief je database. Door de data los te koppelen van de container blijft deze altijd toegankelijk.
  • Data delen tussen containers: door de data los te koppelen van de container kunnen meerdere containers er toegang toe hebben. Zo voorkom je dataduplicatie en vereenvoudig je synchronisatie tussen projecten die dezelfde data gebruiken.
  • Draagbaarheid en back-up: persistente data kan eenvoudig worden geback-upt en onafhankelijk gedeeld, wat een betrouwbare manier biedt om te herstellen van dataverlies of per ongeluk verwijderen.
  • Betere prestaties en schaalbaarheid: door vaak geraadpleegde data op persistente opslag zoals SSD’s te zetten, kun je de prestaties verbeteren vergeleken met de beschrijfbare laag van de container, die meestal trager is.

De werkwijze heb je al gezien — we maken een volume en mounten dat op de plek waar de data in onze container wordt opgeslagen. Dit zijn de stappen:

1. Maak een volume:

$ docker volume create test-mysql-data

Het commando volume create maakt op je lokale bestandssysteem een toegewezen opslag voor het volume. Nadat het volume is gemount, wordt alle containerdata eraan gekoppeld.

2. Start de container opnieuw met het volume gemount:

$ docker stop test-mysql; docker rm test-mysql
$ docker run \
   --name test-mysql \
   -v test-mysql-data:/var/lib/mysql \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -d mysql

Dit keer is de syntax in dit formaat: -v volume_name:directory_in_container. Alle aangemaakte volumes moeten worden gemount op de map /var/lib/mysql, zoals gespecificeerd in de MySQL-imagedocumentatie.

Alle databases of tabellen die nu in test-mysql worden gemaakt, blijven lokaal bewaard, ook nadat de container is gestopt of verwijderd.

Het definitieve commando

In de loop van het artikel is ons docker run-commando flink geëvolueerd. Laten we alle varianten samenvoegen tot één definitief mastercommando. We moeten de container weer stoppen en verwijderen. We verwijderen ook het volume om helemaal schoon te beginnen:

$ docker stop test-mysql; docker rm test-mysql
$ docker volume rm test-mysql-data

Hier is het definitieve mastercommando:

$ docker run \
   --name final-mysql \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -p 3307:3306 \
   -v /etc/docker/test-mysql:/etc/mysql/conf.d \
   -v final-mysql-data:/var/lib/mysql \
   -d mysql

Dit commando mount ons eerdere lokale my.cnf-bestand naar de gewenste locatie en maakt bovendien een nieuw volume met de naam final-mysql-data aan en mount dat.

Complexe MySQL-setups beheren met Docker Compose

Voor meer geavanceerde setups met meerdere containers, zoals MySQL naast andere services (bijv. webservers of applicatie-backends), vereenvoudigt Docker Compose het proces doordat je multi-containerapplicaties met één configuratiebestand kunt definiëren en beheren.

Hier is een eenvoudig voorbeeld van een docker-compose.yml-bestand voor een MySQL-container:

version: '3.9'
services:
  db:
    image: mysql:8.3.0
    container_name: mysql-db
    environment:
      MYSQL_ROOT_PASSWORD: strong_password
      MYSQL_DATABASE: example_db
      MYSQL_USER: user
      MYSQL_PASSWORD: user_password
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql
      - ./mysql-config:/etc/mysql/conf.d
volumes:
  db_data:

Stappen om Docker Compose te gebruiken:

  • Maak een docker-compose.yml-bestand: Sla het configuratiebestand op in je projectmap.
  • Start de services: Voer het volgende commando uit om alle services in het bestand te starten:
docker-compose up -d
  • Stop de services: Zet de services uit als je klaar bent:
docker-compose down

Voordelen van Docker Compose voor MySQL:

  • Vereenvoudigde configuratie: Beheer MySQL-configuraties, poorten en volumes in één bestand.
  • Makkelijker schalen: Schaal de database eenvoudig op of integreer met andere services in je stack.
  • Persistente data: Beheer volumes automatisch voor datapersistentie over containerherstarts heen.

Docker Compose is vooral handig voor het beheren van meerdere omgevingen (bijv. development, staging en productie) of bij samenwerking in teams.

Conclusie

Dit artikel behandelde de essentie van het draaien en beheren van MySQL-databases in Docker-containers. We hebben geleerd hoe je MySQL-images downloadt en instelt, MySQL-servers in containers start, en hoe je die containers aanpast en volumes toevoegt voor aangepaste configuratie en datapersistentie.

Wil je meer leren over dit onderwerp? Dan raad ik de volgende bronnen aan:

Bedankt voor het lezen!

FAQs

Kan ik Docker Compose gebruiken om meerdere MySQL-containers te beheren?

Ja, Docker Compose is een uitstekend hulpmiddel om meerdere Docker-containers te beheren, waaronder MySQL. Je kunt je MySQL-serviceconfiguraties definiëren in een docker-compose.yml-bestand, zodat je meerdere services met één commando kunt starten, stoppen en beheren.

Hoe upgrade ik MySQL naar een nieuwere versie in een Docker-container?

Om MySQL in een Docker-container te upgraden, moet je de nieuwe versie van de MySQL Docker-image pullen en vervolgens je container opnieuw aanmaken met deze nieuwe image. Zorg dat je back-ups van je data hebt voordat je met de upgrade begint.

Kan ik meerdere MySQL-containers op dezelfde host draaien?

Ja, je kunt meerdere MySQL-containers op dezelfde host draaien. Elke container moet een unieke poort op de host toegewezen krijgen met de -p-optie om poortconflicten te vermijden.

Wat zijn de beste beveiligingspraktijken voor het draaien van MySQL-containers?

Beveiligingsbest practices omvatten: stel MySQL-containers niet bloot aan het publieke internet zonder adequate beveiliging, gebruik sterke wachtwoorden, update Docker- en MySQL-images regelmatig en gebruik Docker secrets voor gevoelige informatie zoals wachtwoorden.

Hoe kan ik het back-uppen van MySQL-databases in Docker automatiseren?

Je kunt back-ups automatiseren door een cronjob op de hostmachine te maken die docker exec gebruikt om mysqldump binnen de container uit te voeren. Als alternatief kun je Docker-volumes gebruiken om data persistent op te slaan en back-ups rechtstreeks vanaf de host af te handelen.

Kan ik vanuit een andere container verbinding maken met de MySQL Docker-container?

Ja, je kunt verbinden vanuit een andere container door ervoor te zorgen dat beide containers op hetzelfde Docker-netwerk zitten. Je kunt de containernaam als hostnaam gebruiken bij het verbinden.

Hoe los ik verbindingsproblemen met mijn MySQL-container op?

Los verbindingsproblemen op door te controleren of de container draait (docker ps), de poortkoppelingen te verifiëren (docker port), netwerkconfiguraties te controleren en te zorgen dat de MySQL-server in de container is geconfigureerd om verbindingen van je host of andere containers te accepteren.

Is het mogelijk een aangepast MySQL-configuratiebestand te gebruiken zonder het vanaf de host te mounten?

Ja, je kunt binnen de container een aangepast configuratiebestand maken. Maar het is gebruikelijker om het vanaf de host te mounten voor eenvoudiger beheer en persistentie.

Hoe kan ik de prestaties van mijn MySQL-container monitoren?

Je kunt prestaties monitoren met tools zoals mysqladmin voor MySQL-specifieke metrics, de ingebouwde stats-opdracht van Docker (docker stats), of third-party monitoringoplossingen zoals Prometheus met exporters voor Docker en MySQL.

Wat moet ik doen als mijn MySQL Docker-container crasht?

Als je container crasht, bekijk dan eerst de logs met docker logs <container_name> om fouten te identificeren. Controleer of je configuratie en omgevingsvariabelen kloppen, en verifieer dat er geen resourcebeperkingen zijn (CPU, geheugen). Start de container opnieuw en monitor de prestaties.

Bexruz (Bex) Tuychiev

Auteur

Bexruz (Bex) Tuychiev

Ik ben een contentmaker op het gebied van data science met meer dan 2 jaar ervaring en een van de grootste achterbannen op Medium. Ik schrijf graag uitgebreide artikelen over AI en ML met een vleugje sarcastische stijl, want je moet toch íets doen om ze wat minder saai te maken. Ik heb meer dan 130 artikelen en een DataCamp-cursus gemaakt, en er is nog een nieuwe in de maak. Mijn content is door meer dan 5 miljoen paar ogen gezien, van wie 20k volgers werden op zowel Medium als LinkedIn. 

Onderwerpen

Gerelateerd