Standaard in docker is het moeilijk om twee containers met elkaar te laten praten. Dit is natuurlijk de bedoeling want we willen verschillende containers namelijk afschermen van elkaar.
Om toch te verbinden met de host kan je volgende adressen gebruiken:
- op Windows:
host.docker.local
- op Linux (hoogstwaarschijnlijk):
172.17.0.1
Demo 1: Connect server to database
Networking in docker
Het default netwerk dat docker gebruikt is van het type “bridge” en vormt letterlijk een brug tussen de host en de container. Elke container waarvoor je zelf geen specifiek netwerk instelt zal de “default bridge” gebruiken. Je kan zelf netwerken aanmaken en containers aan verbinden. Er bestaan verschillende types, maar degene die wij het meeste gaan gebruiken is de bridge. Andere interessante types zijn host (laat de container runnen alsof het letterlijk een deel vormt van het host netwerk. Container gebruikt dan dezelfde poorten als de host) en macvlan. Dit laatste type is redelijk complex maar zorgt ervoor dat je container op je (wifi)netwerk als een apart device beschouwd wordt met een eigen ip-adres. We gaan hier niet verder op in maar volgende video geeft een mooi overzicht van de verschillende mogelijkheden: Docker networking - You need to learn it Of je kan natuurlijk de officiĆ«le documentatie raadplegen.
Networking in docker-compose
Wanneer je meerdere services plaatst in dezelfde docker-compose file wordt automatisch een nieuw bridge netwerk gemaakt en verbonden aan de host en al die services. Je kan dan contact opnemen met andere services door hun naam te gebruiken. Je hoeft dus niet hun ip address uit te pluizen! Hieronder zo een voorbeeld van een docker-compose file om een Flask applicatie data uit een database te laten halen (uit een andere container):
docker-compose file
services:
server:
container_name: flask_server
restart: unless-stopped
build:
context: .
dockerfile: ./Dockerfile
ports:
- 5006:5000
volumes:
- ./app:/app
networks:
- mynetwork
# Met depends_on laat je weten dat eerst de "db" service moet starten omdat een deel/delen van deze container moeten communiceren met die service
depends_on:
- db
db:
image: mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: example
volumes:
- ./mydata:/var/lib/mysql:Z
networks:
- mynetwork
adminer:
image: adminer
restart: always
ports:
- 9092:8080
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
Flask app.py
from flask import Flask, render_template_string
import pymysql
app = Flask(__name__)
# Database connection
def get_db_connection():
return pymysql.connect(
# GEBRUIK DE SERVICE NAAM "db" ALS IP-ADRES !!!
host="db",
user="root",
password="example",
database="school",
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
...
De volledige implementatie is terug te vinden op github. (zie menu)
Exercise 1:
Maak analoog aan de demo twee containers aan maar gebruik nu een java container als frontend om de data uit de database te tonen. Je mag de data door je java programma gewoon in de console laten printen. TIP: maak gebruik van een build tool zoals Gradle. (Zoek dus even uit hoe je java image/container eruit moet zien.)