Πώς να Εγκαταστήσετε και να Ρυθμίσετε το Laravel με Docker Compose σε Ubuntu 22.04
Εισαγωγή
Το containerize μιας εφαρμογής αναφέρεται στη διαδικασία προσαρμογής μιας εφαρμογής και των συστατικών της ώστε να είναι δυνατή η εκτέλεσή της σε ελαφριά περιβάλλοντα που ονομάζονται containers. Τέτοια περιβάλλοντα είναι απομονωμένα και προσωρινά, και μπορούν να αξιοποιηθούν για την ανάπτυξη, τον έλεγχο και την ανάπτυξη των εφαρμογών στην παραγωγή.
Σε αυτόν τον οδηγό, θα χρησιμοποιήσουμε το Docker Compose για να κάνουμε containerization μιας εφαρμογής Laravel για ανάπτυξη. Όταν ολοκληρώσετε, θα έχετε μια δοκιμαστική εφαρμογή Laravel να τρέχει σε τρία ξεχωριστά container υπηρεσιών:
- Μια υπηρεσία
appπου τρέχει PHP7.4-FPM; - Μια υπηρεσία
dbπου τρέχει MySQL 8.0; - Μια υπηρεσία
nginxπου χρησιμοποιεί την υπηρεσίαappγια να αναλύσει κώδικα PHP πριν σερβίρει την εφαρμογή Laravel στον τελικό χρήστη.
Για να επιτρέψουμε μια πιο ομαλή διαδικασία ανάπτυξης και να διευκολύνουμε τον εντοπισμό σφαλμάτων της εφαρμογής, θα κρατάμε τα αρχεία της εφαρμογής συγχρονισμένα χρησιμοποιώντας κοινόχρηστους τόμους. Θα δούμε επίσης πώς να χρησιμοποιούμε τις εντολές docker compose exec για να τρέξουμε το Composer και το Artisan στο κοντέινερ app.
Αναπτύξτε τις εφαρμογές frontend σας από το GitHub χρησιμοποιώντας την πλατφόρμα εφαρμογών Linux-Console.net. Αφήστε το Linux-Console.net να επικεντρωθεί στην κλιμάκωση της εφαρμογής σας.
Βασικά Συμπεράσματα:
- Η κοντεϊνεροποίηση καθιστά την ανάπτυξη προβλέψιμη: Η εκτέλεση του Laravel σε Docker εξασφαλίζει συνεπή περιβάλλοντα σε όλους τους υπολογιστές, εξαλείφοντας τα προβλήματα τύπου «λειτουργεί στον υπολογιστή μου» και διευκολύνοντας τη συνεργασία.
- Ο διαχωρισμός των υπηρεσιών βελτιώνει τη συντηρησιμότητα: Η διάσπαση των PHP, MySQL και Nginx σε ξεχωριστά containers βοηθά στην απομόνωση προβλημάτων, απλοποιεί τις ενημερώσεις και καθρεφτίζει ρυθμίσεις παραγωγής στον πραγματικό κόσμο.
- Οι μεταβλητές περιβάλλοντος είναι κεντρικές για ευέλικτη διαμόρφωση: Η χρήση ενός αρχείου
.envεπιτρέπει στους προγραμματιστές να αλλάζουν τα διαπιστευτήρια της βάσης δεδομένων και άλλες ρυθμίσεις χωρίς να επεμβαίνουν στον κώδικα της εφαρμογής. - Τα προσαρμοσμένα Docker images βελτιώνουν τον έλεγχο και την ασφάλεια: Η δημιουργία του δικού σας PHP image εξασφαλίζει ότι εγκαθιστάτε μόνο ό,τι χρειάζεται το έργο σας, διατηρώντας το περιβάλλον ελαφρύ και ασφαλές.
- Τα δικαιώματα αρχείων πρέπει να ταιριάζουν με τους χρήστες του container: Η σωστή ρύθμιση της ιδιοκτησίας και των δικαιωμάτων για τους φάκελους που μπορούν να γράφονται του Laravel αποτρέπει σφάλματα κατά την εκτέλεση και υποστηρίζει ομαλή τοπική ανάπτυξη.
- Η χρήση αρχείων υπερισχύσεως υποστηρίζει πολλαπλά περιβάλλοντα:
docker-compose.override.ymlεπιτρέπει τοπικές τροποποιήσεις—όπως η ζωντανή ανανέωση—χωρίς να αλλάζουν οι ρυθμίσεις παραγωγής. Αυτό κρατάει την ανάπτυξη και την εγκατάσταση καθαρά διαχωρισμένες. - Η αντιμετώπιση προβλημάτων ξεκινά με την κατανόηση της συμπεριφοράς των κοντέινερ: Η γνώση του τρόπου ελέγχου των αρχείων καταγραφής, της παρακολούθησης των εκτελούμενων υπηρεσιών και της δοκιμής της συνδεσιμότητας είναι κρίσιμη για την ταχεία επίλυση των περισσότερων προβλημάτων σε περιβάλλοντα με κοντέινερ.
- Μια ρύθμιση βασισμένη σε Docker κλιμακώνεται με τη ροή εργασίας σας: Μόλις δημιουργηθεί, η ίδια διαμόρφωση μπορεί να τροφοδοτεί τοπικά, στάδιο ή παραγωγικά περιβάλλοντα, δημιουργώντας ένα σταθερό, επαναχρησιμοποιήσιμο θεμέλιο για μελλοντικά έργα Laravel.
Προαπαιτούμενα
- Πρόσβαση σε έναν τοπικό υπολογιστή Ubuntu ή σε διακομιστή ανάπτυξης ως χρήστης χωρίς δικαιώματα root με δικαιώματα sudo. Αν χρησιμοποιείτε απομακρυσμένο διακομιστή, συνιστάται να υπάρχει ενεργό firewall. Για να τα ρυθμίσετε, παρακαλούμε ανατρέξτε στον Οδηγό Αρχικής Ρύθμισης Διακομιστή για Ubuntu.
- Το Docker είναι εγκατεστημένο στον διακομιστή σας, ακολουθώντας τα Βήματα 1 και 2 του Οδηγού Εγκατάστασης και Χρήσης του Docker σε Ubuntu.
- Το Docker Compose είναι εγκατεστημένο στον διακομιστή σας, ακολουθώντας το Βήμα 1 του Οδηγού για την Εγκατάσταση και Χρήση του Docker Compose σε Ubuntu.
Βήμα 1 — Απόκτηση της Εφαρμογής επίδειξης
Για να ξεκινήσουμε, θα κατεβάσουμε την εφαρμογή demo Laravel από το αποθετήριο της στο Github. Μας ενδιαφέρει ο κλάδος tutorial-01, ο οποίος περιέχει την βασική εφαρμογή Laravel που έχουμε δημιουργήσει στον οδηγό Πώς να Εγκαταστήσετε και να Ρυθμίσετε το Laravel με Nginx σε Ubuntu 22.04 (LEMP).
Για να αποκτήσετε τον κωδικό της εφαρμογής που είναι συμβατός με αυτό το σεμινάριο, κατεβάστε την έκδοση tutorial-1.0.1 στον προσωπικό σας φάκελο με:
cd ~
curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zipΘα χρειαστούμε την εντολή unzip για να αποσυμπιέσουμε τον κώδικα της εφαρμογής. Σε περίπτωση που δεν έχετε εγκαταστήσει αυτό το πακέτο προηγουμένως, κάντε το τώρα με:
sudo apt update
sudo apt install unzipΤώρα, αποσυμπιέστε τα περιεχόμενα της εφαρμογής και μετονομάστε τον ξεπακεταρισμένο φάκελο για πιο εύκολη πρόσβαση:
unzip travellist.zip
mv travellist-laravel-demo-tutorial-1.0.1 travellist-demoΠλοηγηθείτε στον κατάλογο travellist-demo:
cd travellist-demoΣτο επόμενο βήμα, θα δημιουργήσουμε ένα αρχείο ρυθμίσεων .env για να ρυθμίσουμε την εφαρμογή.
Βήμα 2 — Ρύθμιση του αρχείου .env της εφαρμογής
Τα αρχεία ρύθμισης του Laravel βρίσκονται σε έναν κατάλογο που ονομάζεται config, μέσα στον κύριο κατάλογο της εφαρμογής. Επιπλέον, ένα αρχείο .env χρησιμοποιείται για την ρύθμιση παραμέτρων που εξαρτώνται από το περιβάλλον, όπως τα διαπιστευτήρια και οποιαδήποτε πληροφορία μπορεί να διαφέρει μεταξύ των αναπτύξεων. Αυτό το αρχείο δεν περιλαμβάνεται στο σύστημα ελέγχου εκδόσεων.
Προειδοποίηση: Το αρχείο ρύθμισης του περιβάλλοντος περιέχει ευαίσθητες πληροφορίες για τον διακομιστή σας, συμπεριλαμβανομένων των στοιχείων πρόσβασης στη βάση δεδομένων και των κλειδιών ασφαλείας. Γι' αυτόν τον λόγο, δεν πρέπει ποτέ να μοιράζεστε αυτό το αρχείο δημόσια.
Οι τιμές που περιέχονται στο αρχείο .env θα έχουν προτεραιότητα σε σχέση με τις τιμές που ορίζονται στα κανονικά αρχεία ρυθμίσεων που βρίσκονται στον κατάλογο config. Κάθε εγκατάσταση σε ένα νέο περιβάλλον απαιτεί ένα εξατομικευμένο αρχείο περιβάλλοντος για να οριστούν πράγματα όπως οι ρυθμίσεις σύνδεσης βάσης δεδομένων, οι επιλογές εντοπισμού σφαλμάτων, το URL της εφαρμογής, μεταξύ άλλων στοιχείων που μπορεί να διαφέρουν ανάλογα με το περιβάλλον στο οποίο εκτελείται η εφαρμογή.
Θα δημιουργήσουμε τώρα ένα νέο αρχείο .env για να προσαρμόσουμε τις επιλογές διαμόρφωσης για το περιβάλλον ανάπτυξης που στήνουμε. Το Laravel περιλαμβάνει ένα παράδειγμα αρχείου .env που μπορούμε να αντιγράψουμε για να δημιουργήσουμε το δικό μας:
cp .env.example .envΆνοιξε αυτό το αρχείο χρησιμοποιώντας το nano ή τον επεξεργαστή κειμένου της επιλογής σου:
nano .envΤο τρέχον αρχείο .env από την εφαρμογή επίδειξης travellist περιέχει ρυθμίσεις για χρήση μιας τοπικής βάσης δεδομένων MySQL, με 127.0.0.1 ως διακομιστή βάσης δεδομένων. Πρέπει να ενημερώσουμε τη μεταβλητή DB_HOST ώστε να δείχνει στην υπηρεσία βάσης δεδομένων που θα δημιουργήσουμε στο περιβάλλον Docker μας. Σε αυτόν τον οδηγό, θα ονομάσουμε την υπηρεσία της βάσης δεδομένων db. Προχωρήστε και αντικαταστήστε την αναφερόμενη τιμή της DB_HOST με το όνομα της υπηρεσίας βάσης δεδομένων:
APP_NAME=Travellist
APP_ENV=dev
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password
...Μη διστάσετε να αλλάξετε επίσης το όνομα της βάσης δεδομένων, το όνομα χρήστη και τον κωδικό πρόσβασης, αν το επιθυμείτε. Αυτές οι μεταβλητές θα χρησιμοποιηθούν σε ένα επόμενο βήμα, όπου θα ρυθμίσουμε το αρχείο docker-compose.yml για να διαμορφώσουμε τις υπηρεσίες μας.
Αποθήκευσε το αρχείο όταν τελειώσεις με την επεξεργασία. Αν χρησιμοποίησες το nano, μπορείς να το κάνεις πατώντας Ctrl+x, μετά Y και Enter για επιβεβαίωση.
Βήμα 3 – Ρύθμιση του Dockerfile της Εφαρμογής
Αν και οι υπηρεσίες μας MySQL και Nginx θα βασίζονται σε προκαθορισμένες εικόνες που λαμβάνονται από το Docker Hub, εξακολουθούμε να χρειάζεται να δημιουργήσουμε μια προσαρμοσμένη εικόνα για το κοντέινερ της εφαρμογής. Θα δημιουργήσουμε ένα νέο Dockerfile γι’ αυτό.
Η εικόνα travellist μας θα βασιστεί στην επίσημη εικόνα PHP php:7.4-fpm από το Docker Hub. Παρά πάνω από αυτό το βασικό περιβάλλον PHP-FPM, θα εγκαταστήσουμε μερικά επιπλέον mod PHP και το εργαλείο διαχείρισης εξαρτήσεων Composer.
Θα δημιουργήσουμε επίσης ένα νέο χρήστη συστήματος· αυτό είναι απαραίτητο για την εκτέλεση εντολών artisan και composer κατά την ανάπτυξη της εφαρμογής. Η ρύθμιση uid εξασφαλίζει ότι ο χρήστης μέσα στο container έχει το ίδιο uid με τον χρήστη του συστήματός σας στον υπολογιστή σας, όπου τρέχετε το Docker. Με αυτόν τον τρόπο, οποιαδήποτε αρχεία δημιουργούνται από αυτές τις εντολές αντιγράφονται στον υπολογιστή σας με τα σωστά δικαιώματα. Αυτό σημαίνει επίσης ότι θα μπορείτε να χρησιμοποιείτε τον επεξεργαστή κώδικα της επιλογής σας στον υπολογιστή σας για να αναπτύξετε την εφαρμογή που τρέχει μέσα στα containers.
Δημιουργήστε ένα νέο αρχείο Dockerfile με:
nano DockerfileΑντιγράψτε τα παρακάτω περιεχόμενα στο αρχείο Dockerfile σας:
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# Set working directory
WORKDIR /var/www
USER $user
Μην ξεχάσεις να αποθηκεύσεις το αρχείο όταν τελειώσεις.
Το Dockerfile μας ξεκινά ορίζοντας την βασική εικόνα που χρησιμοποιούμε: php:7.4-fpm.
Μετά την εγκατάσταση πακέτων συστήματος και επεκτάσεων PHP, εγκαθιστούμε το Composer αντιγράφοντας το εκτελέσιμο composer από την πιο πρόσφατη επίσημη εικόνα του στην δική μας εικόνα εφαρμογής.
Στη συνέχεια δημιουργείται και ρυθμίζεται ένας νέος χρήστης συστήματος χρησιμοποιώντας τα επιχειρήματα user και uid που δηλώθηκαν στην αρχή του Dockerfile. Αυτές οι τιμές θα εγχέονται από το Docker Compose κατά τον χρόνο δημιουργίας.
Τέλος, ορίζουμε τον προεπιλεγμένο κατάλογο εργασίας ως /var/www και αλλάζουμε στον νεοδημιουργημένο χρήστη. Αυτό θα εξασφαλίσει ότι συνδέεστε ως κανονικός χρήστης και ότι βρίσκεστε στον σωστό κατάλογο κατά την εκτέλεση των εντολών composer και artisan στο container της εφαρμογής.
Βήμα 4 — Ρύθμιση Διαμόρφωσης Nginx και Αρχείων Αντιγράφων Βάσης Δεδομένων
Όταν δημιουργείτε περιβάλλοντα ανάπτυξης με το Docker Compose, συχνά είναι απαραίτητο να μοιράζεστε αρχεία ρυθμίσεων ή αρχικοποίησης με τα κοντέινερ υπηρεσιών, προκειμένου να ρυθμίσετε ή να εκκινήσετε αυτές τις υπηρεσίες. Αυτή η πρακτική διευκολύνει την τροποποίηση των αρχείων ρυθμίσεων για να βελτιστοποιήσετε το περιβάλλον σας ενώ αναπτύσσετε την εφαρμογή.
Τώρα θα δημιουργήσουμε ένα φάκελο με αρχεία που θα χρησιμοποιηθούν για τη διαμόρφωση και την εκκίνηση των κοντέινερ υπηρεσιών μας.
Για να ρυθμίσουμε το Nginx, θα μοιραστούμε ένα αρχείο travellist.conf που θα καθορίζει τον τρόπο με τον οποίο θα εξυπηρετείται η εφαρμογή. Δημιουργήστε τον φάκελο docker-compose/nginx με:
mkdir -p docker-compose/nginxΆνοιξε ένα νέο αρχείο με όνομα travellist.conf μέσα σε αυτόν τον κατάλογο:
nano docker-compose/nginx/travellist.confΑντιγράψτε την παρακάτω διαμόρφωση Nginx σε αυτό το αρχείο:
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}Αυτό το αρχείο θα ρυθμίσει το Nginx να ακούει στην θύρα 80 και να χρησιμοποιεί το index.php ως προεπιλεγμένη σελίδα ευρετηρίου. Θα ορίσει τη ρίζα των εγγράφων στο /var/www/public, και στη συνέχεια θα ρυθμίσει το Nginx να χρησιμοποιεί την υπηρεσία app στην θύρα 9000 για να επεξεργάζεται αρχεία *.php.
Αποθήκευσε και κλείσε το αρχείο όταν τελειώσεις την επεξεργασία.
Για να ρυθμίσουμε τη βάση δεδομένων MySQL, θα μοιραστούμε ένα dump της βάσης δεδομένων που θα εισαχθεί όταν ξεκινήσει το container. Αυτό είναι ένα χαρακτηριστικό που παρέχεται από την εικόνα MySQL 8.0 που θα χρησιμοποιήσουμε σε αυτό το container.
Δημιουργήστε έναν νέο φάκελο για τα αρχεία αρχικοποίησης του MySQL μέσα στο φάκελο docker-compose:
mkdir docker-compose/mysqlΆνοιξε ένα νέο αρχείο .sql:
nano docker-compose/mysql/init_db.sqlΤο παρακάτω dump MySQL βασίζεται στη βάση δεδομένων που έχουμε δημιουργήσει στον οδηγό μας για Laravel σε LEMP. Θα δημιουργήσει έναν νέο πίνακα με το όνομα places. Στη συνέχεια, θα γεμίσει τον πίνακα με ένα σύνολο παραδειγματικών τοποθεσιών.
Προσθέστε τον παρακάτω κώδικα στο αρχείο:
DROP TABLE IF EXISTS `places`;
CREATE TABLE `places` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`visited` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);Ο πίνακας places περιλαμβάνει τρία πεδία: id, name και visited. Το πεδίο visited είναι μία σημαία που χρησιμοποιείται για να εντοπίζονται οι τοποθεσίες που είναι ακόμα να επισκεφθείτε. Μπορείτε να αλλάξετε τις υπάρχουσες τοποθεσίες ή να προσθέσετε νέες. Αποθηκεύστε και κλείστε το αρχείο όταν ολοκληρώσετε.
Έχουμε ολοκληρώσει τη ρύθμιση του Dockerfile της εφαρμογής και των αρχείων διαμόρφωσης των υπηρεσιών. Στη συνέχεια, θα ρυθμίσουμε το Docker Compose για να χρησιμοποιεί αυτά τα αρχεία κατά τη δημιουργία των υπηρεσιών μας.
Βήμα 5 — Δημιουργία περιβάλλοντος με πολλαπλά κοντέινερ χρησιμοποιώντας το Docker Compose
Το Docker Compose σας επιτρέπει να δημιουργείτε περιβάλλοντα με πολλαπλά κοντέινερ για εφαρμογές που τρέχουν στο Docker. Χρησιμοποιεί ορισμούς υπηρεσιών για να δημιουργήσει πλήρως παραμετροποιήσιμα περιβάλλοντα με πολλαπλά κοντέινερ που μπορούν να μοιράζονται δίκτυα και όγκους δεδομένων. Αυτό επιτρέπει μια ομαλή ενσωμάτωση μεταξύ των στοιχείων της εφαρμογής.
Για να ορίσουμε τους ορισμούς υπηρεσιών μας, θα δημιουργήσουμε ένα νέο αρχείο με το όνομα docker-compose.yml. Συνήθως, αυτό το αρχείο βρίσκεται στη ρίζα του φακέλου της εφαρμογής και ορίζει το περιβάλλον με κοντέινερ σας, συμπεριλαμβανομένων των βασικών εικόνων που θα χρησιμοποιήσετε για να κατασκευάσετε τα κοντέινερ σας και πώς θα αλληλεπιδρούν οι υπηρεσίες σας.
Θα ορίσουμε τρεις διαφορετικές υπηρεσίες στο αρχείο μας docker-compose.yml: app, db και nginx.
Η υπηρεσία app θα δημιουργήσει μια εικόνα με όνομα travellist, βασισμένη στο Dockerfile που έχουμε δημιουργήσει προηγουμένως. Το κοντέινερ που ορίζεται από αυτή την υπηρεσία θα τρέχει έναν διακομιστή php-fpm για να αναλύει κώδικα PHP και να στέλνει τα αποτελέσματα πίσω στην υπηρεσία nginx, η οποία θα τρέχει σε ξεχωριστό κοντέινερ. Η υπηρεσία mysql ορίζει ένα κοντέινερ που τρέχει διακομιστή MySQL 8.0. Οι υπηρεσίες μας θα μοιράζονται ένα δικτυακό δίκτυο γέφυρας με όνομα travellist.
Τα αρχεία της εφαρμογής θα συγχρονιστούν και στις υπηρεσίες app και nginx μέσω bind mounts. Τα bind mounts είναι χρήσιμα σε περιβάλλοντα ανάπτυξης επειδή επιτρέπουν έναν αποτελεσματικό διπλής κατεύθυνσης συγχρονισμό μεταξύ του μηχανήματος υποδοχής και των containers.
Δημιουργήστε ένα νέο αρχείο docker-compose.yml στο ριζικό φάκελο της εφαρμογής:
nano docker-compose.ymlΈνα τυπικό αρχείο docker-compose.yml ξεκινά με έναν ορισμό έκδοσης, ακολουθούμενο από έναν κόμβο services, κάτω από τον οποίο ορίζονται όλες οι υπηρεσίες. Τα κοινόχρηστα δίκτυα συνήθως ορίζονται στο κάτω μέρος αυτού του αρχείου.
Για να ξεκινήσετε, αντιγράψτε αυτόν τον βασικό κώδικα στο αρχείο σας docker-compose.yml:
version: "3.9"
services:
networks:
travellist:
driver: bridgeΤώρα θα επεξεργαστούμε τον κόμβο services για να περιλάβουμε τις υπηρεσίες app, db και nginx.
Η υπηρεσία app
Η υπηρεσία app θα δημιουργήσει ένα κοντέινερ με το όνομα travellist-app. Δημιουργεί μια νέα εικόνα Docker βασισμένη σε ένα Dockerfile που βρίσκεται στην ίδια διαδρομή με το αρχείο docker-compose.yml. Η νέα εικόνα θα αποθηκευτεί τοπικά με το όνομα travellist.
Παρόλο που η ριζική διαδρομή του εγγράφου που εξυπηρετείται ως εφαρμογή βρίσκεται στο κοντέινερ nginx, χρειάζουμε τα αρχεία της εφαρμογής κάπου μέσα στο κοντέινερ app επίσης, ώστε να μπορούμε να εκτελούμε εργασίες γραμμής εντολών με το εργαλείο Laravel Artisan.
Αντιγράψτε τον παρακάτω ορισμό υπηρεσίας κάτω από τον κόμβο services, μέσα στο αρχείο docker-compose.yml:
app:
build:
args:
user: sammy
uid: 1000
context: ./
dockerfile: Dockerfile
image: travellist
container_name: travellist-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- travellistΑυτές οι ρυθμίσεις κάνουν τα εξής:
build: Αυτή η ρύθμιση λέει στο Docker Compose να δημιουργήσει μια τοπική εικόνα για την υπηρεσίαapp, χρησιμοποιώντας τη συγκεκριμένη διαδρομή (context) και το Dockerfile για οδηγίες. Τα επιχειρήματαuserκαιuidεισάγονται στο Dockerfile για να προσαρμόσουν τις εντολές δημιουργίας χρήστη κατά τον χρόνο κατασκευής.image: Το όνομα που θα χρησιμοποιηθεί για την εικόνα που δημιουργείται.container_name: Ορίζει το όνομα του container για αυτήν την υπηρεσία.restart: Επανεκκινήστε πάντα, εκτός αν η υπηρεσία είναι σταματημένη.working_dir: Ορίζει τον προεπιλεγμένο κατάλογο για αυτήν την υπηρεσία ως/var/www.όγκοι: Δημιουργεί έναν κοινόχρηστο όγκο που θα συγχρονίζει τα περιεχόμενα από τον τρέχοντα φάκελο στο/var/wwwμέσα στο container. Σημειώστε ότι αυτό δεν είναι η ρίζα των εγγράφων σας, καθώς αυτή θα βρίσκεται στοnginxcontainer.δίκτυα: Διαμορφώνει αυτήν την υπηρεσία ώστε να χρησιμοποιεί ένα δίκτυο με όνομαtravellist.
Η υπηρεσία db
Η υπηρεσία db χρησιμοποιεί μια προκατασκευασμένη εικόνα MySQL 8.0 από το Docker Hub. Επειδή το Docker Compose φορτώνει αυτόματα αρχεία μεταβλητών .env που βρίσκονται στον ίδιο φάκελο με το αρχείο docker-compose.yml, μπορούμε να πάρουμε τις ρυθμίσεις της βάσης δεδομένων μας από το αρχείο .env του Laravel που δημιουργήσαμε σε προηγούμενο βήμα.
Συμπεριλάβετε τον παρακάτω ορισμό υπηρεσίας στον κόμβο services, αμέσως μετά την υπηρεσία app:
db:
image: mysql:8.0
container_name: travellist-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- travellistΑυτές οι ρυθμίσεις κάνουν τα εξής:
image: Καθορίζει το Docker image που θα χρησιμοποιηθεί για αυτό το container. Σε αυτή την περίπτωση, χρησιμοποιούμε ένα image MySQL 8.0 από το Docker Hub.container_name: Ορίζει το όνομα του κοντέινερ για αυτή την υπηρεσία:travellist-db.restart: Επανεκκινήστε πάντα αυτήν την υπηρεσία, εκτός αν έχει διακοπεί ρητά.environment: Ορίζει μεταβλητές περιβάλλοντος στο νέο κοντέινερ. Χρησιμοποιούμε τιμές που λαμβάνονται από το αρχείο.envτου Laravel για να ρυθμίσουμε την υπηρεσία MySQL μας, η οποία θα δημιουργήσει αυτόματα μια νέα βάση δεδομένων και χρήστη με βάση τις παρεχόμενες μεταβλητές περιβάλλοντος.volumes: Δημιουργεί έναν τόμο για να μοιραστεί ένα αντίγραφο ασφαλείας βάσης δεδομένων.sqlπου θα χρησιμοποιηθεί για την αρχικοποίηση της βάσης δεδομένων της εφαρμογής. Η εικόνα MySQL θα εισάγει αυτόματα τα αρχεία.sqlπου τοποθετούνται στον κατάλογο/docker-entrypoint-initdb.dμέσα στο container.δίκτυα: Διαμορφώνει αυτήν την υπηρεσία ώστε να χρησιμοποιεί ένα δίκτυο με όνομαtravellist.
Η υπηρεσία nginx
Η υπηρεσία nginx χρησιμοποιεί μια προεγκατεστημένη εικόνα Nginx πάνω σε Alpine, μια ελαφριά διανομή Linux. Δημιουργεί ένα container με το όνομα travellist-nginx και χρησιμοποιεί τον ορισμό ports για να δημιουργήσει μια ανακατεύθυνση από την θύρα 8000 στο σύστημα φιλοξενίας στην θύρα 80 μέσα στο container.
Συμπεριλάβετε τον παρακάτω ορισμό υπηρεσίας στον κόμβο services, αμέσως μετά την υπηρεσία db:
nginx:
image: nginx:1.17-alpine
container_name: travellist-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d
networks:
- travellistΑυτές οι ρυθμίσεις κάνουν τα εξής:
image: Ορίζει την εικόνα Docker που θα πρέπει να χρησιμοποιηθεί για αυτό το container. Σε αυτή την περίπτωση, χρησιμοποιούμε την εικόνα Alpine Nginx 1.17.container_name: Ορίζει το όνομα του κοντέινερ για αυτή την υπηρεσία: travellist-nginx.restart: Επανεκκινήστε πάντα αυτήν την υπηρεσία, εκτός αν έχει διακοπεί ρητά.ports: Ρυθμίζει μια ανακατεύθυνση θύρας που θα επιτρέψει εξωτερική πρόσβαση μέσω της θύρας8000στον διακομιστή ιστού που εκτελείται στη θύρα80μέσα στο container.volumes: Δημιουργεί δύο κοινόχρηστους όγκους. Ο πρώτος θα συγχρονίζει το περιεχόμενο από τον τρέχοντα κατάλογο στο/var/wwwμέσα στο container. Με αυτόν τον τρόπο, όταν κάνετε τοπικές αλλαγές στα αρχεία της εφαρμογής, θα αντικατοπτρίζονται γρήγορα στην εφαρμογή που εξυπηρετείται από το Nginx μέσα στο container. Ο δεύτερος όγκος θα διασφαλίσει ότι το αρχείο διαμόρφωσης του Nginx μας, που βρίσκεται στοdocker-compose/nginx/travellist.conf, αντιγράφεται στον φάκελο διαμόρφωσης του Nginx του container.networks: Ρυθμίζει αυτήν την υπηρεσία να χρησιμοποιεί ένα δίκτυο με όνομαtravellist.
Ολοκληρωμένο αρχείο docker-compose.yml
Έτσι φαίνεται το τελικό μας αρχείο docker-compose.yml:
version: "3.9"
services:
app:
build:
args:
user: sammy
uid: 1000
context: ./
dockerfile: Dockerfile
image: travellist
container_name: travellist-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- travellist
db:
image: mysql:8.0
container_name: travellist-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- travellist
nginx:
image: nginx:1.17-alpine
container_name: travellist-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- travellist
networks:
travellist:
driver: bridgeΒεβαιώσου ότι θα αποθηκεύσεις το αρχείο όταν τελειώσεις.
Βήμα 6 — Εκτέλεση της Εφαρμογής με Docker Compose
Τώρα θα χρησιμοποιήσουμε τις εντολές docker compose για να δημιουργήσουμε την εικόνα της εφαρμογής και να τρέξουμε τις υπηρεσίες που ορίσαμε στη ρύθμισή μας.
Δημιουργήστε την εικόνα app με την ακόλουθη εντολή:
docker compose build appΑυτή η εντολή μπορεί να χρειαστεί μερικά λεπτά για να ολοκληρωθεί. Θα δείτε έξοδο παρόμοια με αυτή:
Building app
Sending build context to Docker daemon 377.3kB
Step 1/11 : FROM php:7.4-fpm
---> 8c08d993542f
Step 2/11 : ARG user
---> e3ce3af04d87
Step 3/11 : ARG uid
---> 30cb921ef7df
Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev libxml2-dev zip unzip
. . .
---> b6dbc7a02e95
Step 5/11 : RUN apt-get clean && rm -rf /var/lib/apt/lists/*
---> 10ef9dde45ad
. . .
Step 6/11 : RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
. . .
---> 920e4f09ec75
Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
---> dbbcd44e44af
Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user
---> db98e899a69a
Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user
---> 5119e26ebfea
Step 10/11 : WORKDIR /var/www
---> 699c491611c0
Step 11/11 : USER $user
---> cf250fe8f1af
Successfully built cf250fe8f1af
Successfully tagged travellist:latestΌταν ολοκληρωθεί η κατασκευή, μπορείτε να εκτελέσετε το περιβάλλον σε λειτουργία υποβάθρου με:
docker compose up -dCreating travellist-db ... done
Creating travellist-app ... done
Creating travellist-nginx ... doneΑυτό θα εκτελέσει τα κοντέινερ σας στο παρασκήνιο. Για να εμφανίσετε πληροφορίες σχετικά με την κατάσταση των ενεργών υπηρεσιών σας, εκτελέστε:
docker compose psΘα δείτε έξοδο όπως αυτή:
Name Command State Ports
-----------------------------------------------------------------------------------------------
travellist-app docker-php-entrypoint php-fpm Up 9000/tcp
travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
travellist-nginx nginx -g daemon off; Up 0.0.0.0:8000->80/tcp,:::8000->80/tcpΤο περιβάλλον σας είναι πλέον σε λειτουργία.
Τώρα μπορείτε να επαληθεύσετε ότι κάθε υπηρεσία σε κοντέινερ ανταποκρίνεται σωστά χρησιμοποιώντας απλές εντολές curl.
Για να δοκιμάσετε την υπηρεσία ιστού Nginx:
curl -I http://localhost:8000Αναμενόμενο αποτέλεσμα:
HTTP/1.1 200 OK Server: nginx/1.17.10 Content-Type: text/html; charset=UTF-8Αυτό επιβεβαιώνει ότι το κοντέινερ Nginx λειτουργεί και παρέχει απαντήσεις από την εφαρμογή σας Laravel.
Για να δοκιμάσετε το PHP-FPM μέσω Nginx:
curl -s http://localhost:8000 | grep "Berlin"Αν η εφαρμογή λειτουργεί σωστά, αυτή η εντολή επιστρέφει το HTML της σελίδας καλωσορίσματος που περιλαμβάνει τη λέξη Βερολίνο.
Ακόμα χρειάζεται να εκτελέσουμε μερικές εντολές για να ολοκληρώσουμε τη ρύθμιση της εφαρμογής. Μπορείτε να χρησιμοποιήσετε την εντολή docker compose exec για να εκτελέσετε εντολές μέσα στα κοντέινερ της υπηρεσίας, όπως μια ls -l για να δείτε λεπτομερείς πληροφορίες σχετικά με τα αρχεία στον κατάλογο της εφαρμογής:
docker compose exec app ls -ltotal 256
-rw-r--r-- 1 sammy sammy 737 Apr 18 14:21 Dockerfile
-rw-r--r-- 1 sammy sammy 101 Jan 7 2020 README.md
drwxr-xr-x 6 sammy sammy 4096 Jan 7 2020 app
-rwxr-xr-x 1 sammy sammy 1686 Jan 7 2020 artisan
drwxr-xr-x 3 sammy sammy 4096 Jan 7 2020 bootstrap
-rw-r--r-- 1 sammy sammy 1501 Jan 7 2020 composer.json
-rw-r--r-- 1 sammy sammy 179071 Jan 7 2020 composer.lock
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 config
drwxr-xr-x 5 sammy sammy 4096 Jan 7 2020 database
drwxr-xr-x 4 sammy sammy 4096 Apr 18 14:22 docker-compose
-rw-r--r-- 1 sammy sammy 1017 Apr 18 14:29 docker-compose.yml
-rw-r--r-- 1 sammy sammy 1013 Jan 7 2020 package.json
-rw-r--r-- 1 sammy sammy 1405 Jan 7 2020 phpunit.xml
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 public
-rw-r--r-- 1 sammy sammy 273 Jan 7 2020 readme.md
drwxr-xr-x 6 sammy sammy 4096 Jan 7 2020 resources
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 routes
-rw-r--r-- 1 sammy sammy 563 Jan 7 2020 server.php
drwxr-xr-x 5 sammy sammy 4096 Jan 7 2020 storage
drwxr-xr-x 4 sammy sammy 4096 Jan 7 2020 tests
-rw-r--r-- 1 sammy sammy 538 Jan 7 2020 webpack.mix.jsΤώρα θα εκτελέσουμε composer install για να εγκαταστήσουμε τις εξαρτήσεις της εφαρμογής:
docker compose exec app rm -rf vendor composer.lock
docker compose exec app composer installΘα δείτε έξοδο όπως αυτή:
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
. . .
Lock file operations: 89 installs, 0 updates, 0 removals
- Locking doctrine/inflector (2.0.4)
- Locking doctrine/instantiator (1.4.1)
- Locking doctrine/lexer (1.2.3)
- Locking dragonmantank/cron-expression (v2.3.1)
- Locking egulias/email-validator (2.1.25)
- Locking facade/flare-client-php (1.9.1)
- Locking facade/ignition (1.18.1)
- Locking facade/ignition-contracts (1.0.2)
- Locking fideloper/proxy (4.4.1)
- Locking filp/whoops (2.14.5)
. . .
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 89 installs, 0 updates, 0 removals
- Downloading doctrine/inflector (2.0.4)
- Downloading doctrine/lexer (1.2.3)
- Downloading dragonmantank/cron-expression (v2.3.1)
- Downloading symfony/polyfill-php80 (v1.25.0)
- Downloading symfony/polyfill-php72 (v1.25.0)
- Downloading symfony/polyfill-mbstring (v1.25.0)
- Downloading symfony/var-dumper (v4.4.39)
- Downloading symfony/deprecation-contracts (v2.5.1)
. . .
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.Το τελευταίο πράγμα που πρέπει να κάνουμε πριν δοκιμάσουμε την εφαρμογή είναι να δημιουργήσουμε ένα μοναδικό κλειδί εφαρμογής με το εργαλείο γραμμής εντολών artisan του Laravel. Αυτό το κλειδί χρησιμοποιείται για την κρυπτογράφηση των συνεδριών χρηστών και άλλων ευαίσθητων δεδομένων:
docker compose exec app php artisan key:generateApplication key set successfully.Τώρα πηγαίνετε στον περιηγητή σας και αποκτήστε πρόσβαση στο όνομα τομέα ή στη διεύθυνση IP του διακομιστή σας στη θύρα 8000:
http://server_domain_or_IP:8000Σημείωση: Σε περίπτωση που εκτελείτε αυτή τη δοκιμή στον τοπικό σας υπολογιστή, χρησιμοποιήστε http://localhost:8000 για να αποκτήσετε πρόσβαση στην εφαρμογή από τον περιηγητή σας.
Θα δείτε μια σελίδα σαν αυτή:
Μπορείτε επίσης να δοκιμάσετε την εφαρμογή Laravel από μέσα στο container της εφαρμογής χωρίς να χρησιμοποιήσετε πρόγραμμα περιήγησης:
docker compose exec app curl http://nginxΑν όλα είναι ρυθμισμένα σωστά, θα πρέπει να δείτε την HTML έξοδο της προεπιλεγμένης σελίδας καλωσορίσματος του Laravel.
<html>
<head>
<title>Travel List</title>
</head>
<body>
<h1>My Travel Bucket List</h1>
<h2>Places I'd Like to Visit</h2>
<ul>
<li>Berlin</li>
<li>Budapest</li>
<li>Denver</li>
<li>Helsinki</li>
<li>Lisbon</li>
<li>Nairobi</li>
<li>Rio</li>
<li>Tokyo</li>
</ul>
<h2>Places I've Already Been To</h2>
<ul>
<li>Cincinnati</li>
<li>Moscow</li>
<li>Oslo</li>
</ul>
</body>
</html>Μπορείτε να χρησιμοποιήσετε την εντολή logs για να ελέγξετε τα αρχεία καταγραφής που δημιουργούνται από τις υπηρεσίες σας:
docker compose logs nginxAttaching to travellist-nginx
. . .
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:49:16 +0000] "GET / HTTP/1.1" 200 627 "-" "curl/7.82.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET /favicon.ico HTTP/1.1" 200 0 "http://localhost:8000/" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"Μπορείτε επίσης να χρησιμοποιήσετε την παρακάτω εντολή curl για να δημιουργήσετε καταχωρήσεις καταγραφής:
curl http://localhost:8000Στη συνέχεια εκτέλεσε ξανά:
docker compose logs nginxΤώρα θα πρέπει να δείτε μια αντίστοιχη καταχώρηση στο αρχείο καταγραφής πρόσβασης για το αίτημά σας.
Αν θέλετε να σταματήσετε προσωρινά το περιβάλλον Docker Compose ενώ διατηρείτε την κατάσταση όλων των υπηρεσιών του, εκτελέστε:
docker compose pausePausing travellist-db ... done
Pausing travellist-nginx ... done
Pausing travellist-app ... doneΜπορείτε στη συνέχεια να συνεχίσετε τις υπηρεσίες σας με:
docker compose unpauseUnpausing travellist-app ... done
Unpausing travellist-nginx ... done
Unpausing travellist-db ... doneΓια να τερματίσετε το περιβάλλον Docker Compose και να αφαιρέσετε όλα τα containers, τα δίκτυα και τους τόμους του, εκτελέστε:
docker compose downStopping travellist-nginx ... done
Stopping travellist-db ... done
Stopping travellist-app ... done
Removing travellist-nginx ... done
Removing travellist-db ... done
Removing travellist-app ... done
Removing network travellist-laravel-demo_travellistΓια μια επισκόπηση όλων των εντολών του Docker Compose, παρακαλώ ελέγξτε την αναφορά εντολών γραμμής εντολών του Docker Compose.
Διόρθωση Δικαιωμάτων Αρχείων και Φακέλων στο Laravel
Όταν τρέχετε Laravel μέσα σε κοντέινερ Docker, ένα από τα πιο συχνά προβλήματα που αντιμετωπίζουν οι προγραμματιστές σχετίζεται με τα δικαιώματα αρχείων και φακέλων. Το Laravel απαιτεί κάποιοι φάκελοι να είναι εγγράψιμοι από τη διεργασία PHP-FPM μέσα στο κοντέινερ app. Εάν αυτοί οι φάκελοι δεν είναι εγγράψιμοι, η εφαρμογή μπορεί να αποτύχει να καταγράψει σφάλματα, να αποθηκεύσει σωστά τα αρχεία ρυθμίσεων cache ή να διαχειριστεί σωστά τα δεδομένα συνεδρίας.
Μπορεί να συναντήσετε μηνύματα όπως:
The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission deniedή
file_put_contents(/var/www/bootstrap/cache/config.php): Failed to open stream: Permission deniedΑυτά τα σφάλματα υποδηλώνουν ότι ο χρήστης που εκτελεί PHP μέσα στο κοντέινερ δεν έχει άδεια να γράψει στους απαραίτητους φακέλους.
Τα ακόλουθα βήματα περιγράφουν πώς να διαγνώσετε και να διορθώσετε αυτά τα προβλήματα τόσο σε τοπικά όσο και σε παραγωγικά περιβάλλοντα.
Ρύθμιση Δικαιωμάτων Φακέλου για Εγγραφή
Το Laravel απαιτεί δύο καταλόγους ώστε να μπορούν να τροποποιηθούν από τον χρήστη του web server:
/var/www/storage/var/www/bootstrap/cache
Αν δείτε σφάλματα αδειών, μπορείτε να τα διορθώσετε ρυθμίζοντας την ιδιοκτησία και τις άδειες από μέσα στο container:
docker compose exec app chown -R sammy:sammy /var/www/storage /var/www/bootstrap/cache
docker compose exec app chmod -R 775 /var/www/storage /var/www/bootstrap/cacheΑν το Dockerfile σας χρησιμοποιεί διαφορετικό όνομα χρήστη (ορίζεται μέσω του επιχειρήματος κατασκευής user), αντικαταστήστε το sammy με αυτό το όνομα χρήστη.
Μπορείτε να επαληθεύσετε την ιδιοκτησία με την ακόλουθη εντολή:
docker compose exec app ls -ld /var/www/storage /var/www/bootstrap/cacheΗ έξοδος θα πρέπει να δείχνει ότι ο χρήστης και η ομάδα ταιριάζουν με τη διαδικασία PHP-FPM μέσα στο κοντέινερ.
Αν θέλετε να προσαρμόσετε τα δικαιώματα από τον υπολογιστή-ξενιστή, εκτελέστε:
sudo chown -R $(id -u):$(id -g) storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cacheΑυτό εξασφαλίζει ότι και οι δύο κατάλογοι του Laravel είναι εγγράψιμοι από το container και τον χρήστη του host σας.
Ορίστε την Ιδιοκτησία Φακέλου κατά τη Δόμηση Εικόνας
Για να αποφύγετε την επανάληψη προβλημάτων δικαιωμάτων μετά από κάθε επανεκκίνηση, μπορείτε να ορίσετε την ιδιοκτησία του καταλόγου κατά τη διαδικασία δημιουργίας της εικόνας Docker. Ανοίξτε το Dockerfile σας και προσθέστε την ακόλουθη γραμμή κοντά στο τέλος, πριν αλλάξετε στον χρήστη χωρίς δικαιώματα root:
RUN chown -R $user:www-data /var/wwwΑυτή η εντολή διασφαλίζει ότι όλα τα αρχεία και οι φάκελοι κάτω από το /var/www ανήκουν στον χρήστη που ορίσατε στο Dockerfile σας.
Για μια πιο στοχευμένη και ασφαλή προσέγγιση, μπορείτε να προσαρμόσετε μόνο τους φακέλους στους οποίους χρειάζεται να γράφει το Laravel:
RUN chown -R $user:www-data /var/www/storage /var/www/bootstrap/cacheΜετά την πραγματοποίηση αυτής της αλλαγής, επανακατασκευάστε την εικόνα και επανεκκινήστε τα κοντέινερ:
docker compose build app
docker compose up -dΤην επόμενη φορά που θα ξεκινήσει το κοντέινερ, θα έχει ήδη τα σωστά δικαιώματα.
Επαληθεύστε τη Συνοχή του Αναγνωριστικού Χρήστη μεταξύ Host και Container
Όταν χρησιμοποιείτε bind mounts, το Docker μοιράζεται αρχεία μεταξύ του υπολογιστή σας και του container. Εάν ο αριθμητικός UID του χρήστη του υπολογιστή διαφέρει από τον UID που έχει οριστεί στο container, ενδέχεται να προκύψουν συγκρούσεις στην ιδιοκτησία των αρχείων. Αυτό είναι συνηθισμένο σε συστήματα όπου οι ταυτότητες χρήστη διαφέρουν μεταξύ των μηχανημάτων.
Για να επαληθεύσετε τις τιμές UID, εκτελέστε:
id -u $(whoami)
docker compose exec app id -uΕάν αυτοί οι δύο αριθμοί δεν ταιριάζουν, ενημερώστε το αρχείο σας docker-compose.yml για να περάσετε το πραγματικό σας UID στη διαδικασία κατασκευής:
build:
args:
user: sammy
uid: 1000Στη συνέχεια, ξαναχτίστε την εικόνα:
docker compose build app
docker compose up -dΑυτό εξασφαλίζει ότι ο χρήστης του κοντέινερ ταιριάζει με τον χρήστη του υπολογιστή σας, αποτρέποντας δυσκολίες λόγω αδειών στα αρχεία που έχουν προσαρτηθεί με bind mount.
Διορθώστε τα Δικαιώματα του Καταλόγου Cache του Composer
Ο Composer αποθηκεύει τις ληφθείσες εξαρτήσεις και τα αρχεία προσωρινής μνήμης στον κατάλογο αρχικής σελίδας του χρήστη μέσα στο container (/home/sammy/.composer). Εάν αυτός ο κατάλογος δεν είναι εγγράψιμος, μπορεί να δείτε προειδοποιήσεις όπως:
Cannot create cache directory /home/sammy/.composer/cacheΜπορείτε να διορθώσετε αυτό δημιουργώντας τον κατάλογο cache και αναθέτοντας τη σωστή ιδιοκτησία:
docker compose exec app mkdir -p /home/sammy/.composer/cache
docker compose exec app chown -R sammy:sammy /home/sammy/.composerΑυτό διασφαλίζει ότι το Composer μπορεί να αποθηκεύει εξαρτήσεις και αρχεία προσωρινής μνήμης χωρίς σφάλματα αδειών, κάτι που επίσης επιταχύνει τις μελλοντικές εκτελέσεις του composer install.
Συνιστώμενες Πρακτικές για Περιβάλλοντα Παραγωγής
Στην παραγωγή, η διαχείριση των αδειών θα πρέπει να γίνεται κατά τη διάρκεια της δημιουργίας της εικόνας και όχι κατά την εκτέλεση. Αυτό βελτιώνει την συνέπεια και την ασφάλεια.
Ακολουθήστε αυτές τις πρακτικές για μια ρύθμιση έτοιμη για παραγωγή:
Αποφεύγετε τα bind mounts για τον κώδικα της εφαρμογής: Αντίθετα, αντιγράψτε τα αρχεία της εφαρμογής στην εικόνα κατά τη διάρκεια της κατασκευής. Τα bind mounts θα πρέπει να χρησιμοποιούνται μόνο για ανάπτυξη.
Ορισμός δικαιωμάτων κατά τη διάρκεια της κατασκευής: Προσθέστε τις εντολές
RUN chownκαιchmodστο Dockerfile σας για να διασφαλίσετε τα σωστά δικαιώματα ιδιοκτησίας και πρόσβασης πριν από την ανάπτυξη.Χρησιμοποιήστε τον χρήστη με τα λιγότερα δικαιώματα: Βεβαιωθείτε ότι η διαδικασία PHP εκτελείται υπό έναν χρήστη χωρίς δικαιώματα root (η τρέχουσα ρύθμιση με
$userήδη το κάνει αυτό).Περιορίστε τα δικαιώματα σε φακέλους που δεν είναι εγγράψιμοι: Τα περισσότερα αρχεία εφαρμογών θα πρέπει να είναι μόνο για ανάγνωση. Μπορείτε να το επιβάλετε με:
chmod -R 755 /var/www chmod -R 775 /var/www/storage /var/www/bootstrap/cacheΑυτή η ρύθμιση επιτρέπει στο Laravel να γράφει μόνο όπου είναι απαραίτητο, ενώ προστατεύει τα υπόλοιπα αρχεία της εφαρμογής από τροποποίηση.
Ακολουθώντας αυτά τα βήματα, τα κοντέινερ Laravel σας θα έχουν σταθερές, προβλέψιμες άδειες αρχείων τόσο σε τοπικά όσο και σε περιβάλλοντα παραγωγής. Αυτό μειώνει τα επαναλαμβανόμενα σφάλματα και εξασφαλίζει ότι το Laravel μπορεί να καταγράφει δεδομένα, να αποθηκεύει προσωρινά αρχεία και να γράφει συνεδρίες με αξιοπιστία.
Κατανόηση του docker-compose.override.yml για Τοπικά και Παραγωγικά Περιβάλλοντα
Το Docker Compose σας επιτρέπει να ορίζετε εφαρμογές με πολλαπλά κοντέινερ χρησιμοποιώντας ένα μόνο αρχείο ρυθμίσεων. Στις περισσότερες περιπτώσεις, αυτή η ρύθμιση αποθηκεύεται σε ένα αρχείο με όνομα docker-compose.yml. Ωστόσο, η διαχείριση πολλαπλών περιβαλλόντων, όπως η τοπική ανάπτυξη και η παραγωγή, συχνά απαιτεί προσαρμογές που αφορούν το συγκεκριμένο περιβάλλον. Εδώ είναι που το αρχείο docker-compose.override.yml γίνεται χρήσιμο.
Από προεπιλογή, το Docker Compose αναζητά αυτόματα ένα αρχείο με το όνομα docker-compose.override.yml στον ίδιο φάκελο με το βασικό αρχείο Compose. Όταν βρεθεί, συγχωνεύει τις ρυθμίσεις και από τα δύο αρχεία όταν εκτελείτε οποιαδήποτε εντολή docker compose. Αυτή η προσέγγιση επιτρέπει στους προγραμματιστές να διατηρούν μια καθαρή, επαναχρησιμοποιήσιμη βασική διαμόρφωση, ενώ προσαρμόζουν συγκεκριμένες πτυχές της ρύθμισης για τοπική ή παραγωγική χρήση.
Ο ρόλος του docker-compose.override.yml
Το αρχείο docker-compose.override.yml είναι μια επέκταση της βασικής διαμόρφωσης Compose. Τροποποιεί ή προσθέτει ιδιότητες που εφαρμόζονται μόνο σε ένα συγκεκριμένο περιβάλλον, χωρίς να απαιτούνται αλλαγές στο κύριο αρχείο docker-compose.yml. Το αρχείο override είναι ιδιαίτερα χρήσιμο σε ροές εργασίας τοπικής ανάπτυξης, όπου οι προγραμματιστές συχνά χρειάζεται να συνδέσουν τον πηγαίο κώδικα, να ενεργοποιήσουν εργαλεία αποσφαλμάτωσης ή να τροποποιήσουν μεταβλητές περιβάλλοντος για δοκιμές.
Όταν εκτελείτε την εντολή docker compose up, το Docker συγχωνεύει αυτόματα τα περιεχόμενα των docker-compose.yml και docker-compose.override.yml. Αν μια υπηρεσία, ένα volume ή μια ρύθμιση είναι ορισμένα και στα δύο αρχεία, οι τιμές στο αρχείο υπέρθεσης έχουν προτεραιότητα.
Για να χρησιμοποιήσετε ένα διαφορετικό αρχείο παράκαμψης, για παράδειγμα, ένα που προορίζεται για παραγωγή, μπορείτε να καθορίσετε το αρχείο χειροκίνητα χρησιμοποιώντας τη σημαία -f:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dΑυτή η προσέγγιση σας επιτρέπει να διατηρείτε ξεχωριστές ρυθμίσεις για διαφορετικά περιβάλλοντα ενώ χρησιμοποιείτε μια ενιαία συνεπή δομή εντολών.
Δομή για Τοπική Ανάπτυξη
Τα τοπικά περιβάλλοντα ανάπτυξης συνήθως απαιτούν συχνές αλλαγές, ανανέωση του κώδικα σε πραγματικό χρόνο και εκτενή καταγραφή. Το αρχείο docker-compose.override.yml καθιστά δυνατή την εισαγωγή αυτών των δυνατοτήτων χωρίς να επηρεάζονται άλλα περιβάλλοντα.
Ένα τυπικό τοπικό αρχείο υπερισχύσεων μπορεί να περιλαμβάνει:
- Σύνδεσμοι mount για ενημερώσεις κώδικα σε πραγματικό χρόνο
- Τοπικές οδηγίες κατασκευής αντί για χρήση προεκτιμημένων εικόνων
- Μεταβλητές περιβάλλοντος ειδικές για ανάπτυξη
- Υπηρεσίες αποσφαλμάτωσης και δοκιμών
Για παράδειγμα:
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- ./src:/app
- ./logs:/app/logs
environment:
- DATABASE_URL=postgres://postgres:postgres@db:5432/app_db
- LOG_LEVEL=debug
ports:
- "8000:8000"
depends_on:
- db
db:
environment:
- POSTGRES_PASSWORD=postgresΣε αυτό το παράδειγμα:
- Η υπηρεσία
appκατασκευάζεται απευθείας από ένα τοπικό Dockerfile (Dockerfile.dev), καθιστώντας εύκολο το τεστάρισμα αλλαγών χωρίς να χρειάζεται η αναδόμηση εικόνων μέσω ενός registry. - Ο πηγαίος κώδικας προσαρτάται χρησιμοποιώντας bind mounts, επιτρέποντας στο container να αντικατοπτρίζει τις αλλαγές των τοπικών αρχείων σε πραγματικό χρόνο.
- Οι μεταβλητές περιβάλλοντος όπως το
LOG_LEVEL=debugορίζονται για να παρέχουν πιο λεπτομερή έξοδο κατά την ανάπτυξη. - Η βάση δεδομένων χρησιμοποιεί απλά διαπιστευτήρια που είναι κατάλληλα για τοπικό έλεγχο αλλά δεν θα πρέπει να χρησιμοποιούνται σε παραγωγή.
Αυτή η διαμόρφωση παρέχει ένα ταχύτερο και πιο ευέλικτο περιβάλλον ανάπτυξης διατηρώντας ταυτόχρονα την βασική διαμόρφωση αμετάβλητη.
Προετοιμασία για Παραγωγή
Τα περιβάλλοντα παραγωγής απαιτούν σταθερότητα, αναπαραγωγιμότητα και ασφάλεια. Τα containers πρέπει να τρέχουν από προκατασκευασμένες εικόνες αντί να δημιουργούνται τοπικά, και οι ευαίσθητες πληροφορίες πρέπει να διαχειρίζονται με ασφάλεια. Σε αντίθεση με το αρχείο υπερισχύοντως που εφαρμόζεται αυτόματα για την τοπική ανάπτυξη, οι υπερισχύσεις παραγωγής πρέπει να καθορίζονται ρητά.
Ένα αρχείο υπερκατάστασης παραγωγής (docker-compose.prod.yml) συνήθως έχει σχεδιαστεί για να αντικαθιστά τα τοπικά βήματα κατασκευής με αναφορές εικόνων, να χρησιμοποιεί ονομασμένους τόμους αντί για συνδέσεις αρχείων και να ορίζει ιδιότητες σχετικές με την ανάπτυξη, όπως όρια πόρων και κλιμάκωση.
Παράδειγμα:
version: "3.9"
services:
app:
image: registry.example.com/myapp:1.2.3
environment:
- DATABASE_URL=${DATABASE_URL}
- LOG_LEVEL=info
volumes:
- app-data:/var/lib/app
ports:
- "8000:8000"
restart: unless-stopped
deploy:
replicas: 3
resources:
limits:
cpus: "0.5"
memory: 512M
db:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
db_password:
external: true
volumes:
app-data:
db-data:Σε αυτήν τη διαμόρφωση:
Η υπηρεσία
appαναφέρεται σε μια προ-κατασκευασμένη εικόνα (myapp:1.2.3) που αποθηκεύεται σε ένα μητρώο αντί να κατασκευάζεται τοπικά.Οι συνδεδεμένοι κατάλογοι αντικαθίστανται με ονομασμένους τόμους για να εξασφαλιστεί συνεπής και απομονωμένη αποθήκευση δεδομένων.
Τα ευαίσθητα διαπιστευτήρια αποθηκεύονται με ασφάλεια χρησιμοποιώντας τα μυστικά του Docker.
Η ενότητα
deployκαθορίζει τη συμπεριφορά κλιμάκωσης και τα όρια πόρων για καλύτερη σταθερότητα υπό φορτίο.Η διαμόρφωση πρέπει να εφαρμόζεται ρητά κατά την ανάπτυξη:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Αυτή η δομή διασφαλίζει ότι οι παραγωγικές αναπτύξεις είναι συνεπείς, ελεγχόμενες και απαλλαγμένες από τοπικά αντικείμενα ανάπτυξης.
Σύγκριση τοπικών και παραγωγικών παρακάμψεων
| Πτυχή ρύθμισης | Τοπικό (docker-compose.override.yml) | Παραγωγή (docker-compose.prod.yml) |
|---|---|---|
| Εφαρμόζεται αυτόματα | Ναι | Όχι (πρέπει να χρησιμοποιήσετε -f) |
| Διαχείριση πηγαίου κώδικα | Δεσμευμένα mounts για ζωντανές ενημερώσεις | Προκατασκευασμένες εικόνες από το μητρώο |
| Μεταβλητές περιβάλλοντος | Αξίες με επίκεντρο τον προγραμματιστή | Τιμές ασφαλείς για παραγωγή |
| Καταγραφή | Λεπτομερής (debug) | Συνοπτικό (info ή error) |
| Διαχείριση μυστικών | Απλές τιμές ή .env | Μυστικά Docker ή διαχειριζόμενα μυστικά |
| Κλιμάκωση | Μονό δοχείο | Πολλαπλά αντίγραφα |
| Βελτιστοποίηση απόδοσης | Δεν απαιτείται | Ορισμένοι περιορισμοί πόρων |
| Εργαλεία αποσφαλμάτωσης | Ενεργοποιημένο | Αναπηρία |
| Πολιτική επανεκκίνησης | Χειροκίνητο ή κανένα | |
Η χρήση πολλαπλών αρχείων Docker Compose παρέχει έναν καθαρό τρόπο να διαχωρίζονται οι ρυθμίσεις ανά περιβάλλον από τη βασική διαμόρφωση. Το βασικό docker-compose.yml ορίζει τη κοινή δομή της εφαρμογής, ενώ το docker-compose.override.yml την προσαρμόζει για την τοπική ανάπτυξη. Κατά την ανάπτυξη σε περιβάλλον παραγωγής, ένα σαφές αρχείο υπέρβασης εξασφαλίζει μια προβλέψιμη και ασφαλή διαμόρφωση.
Αυτό το πρότυπο επιτρέπει στις ομάδες να διατηρούν μια συνεπή ροή εργασίας. Οι προγραμματιστές μπορούν να ξεκινήσουν την εφαρμογή τοπικά χρησιμοποιώντας:
docker compose upκαι αναπτύξτε σε παραγωγή χρησιμοποιώντας:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dΚαι τα δύο περιβάλλοντα μοιράζονται την ίδια βασική διαμόρφωση, διατηρώντας παράλληλα ανεξάρτητες ρυθμίσεις κατάλληλες για τις συγκεκριμένες ανάγκες τους. Αυτή η διαχωριστική προσέγγιση βελτιώνει τη συντηρησιμότητα, μειώνει τα σφάλματα διαμόρφωσης και διατηρεί τα τοπικά και παραγωγικά περιβάλλοντα ευθυγραμμισμένα.
Αντιμετώπιση Προβλημάτων στο Περιβάλλον σας
Αυτό το τμήμα παρέχει βήματα αντιμετώπισης προβλημάτων για συνήθη προβλήματα που μπορεί να συναντήσετε κατά την εκτέλεση της εφαρμογής σας με το Docker Compose.
502 Κακή Πύλη (Το Nginx εμφανίζει απαντήσεις 502)
Συμπτώματα:
- Ο περιηγητής εμφανίζει 502 Bad Gateway όταν προσπαθεί να αποκτήσει πρόσβαση στο
http://localhost:8000. - Τα αρχεία καταγραφής του Nginx περιέχουν γραμμές όπως
recv() failed (111: Connection refused)ήconnect() failed (111: Connection refused) while connecting to upstream.
Πιθανές αιτίες:
- Το PHP-FPM (η υπηρεσία
app) δεν λειτουργεί ή δεν ακούει στην αναμενόμενη υποδοχή/θύρα. - Το
fastcgi_passτου Nginx δείχνει στον λάθος κεντρικό υπολογιστή/θύρα. - Ασυμφωνία ονόματος κοντέινερ ή προβλήματα δικτύου μεταξύ
nginxκαιapp. appκατέρρευσε κατά την εκκίνηση (π.χ. λόγω ελλείποντων επεκτάσεων ή σφαλμάτων διαμόρφωσης).
Πώς να επιβεβαιώσετε:
Ελέγξτε τα αρχεία καταγραφής του Nginx:
docker compose logs nginx | tail -n 100Αναζητήστε μηνύματα
502ή σφάλματα σύνδεσης upstream.Ελέγξτε την κατάσταση και τα αρχεία καταγραφής του κοντέινερ
app:docker compose ps app docker compose logs app --tail=200Επιβεβαιώστε ότι το PHP-FPM ακούει μέσα στο κοντέινερ
app:docker compose exec app ss -ltnp | grep :9000 || docker compose exec app ss -lxp | grep php-fpmΑναμένεται: είτε ένας ακροατής TCP στη θύρα
9000είτε ένα socket Unix που χρησιμοποιείται από τοnginx(λιγότερο συχνό με αυτό το compose).Επιβεβαιώστε ότι το
nginxμπορεί να επιλύσει και να φτάσει τοappστο δίκτυο του compose:docker compose exec nginx ping -c 2 app docker compose exec nginx wget -qO- --timeout=2 http://app:9000/ || trueΑν το
pingαποτύχει ή τοwgetυπερβεί το χρόνο αναμονής, υπάρχει πρόβλημα δικτύου ή ασυμφωνία στο όνομα υπηρεσίας.
Συνηθισμένες λύσεις:
Αν το PHP-FPM δεν εκτελείται, ελέγξτε τα αρχεία καταγραφής της
appγια σοβαρά σφάλματα PHP ή αποτυχίες κατά την εκκίνηση. Διορθώστε το υποκείμενο σφάλμα (συχνά λείπει επέκταση ή πρόβλημα δικαιωμάτων) και επανεκκινήστε:docker compose restart app docker compose logs app --tail=100Αν η διαμόρφωση του Nginx χρησιμοποιεί διαφορετικό upstream (π.χ.,
fastcgi_pass 127.0.0.1:9000;), ενημερώστε τοdocker-compose/nginx/travellist.confσεfastcgi_pass app:9000;(που να ταιριάζει με το όνομα της υπηρεσίας σας στο compose) και επαναφορτώστε τον Nginx:# After editing config in host docker compose exec nginx nginx -s reload docker compose logs nginx --tail=50Αν το PHP-FPM ακούει σε ένα Unix socket (π.χ.,
/run/php/php7.4-fpm.sock) αλλά το Nginx περιμένει TCP ή το αντίθετο, τυποποιήστε σε TCPapp:9000για ρυθμίσεις Compose ή προσαρμόστε σωστά το socket μεταξύ των containers (συνιστάται: χρησιμοποιήστε TCP σε multi-container Compose).
Λείπουν επεκτάσεις PHP (σφάλματα κατά την εκτέλεση του Composer ή του Artisan, ή σφάλματα κατά την εκτέλεση)
Συμπτώματα:
- Οι εντολές του Composer ή του Laravel αποτυγχάνουν με μηνύματα όπως
Class "PDO" not found,ext-pdo is missingήCall to undefined function json_encode. - Σφάλματα PHP στα αρχεία καταγραφής του
appπου αναφέρονται σε μη ορισμένες κλάσεις ή συναρτήσεις.
Πώς να επιβεβαιώσετε:
Ελέγξτε τη λίστα των μονάδων PHP του κοντέινερ
app:docker compose exec app php -m | sortΑναζητήστε τα ονόματα επεκτάσεων που χρειάζεστε (για τις τυπικές επεκτάσεις του Laravel:
pdo_mysql,mbstring,bcmath,openssl,tokenizer,xml,ctype,json,gd).Ελέγξτε το κείμενο σφάλματος του Composer, το οποίο συνήθως αναφέρει τις απαιτούμενες επεκτάσεις:
docker compose exec app composer install
Διορθώσεις:
Προσθέστε τις ελλείπουσες επεκτάσεις στο Dockerfile σας και επαναδημιουργήστε την εικόνα. Παράδειγμα (για
pdo_mysqlκαιgd):RUN apt-get update && apt-get install -y libpng-dev libxml2-dev \ && docker-php-ext-install pdo_mysql mbstring xml gdΣτη συνέχεια, κάντε ξανά κατασκευή και επανεκκίνηση:
docker compose build app docker compose up -d app docker compose logs app --tail=100Αν μια επέκταση απαιτεί συστήματα βιβλιοθηκών (για παράδειγμα η
gdχρειάζεταιlibpng-dev), προσθέστε τις αντίστοιχες γραμμέςapt-get installπριν από τοdocker-php-ext-install.Αν χρειάζεστε μια επέκταση PHP που δεν είναι ενσωματωμένη, σκεφτείτε να την εγκαταστήσετε μέσω PECL και να την ενεργοποιήσετε στο
php.ini.
Αποτυχίες σύνδεσης στη βάση δεδομένων (Το Laravel δεν μπορεί να συνδεθεί με το MySQL)
Συμπτώματα:
- Το Laravel εμφανίζει σφάλματα σύνδεσης στη βάση δεδομένων (
SQLSTATE[HY000] [2002] Connection refusedήAccess denied for user). - Οι μεταναστεύσεις αποτυγχάνουν ή η εφαρμογή εμφανίζει μια κενή σελίδα για σελίδες που βασίζονται σε δεδομένα.
Πώς να επιβεβαιώσετε:
Ελέγξτε τα αρχεία καταγραφής του κοντέινερ βάσης δεδομένων για σφάλματα αρχικοποίησης:
docker compose logs db --tail=200Ελέγξτε αν το κοντέινερ της βάσης δεδομένων λειτουργεί:
docker compose ps dbΕπιβεβαιώστε ότι οι διαπιστευτήριες πληροφορίες και ο κεντρικός υπολογιστής είναι συνεπείς μεταξύ του
.envκαι τουdocker-compose.yml. Στο Laravel.env, τοDB_HOSTθα πρέπει να είναι το όνομα της υπηρεσίας compose (db), όχι127.0.0.1ήlocalhost:DB_HOST=db DB_PORT=3306 DB_DATABASE=travellist DB_USERNAME=travellist_user DB_PASSWORD=passwordΔοκιμή από μέσα στο κοντέινερ
db:docker compose exec db mysql -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SHOW DATABASES;"Ή, κάντε δοκιμή από το κοντέινερ
appγια να βεβαιωθείτε για τη συνδεσιμότητα του δικτύου:docker compose exec app sh -c 'which mysql >/dev/null 2>&1 || echo "no mysql client"; mysql -h db -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SELECT VERSION();"'
Συχνές αιτίες και λύσεις:
Λάθος διακομιστής στο
.env: ενημερώστεDB_HOST=db, επαναδημιουργήστε τα κοντέινερ ή φορτώστε ξανά τα περιβάλλοντα:docker compose down docker compose up -d docker compose exec app php artisan migrateΗ βάση δεδομένων δεν είναι έτοιμη όταν ξεκινά η εφαρμογή: χρησιμοποιήστε έναν μηχανισμό επαναπροσπάθειας στην εφαρμογή σας ή προσθέστε έναν έλεγχο υγείας και ξεκινήστε τις παραγγελίες. Μπορείτε επίσης να περιμένετε χειροκίνητα:
docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping # expected: mysqld is aliveΗ αρχικοποίηση του SQL απέτυχε: ελέγξτε τα αρχεία κάτω από
./docker-compose/mysql, ένα σφάλμα σύνταξης ή δικαιωμάτων μπορεί να ακυρώσει την αρχικοποίηση της βάσης δεδομένων. Ελέγξτε τα αρχεία καταγραφής της βάσης για σφάλματα εισαγωγής.Δικαιώματα/λανθασμένα στοιχεία σύνδεσης: επιβεβαιώστε ότι η βάση δεδομένων και ο χρήστης υπάρχουν. Δημιουργήστε ξανά τη βάση δεδομένων ή εκτελέστε SQL για να χορηγήσετε δικαιώματα.
Χρήση θύρας σε επίπεδο υπολογιστή-φιλοξενητή: αν προσπαθήσατε
curl telnet://localhost:3306και η υπηρεσίαdbδεν εκθέτει θύρα του υπολογιστή-φιλοξενητή, αυτή η σύνδεση θα απορριφθεί από σχεδιασμό. Δοκιμάστε από μέσα στα κοντέινερ ή εκθέστε τη θύρα στοdocker-compose.yml(ports: - "3306:3306") για αποσφαλμάτωση μόνο τοπικά.
Ζητήματα δικαιωμάτων και συστήματος αρχείων (αποθήκευση, προσωρινά αρχεία, αρχεία καταγραφής)
Συμπτώματα:
- Το Laravel προκαλεί εξαιρέσεις που σχετίζονται με την εγγραφή στην cache ή στα logs:
Δεν ήταν δυνατή η ανοικτή ροή ή αρχείο "/var/www/storage/logs/laravel.log". - Τα αρχεία που δημιουργούνται από διεργασίες κοντέινερ ανήκουν στον
rootκαι δεν μπορούν να τροποποιηθούν από τον χρήστη του υπολογιστή σας.
Πώς να επιβεβαιώσετε:
Ελέγξτε τα δικαιώματα αρχείου από τον υπολογιστή φιλοξενίας:
ls -l ls -l storage bootstrap/cache docker compose exec app id -u # user id inside containerΕλέγξτε τα αρχεία καταγραφής του κοντέινερ για σφάλματα δικαιωμάτων.
Διορθώσεις:
Βεβαιωθείτε ότι το Dockerfile ορίζει τον χρήστη και το UID που αντιστοιχεί στον χρήστη του συστήματός σας (το Dockerfile σας ήδη δημιουργεί έναν χρήστη με
ARG uid). Επιβεβαιώστε ότι τοuidστα build args τουdocker-compose.ymlαντιστοιχεί στο UID του συστήματος σας (συνήθως1000).Διόρθωση ιδιοκτησίας από τον κεντρικό υπολογιστή ή μέσα στο κοντέινερ:
docker compose exec app chown -R sammy:sammy /var/www/storage /var/www/bootstrap/cacheή από τον οικοδεσπότη:
sudo chown -R $(id -u):$(id -g) storage bootstrap/cacheΓια ανάπτυξη, οι συνδέσεις bind μπορούν να προκαλέσουν ασυμφωνίες δικαιωμάτων· προτιμήστε να εκτελείτε εντολές κοντέινερ για να προσαρμόσετε την ιδιοκτησία αφού ξεκινήσετε τα κοντέινερ.
Σφάλματα που σχετίζονται με συνθέτη ή προμηθευτή
Συμπτώματα:
- Η εντολή
composer installαποτυγχάνει μέσα στον φάκελοappή ο φάκελοςvendorλείπει, με αποτέλεσμα να μην βρεθεί η κλάση. composerαναφέρει εξάντληση μνήμης στο container.
Πώς να επιβεβαιώσετε:
Τρέξτε το composer μέσα στο περιέκτη
appκαι καταγράψτε την έξοδο:docker compose exec app composer install --no-interaction --prefer-dist
Διορθώσεις:
Αν φτάσουν τα όρια μνήμης του
composer, επιτρέψτε περισσότερη μνήμη ή ορίστε μια μεταβλητή περιβάλλοντος του composer:docker compose exec app php -d memory_limit=-1 /usr/bin/composer installΒεβαιωθείτε ότι το εκτελέσιμο αρχείο του Composer είναι παρόν (το Dockerfile σας αντιγράφει τον composer). Αν όχι, επαναδημιουργήστε την εικόνα με το επίπεδο του composer.
Αν το
vendorλείπει λόγω επικάλυψης bind mount, βεβαιωθείτε ότι το bind mount σας δεν κρύβει τον φάκελοvendorπου δημιουργείται στην εικόνα. Καλύτερη πρακτική είναι να τρέξετεcomposer installαφού οι κοντέινερ είναι ενεργοποιημένοι ώστε τοvendorνα δημιουργηθεί στον προσαρτημένο φάκελο, ή να προσθέσετε τοvendorστο κοντέινερ μέσω της δημιουργίας εικόνας για την παραγωγή.
Η εφαρμογή εμφανίζει κενή σελίδα ή σφάλματα 500
Συμπτώματα:
- Ο περιηγητής εμφανίζει κενή απάντηση ή σφάλμα HTTP 500.
- Τα αρχεία καταγραφής του Nginx δείχνουν 200 αλλά η σελίδα είναι άδεια· τα αρχεία καταγραφής του
appδείχνουν κρίσιμα σφάλματα.
Πώς να επιβεβαιώσετε:
Ελέγξτε τα αρχεία καταγραφής της εφαρμογής:
docker compose exec app tail -n 200 storage/logs/laravel.log docker compose logs app --tail=200Έλεγχος περιβάλλοντος:
APP_DEBUG=trueστο.envθα κάνει το Laravel να εμφανίζει λεπτομερή σφάλματα στην ανάπτυξη (μην το ενεργοποιείτε σε παραγωγή).
Διορθώσεις:
Διόρθωσε την υποκείμενη εξαίρεση που εμφανίζεται στο
laravel.log.Βεβαιωθείτε ότι το
.envυπάρχει και ότι τοAPP_KEYέχει οριστεί:docker compose exec app php artisan key:generateΕκτέλεση μεταναστεύσεων, εκκαθάριση cache:
docker compose exec app php artisan migrate --force docker compose exec app php artisan config:cache docker compose exec app php artisan route:cache docker compose exec app php artisan view:cache
Αποτυχίες κατασκευής κοντέινερ (σφάλματα κατά τη διάρκεια του docker compose build)
Συμπτώματα:
- Το
docker compose buildαποτυγχάνει με σφάλματα στο apt ή κατά το βήμα της δημιουργίας.
Πώς να επιβεβαιώσετε:
Εκτέλεση ξανά της κατασκευής με καταγραφές:
docker compose build app
Διορθώσεις:
Διαβάστε την έξοδο του αποτυχημένου βήματος. Τυπικά προβλήματα:
- Δίκτυο/DNS στο περιβάλλον κατασκευής: επαναλάβετε ή βεβαιωθείτε ότι το Docker μπορεί να έχει πρόσβαση στο διαδίκτυο.
- Λείπουν πακέτα ή λανθασμένη πηγή apt: προσθέστε
apt-get updateπριν από τις εγκαταστάσεις και καθαρίστε τις λίστες apt μετά. - Δικαιώματα στα αρχεία που αντιγράφονται στην εικόνα: βεβαιωθείτε για τις σωστές διαδρομές
COPY.
Παράδειγμα αποσπάσματος Dockerfile για αξιόπιστες εγκαταστάσεις:
RUN apt-get update && apt-get install -y --no-install-recommends \
libpng-dev libxml2-dev zip unzip \
&& docker-php-ext-install pdo_mysql mbstring xml gd \
&& apt-get clean && rm -rf /var/lib/apt/lists/*Προβλήματα δικτύου ή DNS μεταξύ κοντέινερ
Συμπτώματα:
- Ένα κοντέινερ δεν μπορεί να φτάσει σε ένα άλλο μέσω του ονόματος υπηρεσίας (π.χ.,
appδεν μπορεί να φτάσει τοdbμεdb:3306). - Το
pingμε βάση το όνομα υπηρεσίας αποτυγχάνει.
Πώς να επιβεβαιώσετε:
docker compose exec app ping -c 3 db
docker compose exec app getent hosts db
docker network inspect travellistΔιορθώσεις:
Επιβεβαιώστε ότι οι υπηρεσίες μοιράζονται το ίδιο δίκτυο στο
docker-compose.yml(και οι δύο θα πρέπει να αναφέρονται στοtravellist).Αν αλλάξατε τα ονόματα υπηρεσιών ή δικτύων, ενημερώστε τα
DB_HOSTκαι τα upstreams του Nginx αντίστοιχα.Δημιουργήστε ξανά το δίκτυο (αυτό καταστρέφει προσωρινά κοντέινερ, οπότε προσοχή):
docker compose down docker network prune # optional and destructive docker compose up -d
Χρήσιμες εντολές διάγνωσης
Τρέξτε αυτά για στοχευμένη επιθεώρηση:
Εμφάνιση τρεχόντων κοντέινερ και θυρών:
docker compose psΚαταγραφή τερματισμού για μια υπηρεσία:
docker compose logs -f --tail=200 nginxΕκτέλεση κελύφους μέσα σε ένα κοντέινερ:
docker compose exec app sh docker compose exec db bashΕλέγξτε τις μεταβλητές περιβάλλοντος του κοντέινερ:
docker compose exec app env | sort docker compose exec db env | grep MYSQLΕλέγξτε τη λίστα διαδικασιών του κοντέινερ:
docker compose exec app ps aux docker compose exec app ss -ltnpΈλεγχος της κατάστασης του MySQL:
docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping
Πότε να εκθέσετε τις θύρες του κεντρικού υπολογιστή για αποσφαλμάτωση
Από προεπιλογή, η υπηρεσία db σε αυτή τη ρύθμιση δεν είναι δεσμευμένη σε θύρες του υπολογιστή. Ανοίξτε θύρες μόνο για τοπικό εντοπισμό σφαλμάτων. Για προσωρινή έκθεση του MySQL στον υπολογιστή, προσθέστε στο docker-compose.yml κάτω από db:
ports:
- "3306:3306"Στη συνέχεια, επανεκκινήστε:
docker compose up -d dbΑφού ολοκληρωθεί ο εντοπισμός σφαλμάτων, αφαιρέστε τον χάρτη ports για να αποφύγετε την έκθεση της βάσης δεδομένων στο δίκτυο.
Συχνές Ερωτήσεις
1. Χρειάζεται να είναι εγκατεστημένο το Composer στον υπολογιστή φιλοξενίας;
Όχι. Μπορείτε να εκτελέσετε το Composer εντελώς μέσα στο container της εφαρμογής, κάτι που είναι η συνιστώμενη προσέγγιση για αυτή τη ροή εργασίας στο Compose. Το Dockerfile στο σεμινάριο περιλαμβάνει το Composer, οπότε εκτελέστε εντολές όπως docker compose exec app composer install ή docker compose run --rm app composer require vendor/package. Η εκτέλεση του Composer μέσα στο container διασφαλίζει ότι χρησιμοποιείται η σωστή έκδοση PHP και οι σωστές επεκτάσεις και αποφεύγει την παραγωγή αρχείων vendor με ακατάλληλη ιδιοκτησία στον host.
2. Μπορώ να τρέξω τις μεταναστεύσεις του Laravel από μέσα στο container;
Ναι. Εκτελέστε τις μεταναστεύσεις από το κοντέινερ της εφαρμογής ώστε να χρησιμοποιούν το ίδιο runtime και δίκτυο με την εφαρμογή σας: docker compose exec app php artisan migrate. Για εργασίες μίας φοράς ή CI μπορείτε να χρησιμοποιήσετε docker compose run --rm app php artisan migrate --force. Πριν εκτελέσετε τις μεταναστεύσεις, βεβαιωθείτε ότι το κοντέινερ της βάσης δεδομένων είναι υγιές και δέχεται συνδέσεις, για παράδειγμα με docker compose exec db mysqladmin -u$ {DB_USERNAME} -p$ {DB_PASSWORD} ping ή προσπαθώντας ξανά μέχρι να απαντήσει.
3. Πώς μπορώ να εγκαταστήσω επιπλέον επεκτάσεις PHP;
Προσθέστε τα απαραίτητα πακέτα συστήματος και εντολές επέκτασης στο Dockerfile, και στη συνέχεια ξαναδημιουργήστε την εικόνα. Για παράδειγμα, εγκαταστήστε τις εξαρτήσεις και δημιουργήστε κοινές επεκτάσεις με κάτι σαν:
RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev \
&& docker-php-ext-configure gd --with-jpeg \
&& docker-php-ext-install pdo_mysql mbstring gdΑν χρειάζεστε μια επέκταση PECL, χρησιμοποιήστε pecl install και docker-php-ext-enable. Αφού επεξεργαστείτε το Dockerfile, εκτελέστε docker compose build app και στη συνέχεια docker compose up -d app για να εφαρμοστούν οι αλλαγές.
4. Πώς μπορώ να εκθέσω το container του Nginx για HTTPS;
Προσθέστε ένα μπλοκ διακομιστή HTTPS στη διαμόρφωση του Nginx, τοποθετήστε το πιστοποιητικό και το κλειδί σας στο container και δημοσιεύστε τη θύρα 443 στο docker-compose. Ακολουθεί ένα παράδειγμα με ελάχιστες αλλαγές στο docker-compose.yml:
services:
nginx:
ports:
- "8000:80"
- "443:443"
volumes:
- ./docker-compose/nginx:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs:roΣτη συνέχεια, προσθέστε ένα μπλοκ διακομιστή SSL που αναφέρεται σε /etc/nginx/certs/fullchain.pem και /etc/nginx/certs/privkey.pem. Για παραγωγή, χρησιμοποιήστε έναν αντίστροφο διακομιστή μεσολάβησης ή διαχειριστή πιστοποιητικών όπως το Traefik ή έναν εξωτερικό φορτωτή ισορροπίας για να αποκτήσετε και να ανανεώσετε τα πιστοποιητικά με ασφάλεια αντί να αποθηκεύετε ιδιωτικά κλειδιά στο στοίβαγμα της εφαρμογής.
5. Πώς μπορώ να αναδημιουργήσω το Laravel μετά από αλλαγές στον κώδικα;
Εξαρτάται από το τι άλλαξε. Αν χρησιμοποιείτε bind mounts για τον κατάλογο του έργου, οι αλλαγές σε PHP, πρότυπα, διαδρομές και ελεγκτές αντικατοπτρίζονται αμέσως· εκτελέστε εκκαθαρίσεις cache του Laravel αν χρειάζεται, για παράδειγμα:
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear
docker compose exec app php artisan view:clearΕάν αλλάξατε τις εξαρτήσεις του Composer ή το Dockerfile (νέα extensions ή πακέτα συστήματος), επανεγκαταστήστε ή δημιουργήστε ξανά: docker compose exec app composer install για αλλαγές στις εξαρτήσεις, και docker compose build app && docker compose up -d για αλλαγές στο Dockerfile. Επανεκκινήστε την επηρεαζόμενη υπηρεσία όταν αλλάξετε τη διαμόρφωση PHP-FPM ή Nginx: docker compose restart app ή docker compose restart nginx.
Συμπέρασμα
Σε αυτόν τον οδηγό, δημιουργήσαμε ένα περιβάλλον Docker με τρία κοντέινερ χρησιμοποιώντας το Docker Compose για να ορίσουμε την υποδομή μας σε ένα αρχείο YAML.
Από αυτό το σημείο και μετά, μπορείτε να εργαστείτε στην εφαρμογή σας Laravel χωρίς να χρειάζεται να εγκαταστήσετε και να ρυθμίσετε έναν τοπικό διακομιστή ιστού για ανάπτυξη και δοκιμές. Επιπλέον, θα εργάζεστε σε ένα προσωρινό περιβάλλον που μπορεί να αναπαραχθεί και να διανεμηθεί εύκολα, το οποίο μπορεί να είναι χρήσιμο κατά την ανάπτυξη της εφαρμογής σας αλλά και κατά τη μετάβαση σε περιβάλλον παραγωγής.
Για περισσότερα σεμινάρια Laravel, δείτε τα παρακάτω άρθρα:
- Φιλοξενήστε την εφαρμογή Laravel σας στο Linux-Console.net
- Πώς να Εγκαταστήσετε και να Διαμορφώσετε το Laravel με Nginx σε Ubuntu (Στοίβα LEMP)
- Πώς να Δημιουργήσετε Πόρους API του Laravel Eloquent για να Μετατρέψετε Μοντέλα σε JSON
- Πώς να Ξεκινήσετε Μία Νέα Εφαρμογή Laravel με Docker Compose
Ευχαριστούμε που μάθατε με την Κοινότητα Linux-Console.net.

