NLEN
Direct technisch advies?
Direct een ervaren DBA aan de lijn voor database hulp, support en ondersteuning. We kunnen eventueel direct met u meekijken!035 369 0304
dba@optimadata.nl
Home > Blog

How to Postgres on Docker deel 2 van 3

Craig Healey 25-9-2019 14:32
Categorieën: BLOG, Cloud, PostgreSQL, Technisch, Tips

In mijn vorige blogpost heb ik laten zien hoe je postgreSQL in een Docker-container kunt instellen, tot het punt waar je de database met psql of pgAdmin kon beheren. Ik had echter nog niet uitgelegd hoe het werkt. Als je iets anders probeert te doen, zelfs iets kleins, of als je fouten tegenkomt zoals ik heb geschetst, dan moet je weten wat al die commando's eigenlijk doen.

In deze blog leg ik je dat uit.

Docker is een verzameling van producten waarmee software in gevirtualiseerde omgevingen (containers), uitgevoerd wordt. Op Windows draaien die Docker-containers normaal gesproken in een VirtualBox. Docker maakt die VirtualBoxes aan tijdens de eerste uitvoering. De laatste keer hebben we een container gemaakt met de naam "some-postgres".

Maar waar halen we de software vandaan om een container te maken - het besturingssysteem en PostgreSQL?

Herinner je de image van de vorige blogpost (How to Postgres on Docker deel 1 van 3) op de Docker Hub genaamd Postgres? Laten we eens kijken naar de opdracht die is gebruikt om de container te maken:

Docker runDe meeste Docker commando's beginnen met het trefwoord Docker.

docker run --help

geeft je een lijst met de mogelijke opties oftewel flags.

Met de opdracht *run wordt een container gemaakt.

De flag *--name definieert een naam. Containers zijn bijzonder in Docker. Als je ze geen naam geeft, krijgen ze een standaardnaam, zoals angry_davinci, jolly_wing of tender_banach. Voor de meeste andere Docker-objecten geldt dat als je geen naam opgeeft, Docker een hash-key zal genereren en die vervolgens gebruiken. In dit geval heb ik "some-postgres" gebruikt, zoals voorgesteld op de postgres Hub-pagina.

Poorten

De volgende flag definieert de poort van de container. Alle flags hebben een naam met meerdere tekens voorafgegaan door 2 streepjes (POSIX-standaard), maar sommige flags hebben ook een alias die uit één teken bestaat. Ik had dus kunnen gebruiken *-p 5432:5432 of *--publish 5432:5432. Het eerste nummer staat voor de externe- en het tweede - voor de interne poort.

De default poort voor PostgreSQL-servers is 5432. Dus als we meerdere PostgreSQL-containers maken die op de defaultpoort draaien (wat we hierna gaan doen), moeten we ze verschillende externe poorten opgeven. Als ik 3 van dergelijke containers wilde maken die allemaal tegelijkertijd vanuit pgAdmin konden worden benaderd, zou ik de volgende flags gebruiken:

-p 5432:5432

-p 5433:5432

-p 5434:5432 

On pgAdmin, zou ik 3 servers creeëren met de poorten 5432, 5433 en 5434.

De volgende flag, *-e of *--env, somt omgevingsvariabelen op die specifiek zijn voor de image. In dit geval willen we het postgres-gebruikerswachtwoord instellen zodat we via pgAdmin verbinding kunnen maken. Als een image dergelijke variabelen moet instellen, moeten ze ergens vermeld zijn. In het geval van deze PostgreSQL-image zijn ze halverwege de inleidende pagina gedetailleerd uitgelegd: 

De laatste flag is *-d of *--detach, waarmee we aangegeven dat de container op de achtergrond wordt uitgevoerd. Vergeet je dit en voer je het commando uit, dan kom je rechtstreeks in de container en als je weggaat, stopt de container.

Ten slotte wordt de naam van de afbeelding opgegeven, in dit geval postgres. Direct na de afbeeldingsnaam kun je een lijst met de opdrachten opgeven die de container gaat uitvoeren, maar in dit geval hoeven we dat niet te doen. 

Dockerfile

Het op deze manier opspinnen van containers geeft je niet veel controle, vooral omdat Docker de automatisering zou moeten verbeteren in plaats van de typevaardigheden. De normale manier om Docker uit te voeren is een proces in drie stappen. Eerst maakt u een tekstbestand, zogenaamd een Dockerbestand, bestaande uit een basisimage.

De basisimage zit als eerste in het Docker-bestand (je kunt ook de opmerkingen hebben, beginnend met #) en wordt voorafgegaan door het trefwoord FROM. Er is een speciale basisimage, genaamd scratch, die helemaal niets bevat. Dus, om je eigen image zelf te bouwen, zal de eerste regel van je Dockerbestand zijn:

FROM scratch

Hierna kun je alles aan je image toevoegen wat je maar wilt. Maar je hoeft niet helemaal opnieuw te beginnen. Je kan de bestaande image uitbreiden. Je kan een ubuntu-image met specifieke tools en variabelen instellen. Hierna kun je andere images maken door de verschillende versies van PostgreSQL op exact hetzelfde onderliggende besturingssysteem te installeren. Dat stelt je in staat om alleen de verschillen in PostgreSQL-versies te testen. Met behulp van het Docker-bestand bouwt je je eigen image op, net zoals die je uit de Docker-hub kunt halen. En met die image kun je een container draaien.

Images

Wij gaan een image maken op basis van de postgres-image waar we de vorige keer naar gekeken hebben. Maak een tekstbestand met de naam "Dockerfile". Docker zoekt standaard naar het Docker-bestand in de huidige werkmap (genaamd de build-context). Natuurlijk kan je Docker-opdrachten uitvoeren vanuit een command prompt of PowerShell-window, niet uitsluitend vanuit het Docker Terminal-programma. Je kunt je Docker-bestanden in elke gewenste map opslaan, gebruik gewoon de flag *-f om de bestandslocatie op te geven. Om het mezelf makkelijk te maken, maak ik een testmap in de Docker Toolbox-map. Vergeet niet dat je Linux-opdrachten moet gebruiken wanneer je je in het Terminal-venster bevindt. Dus, ls in plaats van dir, en pwd in plaats van echo %cd%. Je hebt ook toegang tot vi-editor als je wilt. Mijn Dockerfile bestaat uit slechts 2 regels:

FROM postgres

ENV POSTGRES_PASSWORD=mysecretpassword

Om het image aan te maken, type

docker build -t craig/postgres:version1 .

Vergeet niet de full stop (punt) aan het eind. Dat geeft Docker opdracht om het "Dockerfile"-bestand in de huidige directory te gebruiken. 

Docker buildJe kunt zien dat de build is een proces in twee stappen. Eerst wordt het basisimage gevonden. Als het al is gedownload, zoals hier, gaat het verder met de volgende stap, anders wordt het voor je uit de Docker Hub gehaald. Vervolgens wordt de volgende opdrachtregel toegevoegd, in dit geval is dit het POSTGRES_PASSWORD. Het betreft een tijdelijke container, die automatisch voor je wordt verwijderd. Nadat de build is voltooid en de image een image-ID heeft gekregen, krijg je een beveiligingswaarschuwing. Dat is belangrijk als je overweegt om dit voor een real-life systeem te doen, maar voor nu kun je het veilig negeren. Als ik versie 2 van het image bouw zonder het Docker bestand te bouwen, is Docker slim genoeg om te weten dat er niets hoeft te worden gewijzigd. Een nieuwe image wordt gemaakt, genaamd craig / postgres: version 2, maar de afbeelding-ID zal hetzelfde zijn als voor craig / postgres: version 1. Je ziet hier de mogelijkheid om meerdere afhankelijkheden te maken. Helaas is er geen gemakkelijke methode om afhankelijkheden te weergeven afgezien van third-party scripts and tools. Het dichtst in de buurt van een Docker-opdracht komt:

docker inspect --format='{{.Id}} {{.Parent}} {{.RepoTags}}' $(docker images -quiet)

Docker inspectDit geeft weer de sha256 van een image (waarvan de eerste 12 cijfers worden gebruikt als de image-ID), gevolgd door de eventuele bovenliggende image, zo die er is. Voor meer informatie over de opmaak van dit commando zie deze blog.

Als het tijd is om een images te verwijderen, kunt je dit niet doen als deze een onderliggende image heeft, dus kun je wellicht hier gebruik van maken om images te verwijderen die je niet langer nodig hebt. Je kan ook gebruiken: 

docker history postgres