Docker: Οδηγός Containers και Ανάπτυξης Εφαρμογών
Το Docker είναι μια πλατφόρμα containerization που επιτρέπει τη συσκευασία μιας εφαρμογής μαζί με τις εξαρτήσεις της και την εκτέλεσή της σε απομονωμένα περιβάλλοντα, τα containers. Χρησιμοποιείται για συνεπή ανάπτυξη, δοκιμές και διάθεση εφαρμογών σε διαφορετικά συστήματα.
Βασική ιδέα: δημιουργούμε ένα image ως πρότυπο και εκτελούμε ένα ή περισσότερα containers από αυτό. Τα containers μπορούν να επικοινωνούν μέσω δικτύων και να αποθηκεύουν μόνιμα δεδομένα σε volumes.
1. Βασικές έννοιες Docker
- Docker Engine: η υπηρεσία που δημιουργεί και διαχειρίζεται images, containers, networks και volumes.
- Image: αμετάβλητο πρότυπο (template) από το οποίο δημιουργούνται containers.
- Container: εκτελούμενο instance ενός image με δικό του writable layer.
- Dockerfile: αρχείο οδηγιών για τη δημιουργία ενός image.
- Docker Compose: εργαλείο ορισμού και εκτέλεσης εφαρμογών πολλών containers.
- Volume: μηχανισμός μόνιμης αποθήκευσης δεδομένων έξω από τον κύκλο ζωής ενός container.
- Network: μηχανισμός επικοινωνίας μεταξύ containers και εξωτερικών δικτύων.
2. Εγκατάσταση και έλεγχος
Η εγκατάσταση διαφέρει ανά λειτουργικό σύστημα. Σε Linux μπορείς να ακολουθήσεις τις επίσημες οδηγίες του Docker για τη διανομή σου. Σε Windows και macOS χρησιμοποιείται συνήθως το Docker Desktop.
docker --version
docker version
docker info
# Έλεγχος λειτουργίας με δοκιμαστικό container
docker run hello-world
3. Docker Images
Τα images αποτελούνται από layers και χρησιμοποιούνται ως βάση για τη δημιουργία containers. Μπορείς να κατεβάσεις έτοιμα images από registries όπως το Docker Hub ή να δημιουργήσεις δικά σου.
# Λίστα τοπικών images
docker image ls
# Λήψη image
docker pull nginx:latest
# Λήψη συγκεκριμένης έκδοσης Ubuntu
docker pull ubuntu:24.04
# Πληροφορίες image
docker image inspect nginx:latest
# Διαγραφή image (εφόσον δεν χρησιμοποιείται)
docker image rm nginx:latest
# Διαγραφή μη χρησιμοποιούμενων images
docker image prune
Βασικές εντολές Image
| Εντολή | Περιγραφή |
|---|---|
| docker pull | Κατεβάζει image από registry |
| docker image ls | Εμφανίζει τα τοπικά images |
| docker image inspect | Εμφανίζει αναλυτικά metadata |
| docker image rm | Διαγράφει image |
| docker image prune | Καθαρίζει μη χρησιμοποιούμενα images |
| docker image history | Εμφανίζει τα layers και το ιστορικό build |
4. Δημιουργία Image με Dockerfile
Το Dockerfile περιγράφει βήμα προς βήμα πώς δημιουργείται ένα image. Το παρακάτω παράδειγμα δημιουργεί ένα απλό Node.js image.
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "server.js"]
Το αρχείο .dockerignore αποκλείει αρχεία από το build context, ώστε να μη μεταφέρονται άσκοπα στο image.
# Παράδειγμα περιεχομένου .dockerignore
node_modules
.git
.env
npm-debug.log
.DS_Store
# Build image από το Dockerfile του τρέχοντος φακέλου
docker build -t grcodeclub-app:1.0 .
# Build χωρίς χρήση cache
docker build --no-cache -t grcodeclub-app:1.0 .
# Εμφάνιση ιστορικού layers
docker image history grcodeclub-app:1.0
5. Docker Containers
Ένα container είναι απομονωμένη διεργασία ή ομάδα διεργασιών που χρησιμοποιεί τον kernel του host. Δεν διαθέτει δικό του kernel. Η απομόνωση βασίζεται σε μηχανισμούς του λειτουργικού συστήματος και δεν πρέπει να θεωρείται απόλυτο όριο ασφαλείας.
# Δημιουργία και εκτέλεση container στο background
docker run -d --name web-server -p 8080:80 nginx:latest
# Εκτέλεση προσωρινού interactive container
docker run --rm -it ubuntu:24.04 bash
# Λίστα ενεργών containers
docker ps
# Όλα τα containers, ακόμη και τα σταματημένα
docker ps -a
# Διακοπή και επανεκκίνηση
docker stop web-server
docker start web-server
docker restart web-server
# Διαγραφή container
docker rm web-server
Χρήσιμες επιλογές docker run
| Option | Λειτουργία |
|---|---|
| -d | Εκτέλεση στο background (detached) |
| -it | Interactive terminal |
| –name | Ορίζει όνομα container |
| -p HOST:CONTAINER | Δημοσιεύει port του container στο host |
| -v | Προσαρτά volume ή bind mount |
| –rm | Διαγράφει το container όταν τερματιστεί |
| -e | Ορίζει environment variable |
| –restart | Ορίζει πολιτική επανεκκίνησης |
| –network | Συνδέει το container σε network |
| –memory | Θέτει όριο μνήμης |
6. Διαχείριση και παρακολούθηση Containers
# Logs container
docker logs web-server
# Συνεχής παρακολούθηση logs
docker logs -f web-server
# Πρόσφατες γραμμές logs
docker logs --tail 100 web-server
# Εκτέλεση εντολής σε ενεργό container
docker exec -it web-server sh
# Αναλυτικές πληροφορίες
docker inspect web-server
# Κατανάλωση πόρων
docker stats
# Εμφάνιση διεργασιών μέσα σε container
docker top web-server
# Αλλαγή ονόματος
docker rename web-server nginx-web
7. Port Mapping
Με το port mapping εκθέτουμε μια θύρα του container σε θύρα του host. Η μορφή είναι HOST_PORT:CONTAINER_PORT.
# Πρόσβαση στο Nginx από http://localhost:8080
docker run -d --name nginx-test -p 8080:80 nginx
# Δέσμευση μόνο στην τοπική loopback διεπαφή
docker run -d --name local-web -p 127.0.0.1:8081:80 nginx
8. Volumes και μόνιμη αποθήκευση
Τα δεδομένα στο writable layer ενός container παραμένουν όσο το ίδιο container υπάρχει, ακόμη και μετά από restart. Όμως μπορεί να χαθούν όταν διαγραφεί το container. Για δεδομένα που πρέπει να διατηρούνται ανεξάρτητα από τον κύκλο ζωής του container, χρησιμοποίησε volumes ή bind mounts.
# Δημιουργία named volume
docker volume create mysql_data
# Λίστα volumes
docker volume ls
# Λεπτομέρειες volume
docker volume inspect mysql_data
# Χρήση volume σε container
docker run -d \
--name database \
-e MYSQL_ROOT_PASSWORD=change-me \
-v mysql_data:/var/lib/mysql \
mysql:8.4
# Διαγραφή volume (προσοχή: μπορεί να διαγραφούν δεδομένα)
docker volume rm mysql_data
Bind Mount
Με bind mount συνδέεις έναν συγκεκριμένο φάκελο του host με έναν φάκελο μέσα στο container. Είναι χρήσιμο στην ανάπτυξη εφαρμογών.
docker run --rm -it \
--mount type=bind,source="$(pwd)",target=/app \
-w /app \
node:22-alpine sh
9. Docker Networks
Τα Docker networks επιτρέπουν στα containers να επικοινωνούν. Σε user-defined bridge network, τα containers μπορούν συνήθως να εντοπίζουν το ένα το άλλο με βάση το όνομά τους.
# Δημιουργία δικτύου
docker network create app-network
# Σύνδεση container στο δίκτυο
docker run -d --name web --network app-network nginx
# Εκτέλεση δεύτερου container στο ίδιο δίκτυο
docker run --rm --network app-network busybox ping -c 3 web
# Λίστα δικτύων
docker network ls
# Πληροφορίες δικτύου
docker network inspect app-network
# Σύνδεση υπάρχοντος container
docker network connect app-network web
# Αποσύνδεση
docker network disconnect app-network web
# Διαγραφή δικτύου
docker network rm app-network
Τύποι δικτύων
| Driver | Χρήση |
|---|---|
| bridge | Επικοινωνία containers στον ίδιο Docker host |
| host | Χρήση του network namespace του host (Linux) |
| none | Χωρίς εξωτερική δικτυακή σύνδεση |
| overlay | Επικοινωνία υπηρεσιών σε πολλαπλούς Docker hosts με κατάλληλη υποδομή |
10. Docker Compose
Το Docker Compose ορίζει μια εφαρμογή πολλών services σε ένα αρχείο compose.yaml. Η σύγχρονη εντολή είναι docker compose (plugin V2).
services:
web:
image: nginx:latest
ports:
- "8080:80"
depends_on:
- app
app:
image: node:22-alpine
working_dir: /app
command: ["node", "server.js"]
volumes:
- ./app:/app
db:
image: postgres:17
environment:
POSTGRES_DB: grcodeclub
POSTGRES_USER: appuser
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Το παραπάνω είναι ενδεικτικό template. Το service app χρειάζεται το δικό σου αρχείο server.js και η μεταβλητή DB_PASSWORD πρέπει να οριστεί με ασφαλή τρόπο στο περιβάλλον εκτέλεσης.
# Έλεγχος και δημιουργία των services
docker compose up -d
# Λίστα services
docker compose ps
# Logs όλων των services
docker compose logs -f
# Logs συγκεκριμένου service
docker compose logs -f web
# Εκτέλεση εντολής σε service
docker compose exec web sh
# Αναδημιουργία images και εκκίνηση
docker compose up -d --build
# Σταμάτημα και αφαίρεση containers/networks του project
docker compose down
# Αφαίρεση και των named volumes του project (προσοχή στα δεδομένα)
docker compose down --volumes
11. Environment Variables και Secrets
Οι μεταβλητές περιβάλλοντος χρησιμοποιούνται για ρυθμίσεις εφαρμογών. Απόφυγε την αποθήκευση πραγματικών κωδικών και tokens μέσα σε Dockerfile, image ή δημόσια αρχεία Compose.
# Μεταβλητή κατά την εκκίνηση
docker run -d --name app \
-e APP_ENV=production \
-e LOG_LEVEL=info \
my-app:1.0
# Ανάγνωση μεταβλητής μέσα στο container
docker exec app printenv APP_ENV
12. Restart Policies και Health Checks
# Επανεκκίνηση εκτός αν το container σταματήσει χειροκίνητα
docker run -d --restart unless-stopped --name web nginx
# Προβολή κατάστασης health
docker inspect --format='{{.State.Health.Status}}' web
Παράδειγμα HEALTHCHECK σε Dockerfile:
FROM nginx:alpine
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -q --spider http://127.0.0.1/ || exit 1
13. Resource Limits
Μπορείς να περιορίσεις τους πόρους που καταναλώνει ένα container. Τα ακριβή όρια και η συμπεριφορά εξαρτώνται από το λειτουργικό και τη διαμόρφωση του Docker Engine.
# Όριο μνήμης 512 MB
docker run -d --name limited-nginx \
--memory=512m \
--cpus=1.5 \
nginx
# Παρακολούθηση πόρων
docker stats limited-nginx
14. Registries και Docker Hub
# Σύνδεση σε registry
docker login
# Tag image για το Docker Hub
docker tag grcodeclub-app:1.0 USERNAME/grcodeclub-app:1.0
# Push image
docker push USERNAME/grcodeclub-app:1.0
# Λήψη image
docker pull USERNAME/grcodeclub-app:1.0
# Αποσύνδεση
docker logout
15. Καθαρισμός και διαχείριση χώρου
Οι εντολές prune αφαιρούν μη χρησιμοποιούμενα αντικείμενα. Έλεγξε πρώτα τι καταλαμβάνει χώρο και χρησιμοποίησε τις επιλογές διαγραφής με προσοχή.
# Αναφορά χρήσης δίσκου Docker
docker system df
# Αφαίρεση stopped containers
docker container prune
# Αφαίρεση μη χρησιμοποιούμενων networks
docker network prune
# Αφαίρεση μη χρησιμοποιούμενων images
docker image prune -a
# Γενικός καθαρισμός μη χρησιμοποιούμενων αντικειμένων
docker system prune
# ΠΡΟΣΟΧΗ: συμπεριλαμβάνει και μη χρησιμοποιούμενα volumes
docker system prune --volumes
16. Ασφάλεια Docker
- Μην εκτελείς containers ως root αν δεν είναι απαραίτητο. Χρησιμοποίησε USER στο Dockerfile.
- Μην ενσωματώνεις passwords, API keys ή private keys στα images.
- Χρησιμοποίησε επίσημα ή αξιόπιστα images και ενημέρωνέ τα τακτικά.
- Περιόρισε Linux capabilities και απόφυγε το –privileged εκτός αν υπάρχει τεκμηριωμένη ανάγκη.
- Μην εκθέτεις ports δημόσια χωρίς να χρειάζεται. Προτίμησε binding σε 127.0.0.1 όπου ταιριάζει.
- Χρησιμοποίησε read-only filesystem όπου είναι εφικτό και ξεχωριστά volumes για τα δεδομένα.
- Σάρωσε images για γνωστά vulnerabilities και έλεγχε τα dependencies.
- Θυμήσου ότι το Docker socket παρέχει ισχυρά δικαιώματα στον host· μην το προσαρτάς αλόγιστα σε containers.
17. Συχνά προβλήματα και διάγνωση
# Αναλυτικά logs
docker logs --tail 200 CONTAINER_NAME
# Κατάσταση και exit code
docker inspect CONTAINER_NAME
# Έλεγχος αν χρησιμοποιείται ήδη μια θύρα (Linux)
ss -lntp
# Έλεγχος διεργασιών container
docker top CONTAINER_NAME
# Επανεκκίνηση Docker Engine σε systemd Linux
sudo systemctl status docker
sudo systemctl restart docker
# Έλεγχος διαθέσιμου χώρου
docker system df
18. Γρήγορη αναφορά εντολών
| Εντολή | Περιγραφή |
|---|---|
| docker ps -a | Όλα τα containers |
| docker image ls | Τοπικά images |
| docker run | Δημιουργία και εκτέλεση container |
| docker start / stop / restart | Έλεγχος λειτουργίας container |
| docker rm | Διαγραφή container |
| docker exec -it NAME sh | Άνοιγμα shell σε container |
| docker logs -f NAME | Παρακολούθηση logs |
| docker inspect NAME | Αναλυτικές πληροφορίες |
| docker stats | Πόροι σε πραγματικό χρόνο |
| docker volume ls | Λίστα volumes |
| docker network ls | Λίστα networks |
| docker compose up -d | Εκκίνηση Compose project |
| docker compose down | Τερματισμός Compose project |
| docker system df | Χρήση χώρου Docker |
19. Χρήσιμες πρακτικές
- Χρησιμοποίησε συγκεκριμένα tags αντί για latest σε παραγωγικά περιβάλλοντα, ώστε οι εκδόσεις να είναι ελεγχόμενες.
- Δημιούργησε μικρά images με κατάλληλα base images και multi-stage builds όπου χρειάζεται.
- Πρόσθεσε .dockerignore για να μειώσεις το build context και να αποφύγεις διαρροή τοπικών αρχείων.
- Αποθήκευε μόνιμα δεδομένα σε volumes ή bind mounts, όχι μόνο στο writable layer του container.
- Χρησιμοποίησε Compose για τοπικά περιβάλλοντα πολλών services και επαναλήψιμη διαμόρφωση.
- Έλεγχε logs, health status και resource usage κατά τη λειτουργία.
- Απόφυγε περιττά privileges και κράτησε τα images και το Docker Engine ενημερωμένα.