Laravel getaddrinfo() in docker-compose

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Kleerkast
  • Registratie: November 2017
  • Laatst online: 28-09-2023
Ik gebruik docker-compose om mijn service te containerizen, en om het een database te geven:

Docker-compose:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
version: "3.8"
services:
  authdb:
    image: mariadb:latest
    container_name: authdb
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_PASSWORD=secret
      - MYSQL_USER=foo
      - MYSQL_DATABASE=bar
    healthcheck:
      test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD

  authapi:
    depends_on:
      - authdb
    build: api/auth
    ports:
      - 8081:8181


Ik weet dat docker-compose standaard een netwerk aanmaakt, en je dus de containers kan aanspreken op hun naam. Dus ik heb dit in mijn .env gezet:

code:
1
2
3
4
5
6
DB_CONNECTION=mysql
DB_HOST=authdb
DB_PORT=3306
DB_DATABASE=bar
DB_USERNAME=foo
DB_PASSWORD=secret


Maar dan krijg ik de volgende error wanneer ik docker-compose up doe:

code:
1
2
3
4
5
 > [ 9/10] RUN php artisan migrate:
#13 0.233
#13 0.233    Illuminate\Database\QueryException
#13 0.233
#13 0.233   SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for authdb failed: Name does not resolve (SQL: select * from information_schema.tables where table_schema = swypurr and table_name = migrations and table_type = 'BASE TABLE')


Ik weet oprecht niet helemaal wat hier fout gaat. Maak ik misschien de containers in de verkeerde volgorde aan? Kan het zijn dat de database nog niet draait wanneer Laravel 'm probeert te benaderen? Ik heb al verschillende dingen geprobeerd; de naam tussen quotes te zetten, de containers in een andere volgorde te bouwen maar niks werkt...

Ik gebruik gewoon Laravel, dus geen Sail o.i.d.

Beste antwoord (via Kleerkast op 30-03-2022 20:24)


Verwijderd

Het probleem zit hem in het feit dat je runtime variabelen gebruikt (in dit geval je environment variables), in een build time omgeving (in dit geval het bouwen van je Docker image).

Mijn advies is om het migreren van je database niet in je Dockerfile te doen, maar runtime nadat je Docker container is opgestart. Een Docker image houd je het liefst zo stateless en op zichzelf staand mogelijk, en je hebt nu eigenlijk een dependency op je database ingebakken. Bij het builden van Docker images is er helemaal geen sprake van networks of volumes in de context van docker-compose.

Alle reacties


Acties:
  • +1 Henk 'm!

  • borft
  • Registratie: Januari 2002
  • Laatst online: 26-09 22:38
Je specificeert geen netwerk. Is er een default netwerk aangemaakt? Weet je zeker dat de db up is? (docker-compose ps) en als je met de hand verbindt met de authapi container, kan je dan wel handmatig authdb resolven?

Acties:
  • 0 Henk 'm!

  • Kleerkast
  • Registratie: November 2017
  • Laatst online: 28-09-2023
borft schreef op dinsdag 29 maart 2022 @ 15:32:
Je specificeert geen netwerk. Is er een default netwerk aangemaakt? Weet je zeker dat de db up is? (docker-compose ps) en als je met de hand verbindt met de authapi container, kan je dan wel handmatig authdb resolven?
Nou dat weet ik dus niet of ie draait. Docker-compose faalt met deze error, en wanneer ik daarna docker ps doet staat er niets...

Docker-compose maakt (als 't goed is) een default netwerk aan.

Acties:
  • 0 Henk 'm!

  • borft
  • Registratie: Januari 2002
  • Laatst online: 26-09 22:38
Kleerkast schreef op dinsdag 29 maart 2022 @ 15:38:
[...]


Nou dat weet ik dus niet of ie draait. Docker-compose faalt met deze error, en wanneer ik daarna docker ps doet staat er niets...

Docker-compose maakt (als 't goed is) een default netwerk aan.
Hmm, allicht dat je db container nog niet klaar is met opstarten dan? of misschien dat ie faalt?

met `docker ps -a` kan je alles zien, dan moet je met `docker logs <id>` kunnen zien of er output was.

je docker-compose ziet er wmb goed uit, ik heb een nagenoeg zelfde setup draaien hier.

als je alleen de db opstart (docker-compose up -d authdb) werkt dat wel?


Wat trouwens ook kan helpen, is zorgen dat de auth-api container even wacht, en opnieuw probeert te verbinden als het niet lukt.

[ Voor 14% gewijzigd door borft op 29-03-2022 16:02 ]


Acties:
  • 0 Henk 'm!

  • kutagh
  • Registratie: Augustus 2009
  • Laatst online: 22:17
Dubbelcheck: de migratie command staat in de Dockerfile van de api? Dat is te vroeg, bij een standaard docker-compose up worden eerst images gemaakt en daarna pas containers in de lucht gebracht. Tijdens images maken bestaat de authdb container dus nog niet.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het migreren van de DB zul je inderdaad niet moeten doen in het builden van je applicatie container, immers is er build-time nog geen container/db waar je tegen kunt praten. Als je het al bij het bouwen van de container wil doen dan zul je het in het bouwen van je DB host container moeten doen.

Een andere optie is om het runtime vanuit je applicatie/api te doen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Waar draait je PHP? Uiteindelijk moeten je PHP en MySQL met elkaar kunnen communiceren. Je moet dus zorgen dat de task/container waar in PHP draait in hetzelfde netwerk zit als je 'authdb' task.

Zoals @Woy aangeeft is dat tijdens een build nog niet het geval, dus dan gaat het helemaal niet werken, maar ook daarna mis ik dus het netwerk. Binnen dezelfde stack zou dat niet nodig moeten zijn, maar ik weet niet wat 'api/auth' is en wat het resultaat is. Kun je niet gewoon een docker image builden en dan twee services in een stack zetten?

[ Voor 22% gewijzigd door Oon op 30-03-2022 09:47 ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
@Oon volgens mij is er een default shared network als je 2 services binnen 1 docker-compose file specificeert (en geen andere dingen voor netwerk specificeert), dus nadat de images opgestart worden zouden ze gewoon op deze manier moeten kunnen communiceren. Maar dat is dan wel run-time, niet build-time.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Woy schreef op woensdag 30 maart 2022 @ 09:52:
@Oon volgens mij is er een default shared network als je 2 services binnen 1 docker-compose file specificeert (en geen andere dingen voor netwerk specificeert), dus nadat de images opgestart worden zouden ze gewoon op deze manier moeten kunnen communiceren. Maar dat is dan wel run-time, niet build-time.
Wel als PHP daarin draait ja, maar dan ga je er dus vanuit dat PHP + Nginx + de Laravel code binnen 'authapi' draaien en is die service niet meer single-purpose.

Ik zeg niet dat TS het niet mag doen, maar dat gaat wel een beetje tegen het idee van Docker in, dus ik vraag me af waar PHP (die uiteindelijk de verbinding naar MySQL legt/uitvoert) draait, want dat is wel een belangrijk detail. Als TS een losse PHP-FPM service heeft draaien dan zal er toch echt een external network voor gedefinieerd moeten worden

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Oon schreef op woensdag 30 maart 2022 @ 09:55:
[...]

Wel als PHP daarin draait ja, maar dan ga je er dus vanuit dat PHP + Nginx + de Laravel code binnen 'authapi' draaien en is die service niet meer single-purpose.
Als ik de TS zo zie ga ik er eigenlijk van uit dat er helemaal geen Nginx in het spel is, maar gewoon een container die een PHP api moet serveren (authapi) en een mariadb container die de DB moet bevatten (authdb). Maar dat zijn natuurlijk aannames, maar aangezien de TS aangeeft dat deze code deze fout geeft lijkt het mij niet vreemd om aan te nemen dat de
code:
1
RUN php artisan migrate

In de docker file uit
code:
1
build: api/auth

staat, en dus gewoon het doel is het in dezelfde docker-compose netwerk te draaien.

[ Voor 4% gewijzigd door Woy op 30-03-2022 10:01 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • borft
  • Registratie: Januari 2002
  • Laatst online: 26-09 22:38
Als dat het geval is, gaat het met een docker-compose up niet werken.

Oplossing is dan:
Bash:
1
2
3
docker-compose up -d authdb
docker-compose build
docker-compose up -d --no-deps

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
borft schreef op woensdag 30 maart 2022 @ 10:14:
Als dat het geval is, gaat het met een docker-compose up niet werken.

Oplossing is dan:
Bash:
1
2
3
docker-compose up -d authdb
docker-compose build
docker-compose up -d --no-deps
Ik vraag mij af of die build dan wel in hetzelfde netwerk zit, maar sowieso lijkt het mij niet echt een goede oplossing

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • Beste antwoord
  • +3 Henk 'm!

Verwijderd

Het probleem zit hem in het feit dat je runtime variabelen gebruikt (in dit geval je environment variables), in een build time omgeving (in dit geval het bouwen van je Docker image).

Mijn advies is om het migreren van je database niet in je Dockerfile te doen, maar runtime nadat je Docker container is opgestart. Een Docker image houd je het liefst zo stateless en op zichzelf staand mogelijk, en je hebt nu eigenlijk een dependency op je database ingebakken. Bij het builden van Docker images is er helemaal geen sprake van networks of volumes in de context van docker-compose.

Acties:
  • 0 Henk 'm!

  • borft
  • Registratie: Januari 2002
  • Laatst online: 26-09 22:38
Woy schreef op woensdag 30 maart 2022 @ 17:18:
[...]

Ik vraag mij af of die build dan wel in hetzelfde netwerk zit, maar sowieso lijkt het mij niet echt een goede oplossing
Ja, het is ranzig, db migraties moet je natuurlijk niet in je build process doen.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 30-09 16:40

Janoz

Moderator Devschuur®

!litemod

Oon schreef op woensdag 30 maart 2022 @ 09:55:
Wel als PHP daarin draait ja, maar dan ga je er dus vanuit dat PHP + Nginx + de Laravel code binnen 'authapi' draaien en is die service niet meer single-purpose.
Dit triggerde me eigenlijk wel een beetje. Ik ben zelf niet zo bekend met PHP in docker draaien, maar dat komt meer omdat ik eigenlijk nauwelijks wat met PHP doe. Echter zou ik verwachten voor het draaien van een PHP website in docker dat je iig laravel en php in een image hebt zitten. Daarnaast verwacht ik ook een (eventueel erg simpele) webserver in dat image want ik neem niet aan dat je een cli variant gaat deployen die voor elk request weer een instantie start.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Janoz schreef op vrijdag 1 april 2022 @ 09:38:
[...]

Dit triggerde me eigenlijk wel een beetje. Ik ben zelf niet zo bekend met PHP in docker draaien, maar dat komt meer omdat ik eigenlijk nauwelijks wat met PHP doe. Echter zou ik verwachten voor het draaien van een PHP website in docker dat je iig laravel en php in een image hebt zitten. Daarnaast verwacht ik ook een (eventueel erg simpele) webserver in dat image want ik neem niet aan dat je een cli variant gaat deployen die voor elk request weer een instantie start.
Laravel is niet meer dan je codebase, het is geen app die je kan draaien ofzo. Of ja, je kan wel via Artisan een ingebouwde server starten, maar dat is niet gebruikelijk. Er is ook een image voor Laravel waarmee je snel kan beginnen, maar die gaat ook al tegen het idee van Docker in en is alleen bedoeld voor development, dus als je toch de moeite doet kun je beter voor development ook meteen een fatsoenlijke setup opzetten.

PHP draai je als het goed is gewoon in FPM-modus, waarbij PHP gewoon een service is die je in een losse container draait en blijft draaien. Die kan evt. voor meerdere projecten gebruikt worden. Daarnaast heb je dan een proxy container (nginx of apache meestal) voor de ingang, die request die eindigen in .php doorstuurt naar je PHP service. PHP pakt dan dat verzoek op en stuurt de response terug via je proxy.

Dus dan krijg je twee tasks; een nginx en een PHP. Beiden hebben toegang tot je codebase (dus je Laravel project). Daarnaast heb je dan de database, waar PHP mee moet kunnen communiceren, maar daar hoeft nginx niks mee te kunnen.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 30-09 16:40

Janoz

Moderator Devschuur®

!litemod

Ik weet dat Laravel inderdaad meer een soort dependency is. Ik vond het wat vreemd staan bij de opsomming eerder, maar dat heb ik verkeerd gelezen ;). Maar wat je zegt is dat je je daadwerkelijke php applicatie vervolgens als een soort volume in je php-fpm container hangt? En waarom zou nginx toegang tot je codebase moeten hebben? dat zou toch alleen maar de php-container hoeven zijn? Of is dat voor de static content?

Klopt het als ik zeg dat in jouw omschrijving je juist php als de service ziet die je aanbied?

Ikzelf doe meer Java en wat python. Ik ben eerder gewend om juist mijn ontwikkelde applicatie als service te zien. Een opgeleverd image bevat dan de door mij ontwikkelde applicatie en zijn dependencies. In het geval van een webapplicatie zit er dan vaak een rudimentaire webserver in en publiceert hij poort 80.

Zou ik dat doortrekken naar php dan zou ik verwachten dat je de php code in je image op zou nemen. Je zou dan niet een php image hebben, maar een 'myApp' image. Dat lijkt me wat lastig met zo'n FPM image omdat je dan de helft van je applicatie (de code) op de ene manier ontsluit, terwijl de webserver op een andere manier bij de static content moet komen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • +1 Henk 'm!

  • kutagh
  • Registratie: Augustus 2009
  • Laatst online: 22:17
Uiteindelijk is het uitgangspunt van docker zelf dat er maar 1 proces is die gedurende de hele lifecycle van de container draait (waarbij die proces andere processen mag starten en stoppen). Dat impliceert al een scheiding tussen nginx en php-fpm. Daarnaast kan het zijn dat je php-fpm sneller moet opschalen dan nginx (simpel foto weergeven vanuit nginx is minder zwaar dan php code parsen en uitvoeren), waardoor je dus met nginx en php-fpm minder onnodige nginx instances draait.

Zou je inderdaad een webserver gebruiken die zelf ook de php code kan uitvoeren (a la nodejs' express), dan heb je inderdaad maar 1 image nodig. Dat is in php wereld nog niet zo gebruikelijk als apache of nginx i.c.m. php-fpm.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 30-09 16:40

Janoz

Moderator Devschuur®

!litemod

Ik bedoelde ook zeker niet dat nginx en php in hetzelfde image terecht zouden moeten komen. Dat is in mijn voorbeeld ook niet zo. Het engie verschil is dat in mijn geval nginx (of treafik of wat dan ook) meer als een reversed proxy werkt waarbij de communicatie werkt via http terwijl het in jouw voorbeeld nginx en fpm-php communiceren via fastcgi.

Maar uiteindelijk is het dan wel zo dat 'php hosting' je service is en de daadwerkelijke webapplicatie de content op een volume.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Janoz schreef op vrijdag 1 april 2022 @ 11:13:
Ik weet dat Laravel inderdaad meer een soort dependency is. Ik vond het wat vreemd staan bij de opsomming eerder, maar dat heb ik verkeerd gelezen ;). Maar wat je zegt is dat je je daadwerkelijke php applicatie vervolgens als een soort volume in je php-fpm container hangt? En waarom zou nginx toegang tot je codebase moeten hebben? dat zou toch alleen maar de php-container hoeven zijn? Of is dat voor de static content?
Nginx hoeft alleen bij de static content te kunnen inderdaad, dus die kun je (ivm veiligheid) nog verder afsplitsen. Dan hoef je echt alleen maar je public mapje in nginx beschikbaar te stellen, met daarin ook de de evt. assets die je met 'vendor:publish' daarheen hebt gestuurd en je eigen assets en uploads e.d.
Klopt het als ik zeg dat in jouw omschrijving je juist php als de service ziet die je aanbied?
Ja en nee, je hebt gewoon een PHP service en een nginx service, daarmee kun je PHP-code uitvoeren vanuit je browser, en Laravel is één van de frameworks die je daarin kunt gebruiken. Laravel is niets meer dan een groepje libraries/packages met een beetje wrapper code eromheen, dus Laravel zelf is geen service.
Ikzelf doe meer Java en wat python. Ik ben eerder gewend om juist mijn ontwikkelde applicatie als service te zien. Een opgeleverd image bevat dan de door mij ontwikkelde applicatie en zijn dependencies. In het geval van een webapplicatie zit er dan vaak een rudimentaire webserver in en publiceert hij poort 80.

Zou ik dat doortrekken naar php dan zou ik verwachten dat je de php code in je image op zou nemen. Je zou dan niet een php image hebben, maar een 'myApp' image. Dat lijkt me wat lastig met zo'n FPM image omdat je dan de helft van je applicatie (de code) op de ene manier ontsluit, terwijl de webserver op een andere manier bij de static content moet komen.
In Java, Python, of bijv. NodeJS zit het inderdaad iets anders, want daar is de webserver deel van je applicatiecode. In het geval van PHP trek je die webserver los (nginx), PHP-FPM kun je dan een beetje als de JVM voor de PHP-code zien, en de daadwerkelijke broncode (dus de niet-gecompileerde .java bestanden) worden ingelezen door PHP-FPM.

Je hebt geen binary die je compileert in PHP, alleen een scheiding tussen clientside assets (die je uit nginx serveert) en serverside code (die door PHP-FPM lopen). Je request komt in nginx binnen, nginx kijkt wat je hebt geconfigureerd en of het naar PHP moet, en nginx stuurt dan het antwoord, dus statische bestanden kunnen volledig zonder PHP terug naar de browser zonder dat het je 'applicatie' überhaupt binnen gaat.

In plaats van dat je applicatie het entrypoint is, is dat dus nginx, en daarna PHP als nginx dat nodig vindt. Pas als je naar PHP gaat komt je eigen code er bij kijken, maar zelfs dan boeit het PHP-FPM niet wat die code doet zolang er maar geen foutmeldingen uit komen, en PHP-FPM geeft indien je output hebt deze weer terug aan nginx.

Zoals jij je in je meest recente reactie zegt is inderdaad de code dus maar gewoon op disk (of in een volume). Shared hosting omgevingen werken over het algemeen niet met docker, maar daar zou je dan bijvoorbeeld een nginx en een PHP-service hebben per gebruiker, die dan toegang heeft tot het mapje van die gebruiker en waar de domeinnamen van die gebruiker naar worden verwezen.

Acties:
  • 0 Henk 'm!

  • kutagh
  • Registratie: Augustus 2009
  • Laatst online: 22:17
Janoz schreef op vrijdag 1 april 2022 @ 15:38:
Ik bedoelde ook zeker niet dat nginx en php in hetzelfde image terecht zouden moeten komen. Dat is in mijn voorbeeld ook niet zo. Het engie verschil is dat in mijn geval nginx (of treafik of wat dan ook) meer als een reversed proxy werkt waarbij de communicatie werkt via http terwijl het in jouw voorbeeld nginx en fpm-php communiceren via fastcgi.

Maar uiteindelijk is het dan wel zo dat 'php hosting' je service is en de daadwerkelijke webapplicatie de content op een volume.
Ah zo, code binnen de image opnemen vs buiten image houden.

Voor lokaal ontwikkelwerk met interpreted languages is het meestal zinniger om de code buiten de image te houden, aangezien je dan minder stappen nodig hebt om met de nieuwste versie van je code te werken. Dit komt ook een beetje terug in het werken met docker, aangezien docker alleen nieuwe images bouwt of download wanneer er geen image aanwezig is of wanneer er expliciet een bouw instructie wordt gegeven aan docker. Waarschijnlijk is dat minder een probleem met talen waar toch al expliciete build instructies voor nodig zijn, waardoor je de docker build & nieuwe containers in lucht brengen erin kan integreren.

Als je de images wilt uitrollen naar TAP, is het inderdaad zuiverder om de code in de image zelf te bewaren. Je zal echter altijd nog een stukje configuratie hebben die je buiten de image houdt en bijvoorbeeld via environment inricht (welke wederom dus pas runtime beschikbaar is, dus nog steeds geen migraties tijdens build :+ ).
Pagina: 1