Docker (μέρος 6) | Φτιάχνουμε τα δικά μας image με το Dockerfile και τα δημοσιεύουμε στο DockerHub

Dockerfile -> Image -> Container

Αν και στο DockerHub κυκλοφορούν άπειρα πακέτα image για να τρέξεις οποιαδήποτε υπηρεσία στο server σου, αργά ή γρήγορα θα θελήσεις να φτιάξεις τα δικά σου. Το Docker μας δίνει τη δυνατότητα να δημιουργήσουμε προσωποποιημένα image, με προεγκατεστημένες εφαρμογές και υπηρεσίες, που είναι κομμένα και ραμμένα στα μέτρα μας. Αυτό γίνεται με το Dockerfile, ένα αρχείο εντολών που εκτελεί αυτόματα όλη τη διαδικασία. Πάμε να δούμε πώς λειτουργεί.

Τι είναι και πώς ακριβώς λειτουργεί το Dockerfile;


Το Dockerfile δεν είναι τίποτα περισσότερο από ένα απλό αρχείο οδηγιών, στο οποίο γράφουμε σε κάθε γραμμή τις εντολές που θέλουμε να εκτελεστούν με τη σειρά. Στη λογική μοιάζει με το bash script που είχαμε δει τις προάλλες, αν και έχει το δικό του συντακτικό. 

Οι οδηγίες που μπορούμε να γράψουμε στο Dockerfile είναι αρκετές και μας επιτρέπουν μεταξύ άλλων να προσθέσουμε αρχεία και φακέλους στο image μας, να δημιουργήσουμε χρήστες και ομάδες, να εκτελέσουμε προγράμματα και άλλα πολλά. Πιο συγκεκριμένα μερικοί από τους πιο χρήσιμους δείκτες που μπορούμε να χρησιμοποιήσουμε είναι οι εξής:

  • FROM: Ορίζουμε το image πάνω στο οποίο θα βασιστεί το δικό μας
  • LABEL: Δίνουμε μια ετικέτα όπως για παράδειγμα μια περιγραφή για να γνωρίζουμε τι κάνει το συγκεκριμένο image.
  • USER: Δημιουργούμε νέους χρήστες και ομάδες
  • WORKDIR: Δηλώνουμε τον κεντρικό φάκελο του image 
  • RUN: Σημειώνουμε τις εντολές που θέλουμε να εκτελεστούν κατά τη διάρκεια του build
  • COPY: Επιλέγουμε τα αρχεία που θέλουμε να προστεθούν στο image μας
  • ENV: Δίνουμε πληροφορίες περιβάλλοντος όπως για παράδειγμα το username και το password μίας SQL βάσης δεδομένων 
  • EXPOSE: Ορίζουμε από ποιο port θα έχουμε πρόσβαση στην υπηρεσία που τρέχει στο image
  • CMD: Δίνουμε την εντολή που θέλουμε να εκτελεστεί αμέσως μετά την εκκίνηση του container
  • ENTRYPOINT: Ορίζουμε τη βασική εντολή του image μας κάνοντάς το εκτελέσιμο
  • ONBUILD: Σημειώνουμε οδηγίες οι οποίες θα εκτελεστούν αν το δικό μας image χρησιμοποιηθεί ως βάση για ένα άλλο

Σημείωση:
Η πλήρης λίστα των δεικτών του Dockerfile βρίσκεται στην επίσημη σελίδα του.

Διαφήμιση

Dockerfile

Παράδειγμα χρήσης του Dockerfile


Ας φτιάξουμε λοιπόν ένα Dockerfile χρησιμοποιώντας μερικούς από τους δείκτες, για να δούμε πώς λειτουργούν στην πράξη. Αρχικά δηλώνω οτι το base image που θα χρησιμοποιήσω είναι η τελευταία έκδοση του Ubuntu Linux:

FROM ubuntu:latest 

Θα του δώσω και μία ετικέτα για να γνωρίζω ανά πάσα στιγμή τι περιέχει αυτό το image:

LABEL description="Ένα Ubuntάκι με python, curl, vim και git"

Στο image μου χρειάζομαι μερικά έξτρα προγραμματάκια όπως την "python", το "curl", το "vim" και το "git", οπότε θα τα προεγκαταστήσω με την εντολή:

RUN apt update && apt install -y \
    python \
curl \
  vim \
    git

Επειδή δε θέλω να χρησιμοποιώ το χρήστη "root" στο σύστημά μου, θα δημιουργήσω εξ' αρχής το χρήστη "babis" με τις εξής εντολές:

RUN useradd -ms /bin/bash babis
USER babis

Θα πω επίσης στο Dockerfile οτι το περιβάλλον εργασίας μου θέλω να είναι ο φάκελος "/home/babis", οπότε κάθε φορά που το ανοίγω θα με βγάζει εκεί:

WORKDIR /home/babis

Στο φάκελο "tools" του υπολογιστή μου έχω κάποια αρχεία τα οποία θα μου είναι χρήσιμα και στο image. Θα τα μεταφέρω λοιπόν στο φάκελο "stuff" του image:

COPY /tools /home/babis/stuff

Ο σκοπός του image αυτού είναι να δημιουργήσω και να τεστάρω web εφαρμογές, οπότε καλό θα είναι να ορίσω εξ' αρχής το port 80 για να έχω πρόσβαση σε αυτές: 

EXPOSE 80

Τέλος επειδή τις εφαρμογές μου τις γράφω σε "Python", όταν ανοίγω το container μου θέλω να με βάζει απ' ευθείας στο αντίστοιχο περιβάλλον για να αρχίσω να δουλεύω. Αυτό γίνεται ως εξής:

CMD [ "python"]

Αυτό ήταν! Το ολοκληρωμένο Dockerfile είναι το εξής:

FROM ubuntu:latest 
LABEL description="Ένα Ubuntάκι με python, curl, vim και git"
RUN apt update && apt install -y \
    python \
curl \
    vim \
    git
RUN useradd -ms /bin/bash babis
USER babis
WORKDIR /home/babis
COPY /tools /home/babis/stuff
EXPOSE 80
CMD [ "python"]

Για να κάνω build το νέο image με βάση το Dockerfile θα δώσω την εντολή:

docker build -t chriskay/web-apps:1.0 .

Σημείωση: 
Το νέο μου image θα έχει ονομασία "web-apps", έκδοση "1.0" και εκδότη τον "chriskay". Η τελεία (.) στο τέλος της εντολής δεν είναι καθόλου τυχαία και σημαίνει οτι τα αρχεία που αναφέρονται στο Dockerfile βρίσκονται στον ίδιο φάκελο με αυτό στο σύστημά μας.

Docker build command

Για να μπω τώρα στο image μου θα δώσω την εντολή:

docker run -it chriskay/web-apps:1.0

Θα δω λοιπόν οτι με βάζει κατ' ευθείαν στο φάκελο που του έχω ορίσει και σε περιβάλλον "Python" για να αρχίσω να δουλεύω! 

Docker run command on interactive mode

Διαφήμιση

Δημιουργία Docker image υπηρεσίας και δημοσίευση στο DockerHub


Στο πρώτο παράδειγμα είδαμε πώς μπορούμε να δημιουργήσουμε ένα περιβάλλον εργασίας, κομμένο και ραμμένο στα μέτρα μας. Ένας δεύτερος λόγος για να φτιάξεις το δικό σου Docker image, είναι η δημιουργία μίας νέας υπηρεσίας την οποία θα δημοσιεύσεις μετά στο DockerHub.

Αν για παράδειγμα έχω φτιάξει ένα παιχνίδι σε python, με την ονομασία "game.py", το Dockerfile που θα γράψω για να δημιουργήσω το image μου θα μοιάζει κάπως έτσι:

FROM alpine:latest
COPY . /app
RUN make /app
CMD python /app/game.py

Σημείωση:
Με το συγκεκριμένο Dockerfile κατεβάζουμε την τελευταία έκδοση του Alpine Linux, αντιγράφουμε το φάκελο "/app" που περιέχει την εφαρμογή μας, από τον υπολογιστή στο image, τρέχουμε την εντολή "make" για να γίνει compile η εφαρμογή και τέλος ορίζουμε να τρέχει το εκτελέσιμο αρχείο του παιχνιδιού, κάθε φορά που "σηκώνουμε" το image σε container.

Για να δημιουργήσω τώρα το image με βάση το συγκεκριμένο Dockerfile, θα δώσω την εντολή:

docker build -t chriskay/puzzlegame:1.0 .

Αν είμαι ευχαριστημένος από το image μου, μπορώ τώρα να το δημοσιεύσω στο DockerHub για να το κατεβάσουν και άλλοι χρήστες. Θα πρέπει πρώτα να δημιουργήσω ένα λογαριασμό στο DockerHub (π.χ. username: "chriskay" email: "[email protected]") και στη συνέχεια να δώσω την εντολή: 

docker login --username=chriskay [email protected]

Αν δεν έχω ορίσει αριθμό έκδοσης στη διαδικασία του build ή αν θέλω να ανεβάσω μία αναβάθμιση του παιχνιδιού μου στο DockerHub, αλλάζω το TAG με την εντολή:

docker tag chriskay/puzzlegame:1.0 chriskay/puzzlegame:2.0

Τέλος ανεβάζω το νέο image στο DockerHub με την εντολή:

docker push chriskay/puzzlegame:2.0

Εν κατακλείδι


Όπως είπαμε και στην αρχή, στο DockerHub μπορούμε να βρούμε σχεδόν τα πάντα. Ο κάθε server όμως είναι διαφορετικός και η κάθε επιχείρηση έχει τις δικές της ανάγκες. Φτιάχνοντας λοιπόν τα δικά μας Docker image, μπορούμε να είμαστε σίγουροι οτι αν κάτι πάει στραβά, θα έχουμε αποθηκευμένο ένα έτοιμο περιβάλλον που είναι κομμένο και ραμμένο στις ανάγκες μας.

Ένα άλλο πλεονέκτημα που μας δίνει αυτή η διαδικασία είναι οτι τα image σου δε χρειάζεται να τα αποθηκεύεις σε κάποιο backup. Αρκεί να έχεις τα Dockerfile που έχεις δημιουργήσει, τα οποία είναι ελάχιστα σε μέγεθος και με ένα "build" μπορείς σε λίγα λεπτά να δημιουργήσεις ακριβώς το λειτουργικό σύστημα που χρειάζεσαι.

Σχόλια

Δείτε επίσης...

Φεύγω από την Google (μέρος 15) | ''Ξηλώνουμε'' τα Google apps από το Android

Android | Γιατί δε θα αγόραζα ποτέ smartphone της OnePlus

Ιδιωτικό απόρρητο | Το αφελές επιχείρημα του ''Δεν έχω τίποτα να κρύψω''

Docker (μέρος 7) | Στήνουμε έναν reverse proxy για τα container μας με το Traefik

Μάθε παιδί μου Linux (μέρος 11) | Δίσκοι, κατατμήσεις και σύστημα αρχείων (filesystem)

Ubuntu Touch 2020 review | Μια πραγματική mobile GNU/Linux διανομή έτοιμη για καθημερινή χρήση

Docker (μέρος 1) | Τι είναι και πώς το εγκαθιστούμε στον υπολογιστή μας;

Android | Περιόρισε την παρακολούθηση των εφαρμογών και κόψε τις διαφημίσεις με το TrackerControl

Απόρρητο | ''Μπερδεύουμε'' τον αλγόριθμο Google και Facebook με ψεύτικες πληροφορίες

Android | Βάλε στην ''απομόνωση'' τις εφαρμογές που δεν εμπιστεύεσαι με το Shelter