Docker (μέρος 3) | Οι βασικές εντολές για τη διαχείριση container, image, volume, network
Αφού έχουμε δει πώς γίνεται η εγκατάσταση του Docker στον υπολογιστή μας και πώς θα "σηκώσουμε" τα πρώτα μας container, ήρθε η ώρα να μιλήσουμε και για τις βασικές εντολές διαχείρισης μέσω τερματικού. Με αυτές τις εντολές θα μάθουμε πώς να βλέπουμε τις υπηρεσίες που τρέχουν ήδη στο σύστημά μας, πώς να τις σταματάμε, να τις διαγράφουμε και ακόμη περισσότερα.
Πληροφορίες συστήματος και εκκαθάριση
Για να διαχειριστείς το σύστημα του Docker πρέπει πρώτα να συλλέξεις κάποιες πληροφορίες για αυτό. Να μάθεις δηλαδή τι έχεις ήδη εγκαταστήσει, τι τρέχει σε αυτό και πόσα "σκουπίδια" έχει δημιουργήσει. Σε γενικές γραμμές το Docker κατεβάζει εφαρμογές (image) από το DockerHub, δημιουργεί container για να μας διαθέσει αυτές τις εφαρμογές, δεσμεύει χώρους αποθήκευσης (volume) για να εξυπηρετήσει το κάθε container και σε κάποιες περιπτώσεις φτιάχνει έξτρα δίκτυα (network) για τη συνδεσιμότητα όλων αυτών μεταξύ τους.
Για να δούμε λοιπόν μία γενική εικόνα των container που έχουμε στο σύστημά μας, δίνουμε την εντολή:
docker ps -a
Σημείωση:
Με το δείκτη "-a" που προέρχεται από τη λέξη "all", μπορούμε να δούμε όλα τα container μας. Δίνοντας την εντολή "docker ps" θα μας επιστρέψει μόνο τα container που τρέχουν αυτή τη στιγμή στο σύστημα (όχι τα σταματημένα).
Το αποτέλεσμα που θα πάρουμε είναι κάπως έτσι:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac376ff4d912 linuxserver/heimdall:latest "/init" 2 weeks ago Up 2 minutes 0.0.0.0:8001->80/tcp, 0.0.0.0:9001->443/tcp heimdall
b5e3fc569161 bitwardenrs/server "/bitwarden_rs" 2 weeks ago Up 2 minutes (healthy) 3012/tcp, 0.0.0.0:8003->80/tcp bitwarden
241f134d0b57 kunde21/gitea-arm:latest "/usr/bin/entrypoint…" 2 weeks ago Up 2 minutes 0.0.0.0:9002->22/tcp, 0.0.0.0:8002->3000/tcp gitea
f64b0cefbda7 containrrr/watchtower "/watchtower" 2 weeks ago Exited (1) 2 weeks ago watchtower
b4aeb042331a portainer/portainer "/portainer" 2 weeks ago Up 2 minutes 0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp portainer
ff0c755be1e0 hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago wonderful_carson
Η εντολή αυτή θα μας πει πόσα container έχουμε εγκαταστήσει, αλλά θα μας δώσει και τις εξής πολύ χρήσιμες πληροφορίες:
- CONTAINER ID: Ο αριθμός του κάθε container στο σύστημά μας. Μπορούμε να τον χρησιμοποιήσουμε για να διαγράψουμε (π.χ.) ένα container αν δε θέλουμε να χρησιμοποιήσουμε το όνομά του.
- IMAGE: Η υπηρεσία που τρέχει μέσα σε κάθε container.
- CREATED: Πότε δημιουργήθηκε το συγκεκριμένο container. Αυτό είναι χρήσιμο στις περιπτώσεις που χρησιμοποιούμε κάποια υπηρεσία αυτόματης αναβάθμισης σαν το Watchtower και θέλουμε να ξέρουμε πότε ενημερώθηκε για τελευταία φορά.
- STATUS: Εδώ μπορούμε να δούμε αν το container λειτουργεί ή αν είναι σταματημένο.
- PORTS: Εδώ προβάλλονται τα port στα οποία τρέχει το κάθε container.
- NAMES: Εδώ είναι τα ονόματα που τους έχουμε δώσει. Αν δεν τα έχουμε ονοματίσει κατά τη δημιουργία τους, το Docker τους δίνει ένα τυχαίο όνομα.
Όσο δοκιμάζουμε νέες εφαρμογές στο Docker, είναι σίγουρο ότι θα αρχίσει να γεμίζει με "σκουπίδια". Στη μνήμη του θα παραμείνουν σταματημένα container, παλιά image, εγκαταλελειμμένα volume και αχρησιμοποίητα network. Όλα αυτά μπορούμε να τα διαγράψουμε με μία μόνο εντολή για να εξοικονομήσουμε πολύτιμο χώρο στο δίσκο του υπολογιστή μας. Η εντολή είναι η εξής:
docker system prune
Με δύο μόνο εντολές λοιπόν μπορούμε να μάθουμε τις γενικές πληροφορίες του συστήματος και να κάνουμε μία γενική εκκαθάριση. Πάμε όμως να δούμε και κάποιες πιο συγκεκριμένες εντολές για τα τέσσερα βασικά στοιχεία του Docker, δηλαδή τα container, τα image, τα volume και τα network.
Διαφήμιση
Βασικές εντολές διαχείρισης container
Είπαμε ότι τα container είναι το βασικό στοιχείο του Docker. Μπορούμε να φτιάξουμε όσα θέλουμε και να τα ενεργοποιούμε / απενεργοποιούμε όποτε μας αρέσει. Πολύ βολικό αυτό καθώς μπορούμε να έχουμε δεκάδες έτοιμες υπηρεσίες και να τις "ανοίγουμε" μόνο όταν τις χρειαζόμαστε, για να μη βαραίνουμε άσκοπα τον υπολογιστή μας.
Για να σταματήσουμε ένα container (π..χ portainer) δίνουμε την εντολή:
docker stop portainer
Αντίστοιχα για να το ξεκινήσουμε και πάλι δίνουμε την εντολή:
docker start portainer
Για να αφαιρέσουμε ένα container από το σύστημά μας θα πρέπει πρώτα να το σταματήσουμε και μετά να το διαγράψουμε. Όλο αυτό όμως μπορεί να γίνει με μία εντολή:
docker rm -f portainer
Για να διαγράψουμε μαζικά όλα τα container που έχουμε σταματημένα δίνουμε την εντολή:
docker container prune
Επειδή οι περισσότερες υπηρεσίες που θα τρέξουμε στο Docker είναι web εφαρμογές, είναι ιδιαίτερα σημαντικό να γνωρίζουμε ανά πάσα στιγμή το port στο οποίο τρέχει η κάθε μία. Αν και μπορούμε να τα δούμε συνολικά στην πρώτη εντολή για την οποία μιλήσαμε, με την ακόλουθη μπορούμε να μάθουμε το port για ένα συγκεκριμένο container (π.χ. portainer):
docker port portainer
Τέλος ας δούμε και πώς μπορούμε να κάνουμε αναβάθμιση σε μία υπηρεσία (image). Αν λοιπόν το Portainer έχει ανεβάσει ένα νέο image στο DockerHub, θα πρέπει να το κατεβάσουμε και να το τοποθετήσουμε στη θέση του παλιού, μέσα στο container μας. Υπάρχουν δύο τρόποι για να το κάνουμε αυτό:
- Χρησιμοποιούμε το Watchtower που τα κάνει όλα αυτόματα.
- Διαγράφουμε το container μας (αλλά όχι το volume) και δίνουμε ξανά ακριβώς την ίδια εντολή δημιουργίας νέου container, για παράδειγμα:
docker run -d \
--name=portainer \
-p 8000:8000 \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer:/data \
--restart unless-stopped \
portainer/portainer
Αν κάτι δεν πάει καλά με την νέα έκδοση της υπηρεσίας μας και θέλουμε να επιστρέψουμε στο παλιό image, μπορούμε να το κάνουμε εύκολα, καθώς το Docker κρατάει στη μνήμη του όλα όσα έχουμε χρησιμοποιήσει στο παρελθόν. Αν για παράδειγμα έχουμε ονομάσει "old_portainer" το παλιό image του Portainer, δίνουμε την κλασική εντολή δημιουργίας container, με τη διαφορά ότι στο τέλος σημειώνουμε το image που έχουμε ήδη στον υπολογιστή μας:
docker run -d \
--name=portainer \
-p 8000:8000 \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer:/data \
--restart unless-stopped \
old_portainer
Αυτά είναι λοιπόν τα βασικά για τα container. Με αυτές τις πολύ απλές εντολές μπορούμε να ανεβάσουμε και να κατεβάσουμε όποια υπηρεσία θέλουμε. Πάμε τώρα να μιλήσουμε για τα αρχεία image.
Βασικές εντολές διαχείρισης image
Αν τα container είναι το βασικό στοιχείο του Docker, τότε το image είναι το βασικό στοιχείο ενός container. Κάθε image που βρίσκεται στο DockerHub είναι και μία πακεταρισμένη υπηρεσία η οποία περιμένει να την κατεβάσουμε και να τη βάλουμε σε ένα container για να τη χρησιμοποιήσουμε.
Για να κατεβάσουμε λοιπόν ένα image (π.χ. bitwarden) στον υπολογιστή μας, δίνουμε την εντολή:
docker pull bitwarden
Ένα σκέτο image στο σύστημά μας βέβαια δεν εξυπηρετεί σε κάτι, οπότε καλύτερα θα ήταν να δώσουμε κατ' ευθείαν την εντολή δημιουργίας container για να το έχουμε έτοιμο. Κάπως έτσι δηλαδή:
docker volume create bitwarden
docker run --name=bitwarden -p 8003:80 -v bitwarden:/config --restart unless-stopped bitwardenrs/server
Σημείωση:
Προσέξτε ότι δίνουμε "docker run" και όχι "docker run -d". Ο λόγος είναι γιατί θέλουμε απλά να δημιουργήσουμε ένα container, το οποίο όμως θα σταματήσει να τρέχει όταν κλείσουμε το τερματικό μας.
Για να δούμε τώρα πόσα image βρίσκονται στον υπολογιστή μας, δίνουμε την εντολή:
docker images
Το αποτέλεσμα που θα πάρουμε είναι κάπως έτσι:
REPOSITORY TAG IMAGE ID CREATED SIZE
bitwardenrs/server latest 503b94c5dc29 2 weeks ago 129MB
linuxserver/heimdall latest c1b242092e6c 2 weeks ago 83.2MB
kunde21/gitea-arm latest 699062da95f4 7 weeks ago 104MB
containrrr/watchtower latest 609dda97f756 2 months ago 14MB
portainer/portainer latest 2869fc110bf7 2 months ago 78.6MB
hello-world latest bf756fb1ae65 4 months ago 13.3kB
Από τις πληροφορίες που θα προβληθούν, μας ενδιαφέρουν το "REPOSITORY", το "TAG" και το "IMAGE ID", τα οποία θα χρησιμοποιήσουμε στη συνέχεια για να διαχειριστούμε τα image.
Για να διαγράψουμε ένα image, προτιμότερο είναι να δώσουμε το "ID" του (π.χ. "j989jh798jh798") ως εξής:
docker rmi j989jh798jh798
Μπορεί όμως να έχουμε στο σύστημά μας περισσότερα από ένα image με το ίδιο "ID". Σε αυτή την περίπτωση θα μας βγάλει σφάλμα κατά τη διαγραφή. Μπορούμε όμως να τα διαγράψουμε μαζικά "με τη βία" προσθέτοντας το δείκτη "-f":
docker rmi -f j989jh798jh798
Αν πάλι δε θέλουμε να τα αφαιρέσουμε όλα, μπορούμε να επιλέξουμε ένα από αυτά δίνοντας το συνδυασμό "REPO:TAG" (π.χ. "bitwarden:latest") που του αντιστοιχεί. Για παράδειγμα:
docker rmi bitwarden:latest
Για να διαγράψουμε τέλος όλα τα αχρησιμοποίητα image, αυτά δηλαδή που δε σχετίζονται με κάποιο container ή δεν είναι συνδεδεμένα σε κάποιο volume η εντολή είναι η εξής:
docker image prune
Αυτές είναι και οι βασικές εντολές για τη διαχείριση των image. Μια καλή πρακτική είναι να φτιάχνουμε ένα container για κάθε image που χρειαζόμαστε και με την εντολή "docker image prune" να διαγράφουμε χωρίς κόπο όλα τα περιττά. Πάμε τώρα να δούμε τα volume.
Διαφήμιση
Βασικές εντολές διαχείρισης volume
Τα περισσότερα container δεν είναι φτιαγμένα για να αποθηκεύουν τις αλλαγές που κάνουμε στις υπηρεσίες που τρέχουν. Για αυτό το σκοπό υπάρχουν τα volume, τα οποία διατηρούν τα δεδομένα μας, ακόμη και αν διαγράψουμε τα container στα οποία αντιστοιχούν.
Για να φτιάξουμε ένα volume πρέπει να του δώσουμε ένα όνομα (π.χ. pihole) και να χρησιμοποιήσουμε την εντολή:
docker volume create pihole
Αντίστοιχα για να διαγράψουμε το ίδιο volume δίνουμε την εντολή:
docker volume rm pihole
Σημείωση:
Το Docker δε μας επιτρέπει να διαγράψουμε volume που χρησιμοποιούνται από κάποιο container, οπότε δεν μπορούμε να χάσουμε τα δεδομένα μας κατά λάθος.
Για να δούμε μία λίστα με τα volume που έχουμε δημιουργήσει δίνουμε την εντολή:
docker volume ls
Το αποτέλεσμα που θα πάρουμε είναι κάπως έτσι:
DRIVER VOLUME NAME
local 05505679a9b88b3455f6d60c6d331ea096e27e45dbc5b6dc126504ef1160a5e0
local bitwarden
local gitea
local heimdall
local portainer
Τέλος για να διαγράψουμε μαζικά όλα τα αχρησιμοποίητα volume δίνουμε την εντολή:
docker volume prune
Τα volume είναι απλά φάκελοι στο σύστημά μας, οπότε δεν υπάρχει κάτι δύσκολο στη διαχείρισή τους. Δημιουργούμε και διαγράφουμε, αυτό είναι όλο! Πάμε τέλος και στα network.
Βασικές εντολές διαχείρισης network
To Docker δημιουργεί αυτόματα ένα δικό του δίκτυο (network) στο οποίο συνδέονται στη συνέχεια τα container μας. Μας δίνει όμως τη δυνατότητα να φτιάξουμε και δικά μας, σε περίπτωση που θέλουμε να απομονώσουμε κάποιες υπηρεσίες από τις υπόλοιπες. Τα δίκτυα μπορεί να είναι τύπου "bridge" ή "overlay", εκτός και αν έχουμε εγκαταστήσει στο σύστημά μας και άλλους driver.
Σε γενικές γραμμές τα bridge τα χρησιμοποιούμε για να συνδέσουμε container που βρίσκονται σε ένα Docker host (μία συσκευή), ενώ τα overlay χρησιμεύουν σε cluster περισσότερων υπολογιστών που τρέχουν το Docker (Swarm).
Όπως είπαμε το Docker δημιουργεί αυτόματα ένα bridge δίκτυο, το οποίο ονομάζεται "docker0" και μπορούμε να το δούμε δίνοντας στο τερματικό μας την εντολή:
ifconfig
Για να φτιάξουμε τώρα το δικό μας bridge network με όνομα "smart-home" θα δώσουμε την εντολή:
docker network create -d bridge smart-home
Αντίστοιχα για να φτιάξουμε ένα overlay network με την ίδια ονομασία θα δώσουμε την εντολή:
docker network create -d overlay smart-home
Σημείωση:
Για να φτιάξουμε overlay network υπάρχουν και άλλες προϋποθέσεις που εξαρτώνται από τη δικτύωση ολόκληρου του cluster. Περισσότερες πληροφορίες θα βρείτε εδώ.
Κατά τη δημιουργία ενός container, αν δε δώσουμε συγκεκριμένες πληροφορίες, αυτό θα συνδεθεί αυτόματα στο υπάρχον bridge δίκτυο του Docker. Για να προσθέσουμε στη συνέχεια το containter με όνομα "home-assistant" στο δίκτυο "smart-home" θα δώσουμε την εντολή:
docker network connect smart-home home-assistant
Αντίστοιχα για να αποσυνδέσουμε το συγκεκριμένο container από αυτό το δίκτυο δίνουμε το εξής:
docker network disconnect smart-home home-assistant
Επειδή το πράγμα μπορεί να ξεφύγει με τη δημιουργία πολλών δικτύων, κάτι που θα μας δημιουργήσει προβλήματα με την επικοινωνία μεταξύ τους, πρέπει να έχουμε μία γενική εικόνα όλων των δικτύων που έχουμε φτιάξει. Για να δούμε λοιπόν μία λίστα των δικτύων μας θα δώσουμε την εντολή:
docker network ls
Το αποτέλεσμα που θα πάρουμε είναι κάπως έτσι:
NETWORK ID NAME DRIVER SCOPE
c3ae8a5bd6fb bridge bridge local
134656deef76 host host local
7c00c70a746a none null local
Από αυτή την εντολή μπορούμε να μάθουμε τις εξής χρήσιμες πληροφορίες:
- NETWORK ID: Ο αριθμός του δικτύου, τον οποίο μπορούμε να χρησιμοποιήσουμε για να το διαγράψουμε για παράδειγμα, αν δε θέλουμε να χρησιμοποιήσουμε το όνομά του.
- NAME: Το όνομα που έχουμε ορίσει στο δίκτυο.
- DRIVER: Ο driver μέσω του οποίου τρέχει το δίκτυό μας. Μπορεί να είναι bridge ή overlay από προεπιλογή.
- SCOPE: Εδώ θα δούμε αν το δίκτυό μας είναι τοπικό (local) ή αν εξυπηρετεί κάποιο cluster με Docker Swarm (swarm).
Ας πούμε τώρα ότι τελικά το δίκτυο "smart-home" δε μας εξυπηρετεί και θέλουμε να το διαγράψουμε. Αυτό γίνεται με την εντολή:
docker network rm smart-home
Τέλος αν θέλουμε να διαγράψουμε όλα τα αχρησιμοποίητα network που έχουμε στο δίκτυό μας, θα χρησιμοποιήσουμε το γνωστό πλέον "prune" ως εξής:
docker network prune
Εν κατακλείδι
Όλα τα παραπάνω, δηλαδή τα container, τα image, τα volume και τα network, είναι όλη η ουσία του Docker. Μαθαίνοντάς τα λοιπόν μας δίνεται η δυνατότητα να διαχειριστούμε με άνεση έναν Docker server στο σπίτι ή την επιχείρησή μας. Όπως και στις εντολές του Linux έτσι και σε αυτές του Docker μπορούμε να προσθέσουμε διάφορους δείκτες για να κάνουμε πιο ειδικά πράγματα ή να εμφανίσουμε περισσότερες πληροφορίες. Τα άπαντα των εντολών αυτών θα τα βρείτε στην επίσημη σελίδα του Docker.
Στα επόμενα άρθρα θα δούμε το Docker compose με το οποίο μπορούμε να αποθηκεύσουμε όλες τις εντολές έναρξης container σε ένα αρχείο και να κάνουμε αυτόματη δημιουργία των πάντων. Θα δούμε επίσης και το Portainer, μία υπηρεσία η οποία μας δίνει τη δυνατότητα να κάνουμε όσα μάθαμε σήμερα χωρίς το τερματικό αλλά από ένα γραφικό περιβάλλον.
Ευχαριστούμε πολύ Dr. Android, κάνεις τα δύσκολα εύκολα...
ΑπάντησηΔιαγραφήΕυχαριστούμε πολύ Dr. Android, κάνεις τα δύσκολα εύκολα...χάρη στον Chris Kay.
ΑπάντησηΔιαγραφήΑγαπητέ Chris Kay, τι ρυθμίσεις να κάνουμε για να μη σέρνεται laptop i3 με docker desktop σε WSL2, με τα νέα windows;
"Τοποθέτησα" portainer σε port 1234, αλλάζοντας το 8000:8000 σε 1234:8000 όπως είχα δει σε docs του metabase/metabase, είναι σωστή πρακτική;
Ευχαριστώ εκ των προτἐρων.
Το WSL το έχω δοκιμάσει για λίγο καιρό και μου φαίνεται ότι δε διορθώνεται όσον αφορά την ταχύτητα. Είναι καλό για να πειραματίζεσαι με το Linux αλλά όχι για να τρέχεις Docker.
ΔιαγραφήΌσον αφορά τη ρύθμιση για το port είναι σωστή. Το ίδιο θα κάνεις σε όλα τα container σου για να τα βάλεις στις πόρτες που θέλεις.
Δηλαδή docker + windows μόνο σε windows 10 pro;
ΔιαγραφήΕπίσης dual boot: linux +windows θα "δουλέψει" ως λύση για το docker σε έναν μέσο i3 laptop:
Τέλος η ρύθμιση που προτείνεις σε άλλο άρθρο για τον portainer σχετικά με τις ρυθμίσεις CPU θα βελτιώσουν την κατάσταση στο wsl2;
Αν όχι θα πρέπει μάλλον να αγοράσω κάποιο pc - laptop με linux;
Νομίζω ότι η καλύτερη λύση είναι Docker σε Linux.
ΔιαγραφήΔε χρειάζεται να αγοράσεις νέο laptop. Απλά κατεβάσεις το Ubuntu και το κάνεις είτε dual boot, είτε virtual machine, είτε αντικαθιστας τελείως το Windows.
Ευχαριστώ πολύ, Doctor.
Διαγραφή"...είτε αντικαθιστας τελείως το Windows", αυτό φοβόμουν ότι θα το πεις.
Τώρα που ετοιμάζει και GUI, η Microsoft για το WSL2(Kernel), αισθάνομαι σαν να μη θέλω να αποχωριστώ τα νέα windows.
Επειδή όμως δε θέλω να κουράζω άλλο τους αναγνώστες σας και την ομάδα σας με την "πολυλογία" μου, θέλω ειλικρινά να σας συγχαρώ.
Συγχαρητήρια για τους οδηγούς σας, μας βοηθάτε πάρα πολύ, ιδίως όσους δεν προερχόμαστε από σχολές πληροφορικής.
Δεν είναι αναγκαίο να βγάλεις το Windows εννοείται. Υπάρχουν τρόποι.
ΔιαγραφήΕυχαριστώ για τα καλά σου λόγια. Είναι σημαντικό να τα ακούμε γιατί όταν γράφουμε τα άρθρα δεν καταλαβαίνουμε αν όντως πετυχαίνουμε το σκοπό του να είναι κατανοητά και απλά.