Docker-perusteet

komentorivi

 

Tässä artikkelissa tutustutaan lyhyesti keskeisimpiin Dockerin perusteisiin, jotka antavat hyvän pohjan jatko-opinnoille ja helpottavat ymmärtämään Dockerin käyttöä.

Asennus

Tämä artikkeli olettaa, että olet asentanut Dockerin. Docker tarjoaa Windowsille ja MacOS:lle Docker Desktopin. Asennusohjeet löytyvät täältä: https://docs.docker.com/get-docker/. Linux-käyttäjät: koska Docker on Linuxin päällä toimiva tuote, riittää käyttöä varten Docker Enginen asennus. Ohjeet eri Linux-jakeluille löydät täältä: https://docs.docker.com/engine/install/.

Pari sanaa terminologiasta

Tässä tekstissä käytetään termiä “näköistiedosto” (englanniksi “image”) kuvaamaan tiedostoa, joka toimii “konttien” (englanniksi “container”) pohjana. Kontti siis on se asia, jota Docker käytännössä ajaa yhden tai useamman kappaleen. Näköistiedosto on muuttumaton pohja näille konteille.

Käyttö

Yksinkertaisimmillaan Dockerin käyttö on run-komennon ajamista halutulla Docker-näköistiedostolla:

docker run hello-world

Huomio: Riippuen siitä, miten Docker Engine on asennettu, Linux-käyttäjät saattavat tarvita sudo-komennon Docker-komentojen alkuun. Esimerkiksi, sudo docker run hello-world.

Esimerkkitapauksessa Docker tarkistaa, löytyykö “hello-world”-nimistä näköistiedostoa jo ladattuna tietokoneelta. Jos ei, ladataan se automaattisesti Docker Hubista. Tämän jälkeen tiedostosta luodaan “kontti”, joka ajetaan. Lopputuloksena pitäisi olla kontin tarjoama lyhyt tervehdys.

Esimerkkiprojekti

Käymme läpi Dockerin perusteet käyttäen yksinkertaista Docker-tiedostoa. Luo tekstitiedosto nimellä “Dockerfile” ja kopio alla olevat kolme riviä tiedostoon.

Dockerfile:

FROM python:3
COPY . /www
CMD ["python", "-m", "http.server", "8080"]

FROM-rivi on aina pakollinen. Rivillä määritellään, mitä valmista pohjaa käytetään kontin luontiin. Jokainen Docker-näköistiedosto rakennetaan jonkun olemassa olevan näköistiedoston päälle. Poikkeuksena ovat ns. pohjanäköistiedostot (englanniksi “base images”), joita käytetään muiden tiedostojen pohjana. Näissäkin tapauksissa FROM-rivi on pakollinen, mutta pohjatiedoston nimeksi annetaan “scratch”. Kaksoispisteen perässä oleva “3” on tagi. Tässä tapauksessa haluamme käyttää Pythonin versiota 3, joten määrittelemme sen tagin avulla. Tageista enemmän myöhemmin erillisessä artikkelissa.

COPY-rivi käskee kopioimaan paikalliset tiedostot kontin sisälle. Komennon perässä lähde- ja kohdepolut, eli tässä tapauksessa kaikki tiedostot nykyisestä paikallisesta hakemistosta ladataan kontin sisälle kansioon “/www”, joka luodaan automaattisesti kopioinnin yhteydessä.

CMD-rivi poikkeaa edellisistä riveistä siinä, että päinvastoin kuin edellä olleet komennot, sitä ei suoriteta näköistiedoston luonnin aikana, vaan määritelty komentorivi asetetaan oletuskomennoksi, joka ajetaan aina kontin ajon yhteydessä automaattisesti. Jos kontin luonnin aikana on tarve suorittaa komentoja kontin sisällä, on sitä varten olemassa komento RUN.

Komentorivi:

docker build -t mytest .

Edellä oleva komentorivi rakentaa näköistiedoston nykyisessä kansiossa sijaitsevan Dockerfile-tiedoston mukaisesti. Lopputuloksena on mytest-niminen näköistiedosto, joka on tallennettu paikallisesti Dockerin kirjastoon valmiina käyttöä varten.

Dockerin paikallisesti varastoimat näköistiedostot voi listata komennolla:

docker image ls

Luomaamme näköistiedostoa voi nyt ajaa komentamalla:

docker run -p 8080:80 mytest

Avaa webbiselain osoitteessa http://localhost:8080 ja pääset kurkistamaan kontin sisälle. Merkillepantavaa on mm. se, mitä määrittelemämme COPY-komento on kopioinut konttiin. Kansiosta www pitäisi löytyä työhakemistossamme oleva Dockerfile.

Komentorivillä annettu rimpsu -p 8080:80 kertoo Dockerille, että haluamme reitittää kontin sisällä avatun TCP-portin 80 isäntäkoneelle porttiin 8080. Dockerin komentoriveissä kaikki tällaiset kontin ja isännän väliset asiat määritellään järjestyksessä isäntä:kontti.

Syöttämällä Ctrl+C kontti sammuu.

Dockerin run-komennolla on kätevä ajella kontteja, mutta usein – kuten tässä tapauksessa HTTP-serverin kanssa – konttia olisi mukavampi ajaa taustalla varaamatta terminaalia. Tämä onnistuu lisäämällä parametri -d.

docker run -d -p 8080:80 mytest

Nyt kontti käynnistyy taustalle ja meillä on komentorivi omassa käytössämme.

Kontin sammuttaminen onnistuu yksinkertaisesti listaamalla käynnissä olevat instanssit ja antamalla tappokäsky halutulle kontille:

docker container ls

Tuloste:

Kontin sammuttaminen:

docker kill <CONTAINER ID> tai <NAME>

Container ID on yksilöivä ID, jonka avulla voidaan viitata kontteihin. Koko ID:tä ei tarvitse kuitenkaan välttämättä antaa, vaan riittää, että ID:tä kirjoittaa sen verran, että se yksilöi haluamamme kontin. Tässä tapauksessa siis riittää, että annamme ID:stä vaikkapa vain pari ensimmäistä merkkiä, yllä olevassa esimerkissä “d3”. Docker generoi jokaiselle kontille automaattisesti myös työnimen. Omassa esimerkkitapauksessani se on “busy_ramanujan”. Tätä nimeä voidaan vaihtoehtoisesti käyttää Docker-komentojen kanssa yksilöimään, mille kontille haluamme operaatioita kohdistettavan.

Docker luo joka ajokertaa varten puhtaan kontin näköistiedostosta. Konttia ei kierrätetä. Siitä huolimatta joka kerta, kun kontti sammutetaan, jättää Docker kontin jäänteet talteen. Tämä mahdollistaa vikatilanteissa jo ajetun kontin sisällön ja siellä olevien logitiedostojen tutkimisen. Jäänteet voi tarkistaa komennolla:

docker container ls -a

Jäämistön voi siivota pois joko yksi kerrallaan rm-komennolla tai kaikki kerralla prune-komennolla.

Yksitellen:

docker container rm <CONTAINER ID>

Kaikki sammutetut kontit kerralla:

docker container prune

Jos haluaa pitää tietokoneensa puhtaana, eikä halua säilytellä muistoja ajetuista konteista, voi sen estää lisäämällä run-komentoon parametrin --rm.

docker run --rm -d -p 8080:80 mytest

Alussa kuvasin Dockerfile-tiedostossa olevaa CMD-riviä kontin ajon aikana toteutettavaksi oletuskomennoksi. Toisin sanoen Dockerissa on tapana ajaa annetun oletuksen sijasta jotain muitakin komentoja. Tätä voidaan hyödyntää esimerkiksi silloin, kun halutaan itse mennä ajettavan kontin sisälle. Voimme esimerkiksi kurkistaa, mitä www-kansioon on kopioitu: docker run --rm mytest ls -l /www.

Koska kontit ovat lähtökohtaisesti eristetty muusta maailmasta, ei käytössä ole paikallista syöttölaitetta tai terminaalia. Ne pitää erikseen määritellä käytettäviksi lisäämällä run-komennolle määreet -i (“interactive”) ja -t (“pseudo TTY”). Näitä tarvitaan interaktiivisen terminaaliohjelman kanssa. Jos haluamme käynnistää komentorivin kontin sisälle, jonka avulla voimme tutkia konttia, voidaan käyttää Python-näköistiedoston mukana tulevaa bash-terminaalia:

docker run --rm -i -t mytest bash

Nyt voimme käyttää konttia kuten normaalia Linuxia. Voimme tutkia, mitä kontti sisältää, voimme tehdä siellä muutoksia, ajaa ohjelmia, tai asentaa kokonaan uusia kirjastoja ja sovelluksia. Kun haluamme poistua kontista, annetaan komento exit ja kontti sammuu. Ja sitä myöten kaikki kontissa tehdyt mahdolliset muutokset katoavat.

Tämä oli kevyt pintaraapaisu Docker-konttien ajamiseen. Erinomainen lähde oppia lisää komennoista: https://docs.docker.com/engine/reference/commandline/cli/

Lisäksi Dockerfile-tiedostojen tekemiseen löytyy korvaamaton tietolähde: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Seuraavassa osassa pureudumme Docker-tageihin, jotka ansaitsevat kokonaan oman artikkelinsa.

Kirjoittaja on Ouron Senior Developer Matti Kärki

Valikko