Weboldal keresés

Hogyan telepítsük és állítsuk be a Laravelt Docker Compose-szal Ubuntu 22.04 rendszeren


Bevezetés

Az alkalmazás konténerizálása az az eljárás, amikor egy alkalmazást és annak összetevőit úgy alakítják át, hogy azokat könnyűsúlyú környezetekben, az úgynevezett konténerekben lehessen futtatni. Az ilyen környezetek izoláltak és eldobhatók, és felhasználhatók alkalmazások fejlesztésére, tesztelésére és éles környezetbe való telepítésére.

Ebben az útmutatóban a Docker Compose-t használjuk egy Laravel alkalmazás konténerizálására fejlesztési célokra. A folyamat végére egy demó Laravel alkalmazás fog futni három különálló szolgáltatáskonténerben:

  • Egy app szolgáltatás PHP7.4-FPM futtatásával;
  • Egy db szolgáltatás, amely MySQL 8.0-t futtat;
  • Egy nginx szolgáltatás, amely a app szolgáltatást használja a PHP-kód feldolgozására, mielőtt a Laravel alkalmazást a végfelhasználónak szolgálná ki.

A gördülékeny fejlesztési folyamat érdekében és az alkalmazás hibakeresésének megkönnyítésére az alkalmazás fájljait megosztott kötetek használatával szinkronban tartjuk. Megnézzük azt is, hogyan lehet a docker compose exec parancsokat használni a Composer és az Artisan futtatásához az app konténerben.

Telepítse frontend alkalmazásait a GitHubról a Linux-Console.net Alkalmazásplatform segítségével. Hagyd, hogy a Linux-Console.net az alkalmazásod skálázására koncentráljon.

Főbb tanulságok:

  • A konténerizáció kiszámíthatóvá teszi a fejlesztést: A Laravel Dockerben történő futtatása biztosítja az egységes környezetet a különböző gépeken, megszüntetve a „nálam működik” problémákat, és megkönnyítve az együttműködést.
  • A szolgáltatások szétválasztása javítja a karbantarthatóságot: A PHP, MySQL és Nginx külön konténerekbe történő szétválasztása segít a problémák elkülönítésében, egyszerűsíti a frissítéseket, és tükrözi a valós termelési környezeteket.
  • A környezeti változók központi szerepet játszanak a rugalmas konfigurációban: A .env fájl használatával a fejlesztők anélkül módosíthatják az adatbázis-hitelesítő adatokat és egyéb beállításokat, hogy az alkalmazáskódhoz kellene nyúlniuk.
  • Egyedi Docker-képek növelik az irányítást és a biztonságot: Saját PHP-kép készítése biztosítja, hogy csak azt telepítse, amire a projektjének szüksége van, így a környezet könnyű és biztonságos marad.
  • A fájlengedélyeknek meg kell egyezniük a konténer felhasználóival: A Laravel írható könyvtárainak megfelelő tulajdonjogának és engedélyeinek beállítása megakadályozza a futásidejű hibákat, és elősegíti a zökkenőmentes helyi fejlesztést.
  • Az override fájlok használata több környezetet támogat: a docker-compose.override.yml lehetővé teszi a helyi módosításokat—például az élő újratöltést—anélkül, hogy a termelési konfigurációkat megváltoztatnánk. Ez tisztán elkülöníti a fejlesztést a telepítéstől.
  • A hibaelhárítás a konténer viselkedésének megértésével kezdődik: A naplók ellenőrzésének, a futó szolgáltatások vizsgálatának és a kapcsolódás tesztelésének ismerete kulcsfontosságú a legtöbb probléma gyors megoldásához a konténerizált környezetekben.
  • A Docker-alapú rendszer a munkafolyamatodhoz igazodik: Miután felépült, ugyanaz a konfiguráció képes működtetni a helyi, teszt- vagy éles környezeteket, stabil és újrahasználható alapot teremtve a jövőbeli Laravel-projektekhez.

Előfeltételek

  • Hozzáférés egy Ubuntu helyi géphez vagy fejlesztői szerverhez nem root felhasználóként, sudo jogosultságokkal. Ha távoli szervert használ, ajánlott aktív tűzfal telepítése. Ezek beállításához kérjük, olvassa el az Ubuntu kezdeti szerverbeállítási útmutatónkat.
  • A Docker telepítve van a szerverére, az Ubuntu Docker telepítéséről és használatáról szóló útmutató 1. és 2. lépését követve.
  • A Docker Compose telepítve van a szerverére, az Ubuntu rendszeren történő Docker Compose telepítéséről és használatáról szóló 1. lépés követésével.

1. lépés — A demóalkalmazás beszerzése

A kezdéshez le fogjuk tölteni a demó Laravel alkalmazást a Github tárolójából. A tutorial-01 ágra vagyunk kíváncsiak, amely tartalmazza az alap Laravel alkalmazást, amelyet a Hogyan telepítsük és konfiguráljuk a Laravel-t Nginx-szel Ubuntu 22.04 (LEMP) alatt útmutatóban hoztunk létre.

Ahhoz, hogy megszerezze a tutorialhoz kompatibilis alkalmazáskódot, töltse le a tutorial-1.0.1 kiadást a kezdőkönyvtárába a következő módon:

cd ~

curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip

Az alkalmazáskód kicsomagolásához szükségünk lesz az unzip parancsra. Ha még nem telepítetted ezt a csomagot, tedd meg most a következővel:

sudo apt update

sudo apt install unzip

Most csomagold ki az alkalmazás tartalmát, és nevezd át a kicsomagolt könyvtárat a könnyebb hozzáférés érdekében:

unzip travellist.zip

mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

Navigálj a travellist-demo könyvtárba:

cd travellist-demo

A következő lépésben létrehozunk egy .env konfigurációs fájlt az alkalmazás beállításához.

2. lépés — Az alkalmazás .env fájljának beállítása

A Laravel konfigurációs fájlok az alkalmazás gyökérkönyvtárában található config nevű könyvtárban vannak. Ezen kívül a .env fájl használatos a környezettől függő konfiguráció beállítására, például hitelesítési adatok vagy bármilyen információ, amely a telepítések között eltérhet. Ez a fájl nincs verziókezelésbe véve.

Figyelmeztetés: A környezetbeállítási fájl érzékeny információkat tartalmaz a szerveréről, beleértve az adatbázis-hitelesítő adatokat és a biztonsági kulcsokat. Emiatt soha ne ossza meg nyilvánosan ezt a fájlt.

A .env fájlban található értékek előnyt élveznek a config könyvtárban található normál konfigurációs fájlokban beállított értékekhez képest. Minden új környezetre történő telepítéshez szükség van egy testreszabott környezeti fájlra, amely meghatározza például az adatbázis-kapcsolati beállításokat, a hibakeresési opciókat, az alkalmazás URL-jét, valamint más, az adott környezettől függően változó elemeket.

Most létrehozunk egy új .env fájlt, hogy testre szabhassuk a fejlesztői környezet beállítási lehetőségeit, amelyet éppen létrehozunk. A Laravel egy példafájlt (.env) tartalmaz, amit lemásolhatunk, hogy a sajátunkat elkészítsük:

cp .env.example .env

Nyisd meg ezt a fájlt a nano segítségével, vagy a választott szövegszerkesztőddel:

nano .env

A jelenlegi .env fájl a travellist demóalkalmazásból olyan beállításokat tartalmaz, amelyek egy helyi MySQL adatbázis használatára irányulnak, 127.0.0.1 mint adatbázis hoszt. Frissítenünk kell a DB_HOST változót, hogy az a Docker környezetünkben létrehozandó adatbázis szolgáltatásra mutasson. Ebben az útmutatóban az adatbázis szolgáltatásunkat db-nek fogjuk hívni. Cseréld le a DB_HOST felsorolt értékét az adatbázis szolgáltatás nevére:

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
...

Nyugodtan változtathatod az adatbázis nevét, a felhasználónevet és a jelszót is, ha szeretnéd. Ezeket a változókat a későbbi lépésben fogjuk felhasználni, amikor beállítjuk a docker-compose.yml fájlt a szolgáltatásaink konfigurálásához.

Mentse el a fájlt, amikor befejezte a szerkesztést. Ha a nano-t használta, ezt úgy teheti meg, hogy megnyomja a Ctrl+x-et, majd a Y-t és az Enter-t a megerősítéshez.

3. lépés – Az alkalmazás Dockerfile-jának beállítása

Bár a MySQL és az Nginx szolgáltatásaink is az alapértelmezett, a Docker Hubról származó képeken alapulnak, még mindig szükségünk van egy egyedi kép felépítésére az alkalmazás konténeréhez. Ehhez létrehozunk egy új Dockerfile-t.

A travellist képünk a Docker Hub php:7.4-fpm hivatalos PHP képére fog épülni. Ezen az alap PHP-FPM környezeten felül néhány extra PHP modult és a Composer függőségkezelő eszközt fogjuk telepíteni.

Létrehozunk egy új rendszerfelhasználót is; erre szükség van az artisan és a composer parancsok futtatásához az alkalmazás fejlesztése közben. A uid beállítás biztosítja, hogy a konténeren belüli felhasználó ugyanazzal a uid-val rendelkezzen, mint a rendszerfelhasználód a host gépeden, ahol a Dockert futtatod. Így ezekkel a parancsokkal létrehozott fájlok a helyes jogosultságokkal jelennek meg a hoston is. Ez azt is jelenti, hogy a kedvenc kódszerkesztőddel a host gépen fejlesztheted az alkalmazást, amely a konténerekben fut.

Hozzon létre egy új Dockerfile-t a következővel:

nano Dockerfile

Másolja a következő tartalmat a Dockerfile-jába:

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

Ne felejtsd el menteni a fájlt, amikor kész vagy.

A Dockerfile-ünk azzal kezdődik, hogy meghatározzuk az alapképet, amit használunk: php:7.4-fpm.

A rendszercsomagok és a PHP-kiterjesztések telepítése után a Compose‑ert úgy telepítjük, hogy a legfrissebb hivatalos képből az alkalmazásunk saját képébe másoljuk a composer futtatható fájlt.

Ezután egy új rendszergazda felhasználó jön létre és kerül beállításra a Dockerfile elején megadott user és uid argumentumok használatával. Ezeket az értékeket a Docker Compose a build idő során injektálja.

Végül beállítjuk az alapértelmezett munkakönyvtárat /var/www-ra, és átváltunk az újonnan létrehozott felhasználóra. Ez biztosítja, hogy normál felhasználóként csatlakozol, és a megfelelő könyvtárban vagy, amikor a composer és a artisan parancsokat futtatod az alkalmazás konténerben.

4. lépés — Nginx konfiguráció és adatbázis mentési fájlok beállítása

Amikor fejlesztői környezeteket hozunk létre Docker Compose segítségével, gyakran szükséges a konfigurációs vagy inicializációs fájlok megosztása a szolgáltatáskonténerekkel annak érdekében, hogy beállítsuk vagy elindítsuk ezeket a szolgáltatásokat. Ez a gyakorlat lehetővé teszi a konfigurációs fájlok módosítását, hogy finomhangoljuk a környezetet a fejlesztés során.

Most létrehozunk egy mappát a fájlokkal, amelyeket a szolgáltatás konténereink konfigurálásához és inicializálásához fogunk használni.

Az Nginx beállításához megosztunk egy travellist.conf fájlt, amely konfigurálja az alkalmazás kiszolgálását. Hozd létre a docker-compose/nginx mappát a következővel:

mkdir -p docker-compose/nginx

Nyiss meg egy új fájlt travellist.conf néven abban a könyvtárban:

nano docker-compose/nginx/travellist.conf

Másolja az alábbi Nginx konfigurációt abba a fájlba:

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;
    }
}

Ez a fájl úgy konfigurálja az Nginx-et, hogy a 80-as porton figyeljen, és az alapértelmezett indexoldalként a index.php-t használja. A dokumentumgyökér a /var/www/public lesz beállítva, majd az Nginx-et úgy konfigurálja, hogy a app szolgáltatást a 9000-es porton használja a *.php fájlok feldolgozására.

Mentsd el a fájlt, és zárd be, amikor befejezted a szerkesztést.

A MySQL adatbázis beállításához megosztunk egy adatbázis-dumpot, amelyet a konténer inicializálásakor importálnak. Ez egy olyan funkció, amelyet a MySQL 8.0 képfájljával biztosítunk, amelyet a konténeren használni fogunk.

Hozz létre egy új mappát a MySQL inicializációs fájljaidnak a docker-compose mappán belül:

mkdir docker-compose/mysql

Nyiss meg egy új .sql fájlt:

nano docker-compose/mysql/init_db.sql

A következő MySQL dump az adatbázison alapul, amelyet a Laravel LEMP útmutatónkban hoztunk létre. Ez egy új, places nevű táblát fog létrehozni. Ezután feltölti a táblát néhány mintavárossal.

Add hozzá a következő kódot a fájlhoz:

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);

A places tábla három mezőt tartalmaz: id, name és visited. A visited mező egy jelző, amely arra szolgál, hogy azonosítsa azokat a helyeket, amelyeket még el kell látogatni. Nyugodtan változtathatod a mintában szereplő helyeket, vagy adhatsz hozzá újakat. Mentés után zárd be a fájlt.

Befejeztük az alkalmazás Dockerfile-jának és a szolgáltatás konfigurációs fájljainak beállítását. Ezután a Docker Compose-t fogjuk beállítani, hogy ezeket a fájlokat használja a szolgáltatásaink létrehozásakor.

5. lépés — Többkonténeres környezet létrehozása Docker Compose-szal

A Docker Compose lehetővé teszi több konténerből álló környezetek létrehozását Dockeren futó alkalmazások számára. Szolgáltatásdefiníciókat használ a teljesen testreszabható környezetek építéséhez, amelyek több konténert foglalnak magukban, és oszthatnak hálózatokat és adatvolumeneket. Ez zökkenőmentes integrációt tesz lehetővé az alkalmazás komponensei között.

A szolgáltatásaink definiálásához létrehozunk egy új fájlt docker-compose.yml néven. Ez a fájl általában az alkalmazás mappájának gyökérkönyvtárában található, és meghatározza a konténerizált környezetet, beleértve azokat az alapképeket, amelyeket a konténerek létrehozásához használunk, valamint azt, hogy a szolgáltatásaink hogyan fognak kölcsönhatásba lépni egymással.

Három különböző szolgáltatást fogunk meghatározni a docker-compose.yml fájlunkban: app, db és nginx.

Az app szolgáltatás egy travellist nevű képet fog készíteni, a korábban létrehozott Dockerfile alapján. Ez a szolgáltatás által definiált konténer egy php-fpm szervert futtat, amely PHP kódot dolgoz fel, és az eredményeket visszaküldi az nginx szolgáltatásnak, amely egy külön konténeren fog futni. A mysql szolgáltatás egy MySQL 8.0 szervert futtató konténert határoz meg. Szolgáltatásaink megosztanak egy travellist nevű híd hálózatot.

Az alkalmazásfájlok szinkronizálva lesznek mind az app, mind a nginx szolgáltatásokon keresztül bind mountok segítségével. A bind mountok hasznosak fejlesztői környezetekben, mert lehetővé teszik a gazdagép és a konténerek közötti teljesítményorientált kétirányú szinkronizációt.

Hozz létre egy új docker-compose.yml fájlt az alkalmazás mappájának gyökerében:

nano docker-compose.yml

Egy tipikus docker-compose.yml fájl egy verziódefinícióval kezdődik, majd következik egy services csomópont, alatta pedig az összes szolgáltatás definiálva van. A megosztott hálózatokat általában a fájl alján szokták definiálni.

A kezdéshez másold be ezt az előre elkészített kódot a docker-compose.yml fájlodba:

version: "3.9"
services:


networks:
  travellist:
    driver: bridge

Most szerkesztjük a services csomópontot, hogy tartalmazza az app, db és nginx szolgáltatásokat.

A app szolgáltatás

Az app szolgáltatás létrehoz egy travellist-app nevű konténert. Egy új Docker képet épít, amely a docker-compose.yml fájl melletti útvonalon található Dockerfile alapján készül. Az új kép helyben lesz elmentve travellist néven.

Bár a dokumentumgyökér, amelyet az alkalmazásként szolgál, az nginx konténerben található, az alkalmazás fájljaira valahol az app konténerben is szükség van, hogy képesek legyünk a Laravel Artisan eszközzel parancssori feladatokat végrehajtani.

Másold a következő szolgáltatásdefiníciót a services csomópont alá a docker-compose.yml fájlban:

  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

Ezek a beállítások a következőket végzik:

  • build: Ez a beállítás azt mondja a Docker Compose-nak, hogy építsen egy helyi képet az app szolgáltatáshoz, a megadott útvonal (context) és a Dockerfile utasításainak felhasználásával. A user és uid argumentumok be vannak injektálva a Dockerfile-ba, hogy testreszabják a felhasználó létrehozási parancsokat a build idő alatt.
  • image: Az a név, amelyet a készülő képhez fognak használni.
  • container_name: Beállítja a konténer nevét ehhez a szolgáltatáshoz.
  • restart: Mindig indítsa újra, kivéve, ha a szolgáltatás le van állítva.
  • working_dir: Beállítja ennek a szolgáltatásnak az alapértelmezett könyvtárát /var/www-re.
  • volumes: Létrehoz egy megosztott kötetet, amely a jelenlegi könyvtár tartalmát szinkronizálja a konténeren belüli /var/www könyvtárhoz. Fontos megjegyezni, hogy ez nem a dokumentumgyökér, mivel az a nginx konténerben lesz.
  • hálózatok: Beállítja ezt a szolgáltatást, hogy a travellist nevű hálózatot használja.

A db szolgáltatás

A db szolgáltatás egy előre elkészített MySQL 8.0 képet használ a Docker Hub-ról. Mivel a Docker Compose automatikusan betölti a .env változó fájlokat, amelyek ugyanabban a könyvtárban találhatók, mint a docker-compose.yml fájl, megszerezhetjük az adatbázis beállításainkat a Laravel .env fájljából, amelyet az előző lépésben hoztunk létre.

Adja hozzá a következő szolgáltatásdefiníciót a services csomópontjához, közvetlenül az app szolgáltatás után:

  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

Ezek a beállítások a következőket végzik:

  • image: Meghatározza a Docker képet, amit ehhez a konténerhez kell használni. Ebben az esetben egy MySQL 8.0 képet használunk a Docker Hub-ról.
  • container_name: Beállítja a konténer nevét ehhez a szolgáltatáshoz: travellist-db.
  • restart: Mindig indítsa újra ezt a szolgáltatást, kivéve, ha azt kifejezetten leállították.
  • environment: A környezeti változókat definiálja az új konténerben. Az értékeket a Laravel .env fájljából vesszük, hogy beállítsuk a MySQL szolgáltatásunkat, amely automatikusan létrehoz egy új adatbázist és felhasználót a megadott környezeti változók alapján.
  • volumes: Létrehoz egy kötetet a .sql adatbázis dump megosztásához, amelyet az alkalmazás adatbázisának inicializálásához használnak. A MySQL kép automatikusan importálja a .sql fájlokat, amelyeket a konténer belsejében a /docker-entrypoint-initdb.d könyvtárba helyeznek.
  • networks: Beállítja ezt a szolgáltatást, hogy a travellist nevű hálózatot használja.

A nginx szolgáltatás

Az nginx szolgáltatás egy előre elkészített Nginx képet használ az Alpine, egy könnyű Linux disztribúció tetején. Létrehoz egy travellist-nginx nevű konténert, és a ports definíciót használja, hogy átirányítást hozzon létre a gazdagépen lévő 8000 port és a konténeren belüli 80 port között.

Adja hozzá a következő szolgáltatásdefiníciót a services csomópontjához, közvetlenül a db szolgáltatás után:

  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

Ezek a beállítások a következőket végzik:

  • image: Meghatározza a Docker képet, amelyet ehhez a konténerhez kell használni. Ebben az esetben az Alpine Nginx 1.17 képet használjuk.
  • container_name: Beállítja a konténer nevét ehhez a szolgáltatáshoz: travellist-nginx.
  • restart: Mindig indítsa újra ezt a szolgáltatást, kivéve, ha azt kifejezetten leállították.
  • ports: Beállít egy port-átirányítást, amely lehetővé teszi a külső hozzáférést a 8000 porton keresztül a konténeren belül a 80 porton futó webkiszolgálóhoz.
  • volumes: Két megosztott kötetet hoz létre. Az első a jelenlegi könyvtár tartalmát szinkronizálja a konténeren belüli /var/www mappába. Így, amikor helyi változtatásokat végzel az alkalmazás fájljaiban, azok gyorsan tükröződni fognak a konténerben futó Nginx által szolgáltatott alkalmazásban. A második kötet biztosítja, hogy az Nginx konfigurációs fájlunk, amely a docker-compose/nginx/travellist.conf útvonalon található, a konténer Nginx konfigurációs mappájába másolódjon.
  • hálózatok: Beállítja ezt a szolgáltatást, hogy a travellist nevű hálózatot használja.

Kész docker-compose.yml fájl

Így néz ki a kész docker-compose.yml fájlunk:

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

Győződj meg róla, hogy elmented a fájlt, amikor végzel.

6. lépés — Az alkalmazás futtatása Docker Compose-szal

Most a docker compose parancsokat fogjuk használni az alkalmazás-kép felépítésére és a beállításunkban megadott szolgáltatások futtatására.

Építsd meg az app képet a következő parancs segítségével:

docker compose build app

Ez a parancs néhány percig is eltarthat. Hasonló kimenetet fogsz látni:

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

Amikor a build befejeződött, a környezetet háttérmódban a következőképpen futtathatod:

docker compose up -d
Creating travellist-db    ... done
Creating travellist-app   ... done
Creating travellist-nginx ... done

Ez háttérben futtatja a konténereidet. Az aktív szolgáltatásaid állapotára vonatkozó információk megjelenítéséhez futtasd:

docker compose ps

Ilyen kimenetet fogsz látni:

      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

A környezeted most már működik.

Most már ellenőrizheted, hogy minden konténerizált szolgáltatás megfelelően válaszol-e egyszerű curl parancsok segítségével.

  1. Az Nginx webszerver teszteléséhez:

    curl -I http://localhost:8000

    Várt kimenet:

    HTTP/1.1 200 OK
    Server: nginx/1.17.10
    Content-Type: text/html; charset=UTF-8

    Ez megerősíti, hogy az Nginx konténer fut, és válaszokat szolgáltat a Laravel alkalmazásodból.

  2. A PHP-FPM Nginx-en keresztüli teszteléséhez:

    curl -s http://localhost:8000 | grep "Berlin"

    Ha az alkalmazás helyesen fut, ez a parancs visszaadja a kezdőlap HTML-jét, amely tartalmazza a Berlin szót.

Még mindig végre kell hajtanunk néhány parancsot az alkalmazás beállításának befejezéséhez. A docker compose exec parancsot használhatod arra, hogy parancsokat hajts végre a szolgáltatás konténereiben, például egy ls -l parancsot, amely részletes információkat mutat az alkalmazás könyvtárában található fájlokról:

docker compose exec app ls -l
total 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

Most futtatni fogjuk a composer install parancsot az alkalmazás függőségeinek telepítéséhez:

docker compose exec app rm -rf vendor composer.lock

docker compose exec app composer install

Ilyen kimenetet fogsz látni:

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.

Az utolsó dolog, amit az alkalmazás tesztelése előtt meg kell tennünk, egy egyedi alkalmazáskulcs generálása a artisan Laravel parancssori eszközzel. Ezt a kulcsot a felhasználói munkamenetek és más érzékeny adatok titkosítására használják:

docker compose exec app php artisan key:generate
Application key set successfully.

Most nyisd meg a böngésződet, és lépj a szervered domain nevére vagy IP-címére a 8000-es porton:

http://server_domain_or_IP:8000

Megjegyzés: Ha ezt a demót a saját gépén futtatja, használja a http://localhost:8000 címet az alkalmazás böngészőből történő eléréséhez.

Ilyen oldalt fogsz látni:

A Laravel alkalmazást a böngésző használata nélkül az app konténeren belül is tesztelheti:

docker compose exec app curl http://nginx

Ha minden helyesen van beállítva, látnod kell a Laravel alapértelmezett üdvözlőoldalának HTML-kimenetét.

<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>

A logs parancsot használhatod a szolgáltatásaid által generált naplók ellenőrzésére:

docker compose logs nginx
Attaching 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"

A következő curl parancsot is használhatod a naplóbejegyzések létrehozásához:

curl http://localhost:8000

Ezután futtasd újra:

docker compose logs nginx

Most már látnia kell egy megfelelő hozzáférési naplóbejegyzést a kéréséhez.

Ha szüneteltetni szeretnéd a Docker Compose környezetedet úgy, hogy megőrizd az összes szolgáltatás állapotát, futtasd a következőt:

docker compose pause
Pausing travellist-db    ... done
Pausing travellist-nginx ... done
Pausing travellist-app   ... done

Ezután folytathatja a szolgáltatásait a következővel:

docker compose unpause
Unpausing travellist-app   ... done
Unpausing travellist-nginx ... done
Unpausing travellist-db    ... done

A Docker Compose környezet leállításához és az összes konténer, hálózat és kötet eltávolításához futtasd a következőt:

docker compose down
Stopping 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

Az összes Docker Compose parancs áttekintéséhez kérjük, tekintse meg a Docker Compose parancssori referencia dokumentációját.

Laravel fájl- és könyvtárengedélyek javítása

Amikor a Laravelt Docker konténerekben futtatjuk, az egyik leggyakoribb probléma, amivel a fejlesztők szembesülnek, a fájl- és könyvtárjogosultságokkal kapcsolatos. A Laravelnek szüksége van bizonyos könyvtárak írási jogosultságára a PHP-FPM folyamat számára az app konténerben. Ha ezek a könyvtárak nem írhatók, az alkalmazás nem tudja helyesen naplózni a hibákat, gyorsítótárazni a konfigurációs fájlokat, vagy tárolni a munkamenet adatait.

Olyan üzenetekbe ütközhetsz, mint például:

The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission denied

vagy

file_put_contents(/var/www/bootstrap/cache/config.php): Failed to open stream: Permission denied

Ezek a hibák azt jelzik, hogy a konténeren belül PHP-t futtató felhasználónak nincs joga az adott könyvtárakba írni.

A következő lépések leírják, hogyan lehet diagnosztizálni és megoldani ezeket a problémákat mind a helyi, mind a éles környezetben.

Írható könyvtár jogosultságainak beállítása

A Laravel megköveteli, hogy két könyvtár írható legyen a webkiszolgáló felhasználója számára:

  • /var/www/storage
  • /var/www/bootstrap/cache

Ha jogosultsági hibákat lát, azokat a tulajdonjogok és engedélyek a konténeren belüli beállításával javíthatja:

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

Ha a Dockerfile-ja más felhasználónevet használ (amelyet a user build argumentumon keresztül határoz meg), cserélje ki a sammy-t arra a felhasználónévre.

A tulajdonjogot a következő parancs kiadásával ellenőrizheti:

docker compose exec app ls -ld /var/www/storage /var/www/bootstrap/cache

A kimenetnek meg kell mutatnia, hogy a felhasználó és a csoport megegyezik a PHP-FPM folyamattal a konténeren belül.

Ha inkább a host gépről szeretnéd módosítani a jogosultságokat, futtasd a következőt:

sudo chown -R $(id -u):$(id -g) storage bootstrap/cache

sudo chmod -R 775 storage bootstrap/cache

Ez biztosítja, hogy mindkét Laravel könyvtár írható legyen a konténer és a hosztfelhasználó számára is.

Állítsa be a könyvtár tulajdonjogát a kép építése során

A jogosultsági problémák ismétlődésének megelőzése érdekében minden újraépítés után beállíthatja a könyvtár tulajdonjogát a Docker-kép építése során. Nyissa meg a Dockerfile-t, és adja hozzá a következő sort a vég közelében, még mielőtt a nem root felhasználóra váltana:

RUN chown -R $user:www-data /var/www

Ez a parancs biztosítja, hogy az összes /var/www alatti fájl és könyvtár a Dockerfile-ban megadott felhasználó tulajdonában legyen.

Egy célzottabb és biztonságosabb megközelítés érdekében csak azokat a könyvtárakat módosíthatja, amelyekhez a Laravelnek írási jogosultsága van:

RUN chown -R $user:www-data /var/www/storage /var/www/bootstrap/cache

Miután elvégezte ezt a módosítást, építse újra a képet és indítsa újra a konténereket:

docker compose build app

docker compose up -d

Amikor a konténer legközelebb elindul, már a megfelelő jogosultságokkal fog rendelkezni.

Ellenőrizze a felhasználói azonosító megfelelőségét a gazdagép és a konténer között

A bind mountok használatakor a Docker fájlokat oszt meg a gazdagép és a konténer között. Ha a gazdagépen lévő felhasználó numerikus UID-je eltér a konténerben megadott UID-től, fájlhozzáférési konfliktusok léphetnek fel. Ez gyakori olyan rendszereken, ahol a felhasználói azonosítók gépenként különböznek.

A UID értékek ellenőrzéséhez futtassa a következőt:

id -u $(whoami)

docker compose exec app id -u

Ha ezek a két szám nem egyezik, frissítse a docker-compose.yml fájlt, hogy a tényleges UID-jét adja át a build folyamatnak:

build:
  args:
    user: sammy
    uid: 1000

Ezután építsd újra a képet:

docker compose build app

docker compose up -d

Ez biztosítja, hogy a konténer felhasználója megegyezzen a gazdagép felhasználójával, megakadályozva a jogosultsági eltéréseket a bind-mounted fájlokon.

Javítsa a Composer gyorsítótár könyvtárának jogosultságait

A Composer a letöltött függőségeket és gyorsítótár fájlokat a felhasználó otthoni könyvtárában tárolja a konténerben (/home/sammy/.composer). Ha ez a könyvtár nem írható, a következőhöz hasonló figyelmeztetéseket láthat:

Cannot create cache directory /home/sammy/.composer/cache

Ezt úgy javíthatja, hogy létrehozza a gyorsítótár könyvtárat, és beállítja a megfelelő tulajdonost:

docker compose exec app mkdir -p /home/sammy/.composer/cache

docker compose exec app chown -R sammy:sammy /home/sammy/.composer

Ez biztosítja, hogy a Composer tárolni tudja a függőségeket és a gyorsítótár fájlokat jogosultsági hibák nélkül, ami a jövőbeli composer install futtatásokat is felgyorsítja.

Ajánlott gyakorlatok éles környezetekhez

A termelés során a jogosultságkezelést az image létrehozásakor kell kezelni, nem futásidőben. Ez növeli a következetességet és a biztonságot.

Kövesse ezeket a gyakorlatokat a termelésre kész konfigurációhoz:

  • Kerüljük az alkalmazáskódhoz használt bind mountokat: Ehelyett másoljuk az alkalmazás fájljait a képbe a build során. A bind mountokat csak fejlesztéshez szabad használni.

  • Engedélyek beállítása a build során: Add hozzá a RUN chown és chmod parancsokat a Dockerfile-odhoz, hogy a telepítés előtt biztosítsd a megfelelő tulajdonjogokat és hozzáférési jogosultságokat.

  • Használja a legkevesebb jogosultsággal rendelkező felhasználót: Győződjön meg róla, hogy a PHP folyamat nem root felhasználó alatt fut (a jelenlegi beállítás $user már ezt biztosítja).

  • Korlátozza az engedélyeket a nem írható könyvtárakon: A legtöbb alkalmazásfájlnak csak olvashatónak kell lennie. Ezt a következőképpen lehet érvényesíteni:

    chmod -R 755 /var/www
    
    chmod -R 775 /var/www/storage /var/www/bootstrap/cache

    Ez a beállítás lehetővé teszi, hogy a Laravel csak ott írjon, ahol szükséges, miközben védi a többi alkalmazásfájlt a módosítástól.

Ezeknek a lépéseknek a követésével a Laravel konténereid stabil, kiszámítható fájlengedélyekkel rendelkeznek mind a helyi, mind a produkciós környezetben. Ez csökkenti az ismétlődő hibákat, és biztosítja, hogy a Laravel megbízhatóan tudjon adatokat naplózni, fájlokat gyorsítótárazni és sessionöket írni.

A docker-compose.override.yml megértése helyi és éles környezetekhez

A Docker Compose lehetővé teszi, hogy többkonténeres alkalmazásokat definiálj egyetlen konfigurációs fájl segítségével. A legtöbb esetben ez a konfiguráció egy docker-compose.yml nevű fájlban van tárolva. Azonban a különböző környezetek, például a helyi fejlesztés és a termelési környezet kezelése gyakran környezet specifikus módosításokat igényel. Itt válik hasznossá a docker-compose.override.yml fájl.

Alapértelmezés szerint a Docker Compose automatikusan keresi a docker-compose.override.yml nevű fájlt ugyanabban a könyvtárban, mint az alap Compose fájl. Ha megtalálja, a két fájl konfigurációit összefésüli, amikor bármely docker compose parancsot futtat. Ez a megközelítés lehetővé teszi a fejlesztők számára, hogy tiszta, újrahasználható alapkonfigurációt tartsanak fenn, miközben a beállítás bizonyos aspektusait testre szabhatják helyi vagy éles használatra.

docker-compose.override.yml szerepe

A docker-compose.override.yml fájl a alapértelmezett Compose konfiguráció kiterjesztése. Olyan tulajdonságokat módosít vagy ad hozzá, amelyek csak egy adott környezetre vonatkoznak, anélkül hogy a fő docker-compose.yml fájlban változtatni kellene. Az override fájl különösen hasznos a helyi fejlesztési munkafolyamatokban, ahol a fejlesztők gyakran szükségét érzik a forráskód csatolásának, hibakereső eszközök engedélyezésének vagy a környezeti változók tesztelés céljából történő módosításának.

Amikor futtatja a docker compose up parancsot, a Docker automatikusan egyesíti a docker-compose.yml és a docker-compose.override.yml fájlok tartalmát. Ha egy szolgáltatás, kötet vagy konfiguráció mindkét fájlban definiálva van, az override fájlban szereplő értékek felülbírálják a másikat.

Ha egy másik felülíró fájlt szeretne használni, például egyet, amely a éles környezethez készült, manuálisan is megadhatja a fájlt a -f kapcsolóval:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Ez a megközelítés lehetővé teszi, hogy különböző környezetekhez külön konfigurációkat tarts fenn, miközben egyetlen következetes parancsszerkezetet használsz.

Helyi Fejlesztés Szervezése

A helyi fejlesztői környezetek általában gyakori változtatásokat, élő kód újratöltést és részletes naplózást igényelnek. A docker-compose.override.yml fájl lehetővé teszi ezeknek a funkcióknak a bevezetését anélkül, hogy a többi környezetet befolyásolná.

Egy tipikus helyi felülíró fájl tartalmazhatja a következőket:

  • Bind csatolások élő kódfrissítésekhez
  • Helyi build irányelvek előre elkészített képek használata helyett
  • Fejlesztéshez kapcsolódó környezeti változók
  • Hibakeresési és tesztelési szolgáltatások

Például:

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

Ebben a példában:

  • A app szolgáltatás közvetlenül egy helyi Dockerfile-ból (Dockerfile.dev) épül, ami megkönnyíti a változtatások tesztelését anélkül, hogy a képfájlokat a regiszteren keresztül kellene újraépíteni.
  • A forráskód bind mountok segítségével van csatolva, így a konténer valós időben tükrözi a helyi fájlok változásait.
  • A LOG_LEVEL=debug jellegű környezeti változókat úgy állítják be, hogy a fejlesztés során részletesebb kimenetet biztosítsanak.
  • Az adatbázis egyszerű hitelesítő adatokat használ, amelyek megfelelőek a helyi teszteléshez, de éles környezetben nem szabad őket használni.

Ez a konfiguráció gyorsabb és rugalmasabb fejlesztési környezetet biztosít, miközben az alapkonfiguráció változatlan marad.

Előkészület a gyártásra

A termelési környezetek stabilitást, reprodukálhatóságot és biztonságot igényelnek. A konténereknek előre elkészített képekből kell futniuk ahelyett, hogy helyben épülnének, és az érzékeny információkat biztonságosan kell kezelni. Ellentétben a helyi fejlesztéshez automatikusan alkalmazott felülíró fájlokkal, a termelési felülírásokat kifejezetten meg kell határozni.

Egy gyártási felülíró fájl (docker-compose.prod.yml) tipikusan arra szolgál, hogy a helyi build lépéseket képfájl hivatkozásokkal helyettesítse, névvel ellátott köteteket használjon bind mountok helyett, és meghatározza a telepítéssel kapcsolatos tulajdonságokat, például az erőforrás-korlátozásokat és a skálázást.

Példa:

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:

Ebben a beállításban:

  • A app szolgáltatás egy előre elkészített képre hivatkozik (myapp:1.2.3), amely egy tárolóban van tárolva ahelyett, hogy helyben építené azt.

  • A kötött csatolásokat névvel ellátott kötetekkel helyettesítik a következetes és elkülönített adattárolás biztosítása érdekében.

  • A bizalmas hitelesítő adatokat biztonságosan tárolják Docker titkok segítségével.

  • A deploy szakasz a skálázási viselkedést és az erőforrás-korlátokat határozza meg a jobb stabilitás érdekében terhelés alatt.

  • A konfigurációt kifejezetten telepítés közben kell alkalmazni:

    docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Ez a struktúra biztosítja, hogy a termelési telepítések következetesek, ellenőrzöttek legyenek, és mentesek a helyi fejlesztési elemekből.

Helyi és éles felülírások összehasonlítása

Konfigurációs aspektusHelyi (docker-compose.override.yml)Termelés (docker-compose.prod.yml)
Automatikusan alkalmazvaIgenNem (kötelező a -f használata)
Forráskód-kezelésKötött csatolások az élő frissítésekhezElőre elkészített képek a tárolóból
Környezeti változókFejlesztőközpontú értékekÉles környezethez biztonságos értékek
NaplózásRészletes (debug)Tömör (info vagy error)
Titkok kezeléseEgyszerű értékek vagy .envDocker titkok vagy kezelt titkok
MéretezésEgyedüli tartályTöbbszörös másolatok
TeljesítményhangolásNem szükségesErőforrás-korlátok meghatározva
Hibakereső eszközökEngedélyezveLetiltva
Újraindítási szabályzatKézi vagy nincs
restart: unless-stopped

Több Docker Compose fájl használata tiszta módot biztosít arra, hogy az adott környezetre jellemző konfigurációkat elkülönítsük az alapbeállításoktól. Az alap docker-compose.yml a közös alkalmazásszerkezetet határozza meg, míg a docker-compose.override.yml a helyi fejlesztéshez igazítja azt. A termelési környezetbe történő telepítéskor egy explicit override fájl biztosítja a kiszámítható és biztonságos konfigurációt.

Ez a minta lehetővé teszi a csapatok számára, hogy fenntartsák a következetes munkafolyamatot. A fejlesztők helyben, lokálisan indíthatják az alkalmazást a következő módon:

docker compose up

és telepítse a termelésbe a következő segítségével:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Mindkét környezet ugyanazt az alapkonfigurációt használja, miközben megtartja a saját igényeiknek megfelelő, független beállításokat. Ez a szétválasztás javítja a karbantarthatóságot, csökkenti a konfigurációs hibákat, és összhangban tartja a helyi és a termelési környezeteket.

A környezet hibakeresése

Ez a rész a gyakori problémák elhárítási lépéseit nyújtja, amelyekbe a Docker Compose-szal futtatott alkalmazás során ütközhet.

502 Hibás átjáró (az Nginx 502-es válaszokat jelez)

Tünetek:

  • A böngésző 502 Bad Gateway hibát jelez, amikor a http://localhost:8000 címre próbál hozzáférni.
  • Az Nginx naplók olyan sorokat tartalmaznak, mint recv() failed (111: Connection refused) vagy connect() failed (111: Connection refused) while connecting to upstream.

Valószínű okok:

  • A PHP-FPM (az app szolgáltatás) nem fut, vagy nem hallgat a várt socketen/porton.
  • Az Nginx fastcgi_pass a rossz hosztra/portra mutat.
  • A tárolónevek nem egyeznek, vagy hálózati problémák vannak a nginx és az app között.
  • Az alkalmazás induláskor összeomlott (például hiányzó bővítmények vagy konfigurációs hibák miatt).

Hogyan erősítsük meg:

  1. Ellenőrizze az Nginx naplóit:

    docker compose logs nginx | tail -n 100

    Keresse a 502 üzeneteket vagy a felső szintű kapcsolati hibákat.

  2. Ellenőrizze az app konténer állapotát és naplóit:

    docker compose ps app
    
    docker compose logs app --tail=200
  3. Ellenőrizze, hogy a PHP-FPM hallgat-e az app konténerben:

    docker compose exec app ss -ltnp | grep :9000 || docker compose exec app ss -lxp | grep php-fpm

    Várható: vagy egy TCP hallgató a 9000 porton, vagy egy Unix socket, amelyet a nginx használ (ez a compose esetében ritkább).

  4. Erősítsd meg, hogy a nginx képes feloldani és elérni a app-ot a compose hálózaton:

    docker compose exec nginx ping -c 2 app
    
    docker compose exec nginx wget -qO- --timeout=2 http://app:9000/ || true

    Ha a ping meghiúsul, vagy a wget időtúllépés miatt nem fejeződik be, hálózati vagy szolgáltatásnév-eltérés áll fenn.

Gyakori javítások:

  • Ha a PHP-FPM nem fut, ellenőrizze az app naplókat a súlyos PHP hibák vagy indítási problémák miatt. Javítsa az alapvető hibát (gyakran hiányzó bővítmény vagy jogosultsági probléma), majd indítsa újra:

    docker compose restart app
    
    docker compose logs app --tail=100
  • Ha az Nginx konfiguráció más upstreamet használ (például fastcgi_pass 127.0.0.1:9000;), frissítse a docker-compose/nginx/travellist.conf-ot fastcgi_pass app:9000;-ra (a compose szolgáltatás nevének megfelelően), majd töltse újra az Nginx-et:

    # After editing config in host
    
    docker compose exec nginx nginx -s reload
    
    docker compose logs nginx --tail=50
  • Ha a PHP-FPM Unix socketen hallgat (például /run/php/php7.4-fpm.sock), de az Nginx TCP-t vár, vagy fordítva, egységesítsd TCP-re app:9000 a Compose beállításokhoz, vagy csatlakoztasd megfelelően a socketet a konténerek között (ajánlott: többkonténeres Compose esetén TCP használata).

Hiányzó PHP-kiegészítők (hibák a Composer vagy Artisan futtatásakor, vagy futásidejű hibák)

Tünetek:

  • A Composer vagy a Laravel parancsok hibával leállnak, például Class "PDO" not found, ext-pdo is missing vagy Call to undefined function json_encode üzenettel.
  • PHP hibák az app naplókban, amelyek nem definiált osztályokra vagy függvényekre hivatkoznak.

Hogyan erősítsük meg:

  1. Ellenőrizze az app konténer PHP-modul listáját:

    docker compose exec app php -m | sort

    Keresse meg a szükséges bővítményneveket (Laravel esetében tipikus bővítmények: pdo_mysql, mbstring, bcmath, openssl, tokenizer, xml, ctype, json, gd).

  2. Ellenőrizd a Composer hibaszöveget, ami általában a szükséges kiterjesztéseket nevezi meg:

    docker compose exec app composer install

Javítások:

  • Adja hozzá a hiányzó kiterjesztéseket a Dockerfile-jához, majd építse újra a képet. Példa (a pdo_mysql és a gd esetén):

    RUN apt-get update && apt-get install -y libpng-dev libxml2-dev \
        && docker-php-ext-install pdo_mysql mbstring xml gd

    Ezután építsd újra és indítsd újra:

    docker compose build app
    
    docker compose up -d app
    
    docker compose logs app --tail=100
  • Ha egy bővítmény rendszerkönyvtárakat igényel (például a gd szükséges libpng-dev), add hozzá a megfelelő apt-get install sorokat a docker-php-ext-install előtt.

  • Ha szükséged van egy beépítetlen PHP-kiterjesztésre, fontold meg a telepítést a PECL segítségével, majd engedélyezd azt a php.ini fájlban.

Adatbázis-kapcsolati hibák (A Laravel nem tud csatlakozni a MySQL-hez)

Tünetek:

  • A Laravel adatbázis-kapcsolati hibákat jelez (SQLSTATE[HY000] [2002] Connection refused vagy Access denied for user).
  • A migrációk sikertelenek, vagy az alkalmazás üres oldalt jelenít meg az adatvezérelt oldalakhoz.

Hogyan erősítsük meg:

  1. Ellenőrizze az adatbázis-konténer naplóit inicializálási hibák után:

    docker compose logs db --tail=200
  2. Ellenőrizze, hogy az adatbázis-konténer fut:

    docker compose ps db
  3. Ellenőrizze, hogy a hitelesítő adatok és a hoszt következetesek-e a .env és a docker-compose.yml között. A Laravel .env fájlban a DB_HOST-nak a compose szolgáltatás nevének (db) kell lennie, nem pedig 127.0.0.1 vagy localhost:

    DB_HOST=db
    DB_PORT=3306
    DB_DATABASE=travellist
    DB_USERNAME=travellist_user
    DB_PASSWORD=password
  4. Teszt a db konténerből:

    docker compose exec db mysql -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SHOW DATABASES;"

    Vagy teszteld az app konténerből, hogy ellenőrizd a hálózati kapcsolatot:

    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();"'

Gyakori okok és megoldások:

  • Hibás hoszt a .env fájlban: frissítsd a DB_HOST=db-t, hozd létre újra a konténereket, vagy töltsd újra a környezeti változókat:

    docker compose down
    
    docker compose up -d
    
    docker compose exec app php artisan migrate
  • Az adatbázis nem készen áll az alkalmazás indításakor: használj újrapróbálkozási mechanizmust az alkalmazásban, vagy adj hozzá egy állapotellenőrzést, majd kezd el a rendelést. Manuálisan is várhatsz:

    docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping
    
    # expected: mysqld is alive
  • Inicializáló SQL hiba: ellenőrizze a ./docker-compose/mysql alatt található fájlokat, egy szintaxis- vagy jogosultsági hiba megszakíthatja az adatbázis inicializálását. Vizsgálja meg az adatbázis naplóit az importálási hibákért.

  • Jogosultságok/hibás hitelesítő adatok: ellenőrizze, hogy az adatbázis és a felhasználó létezik-e. Hozza létre újra az adatbázist, vagy futtasson SQL parancsot a jogosultságok megadásához.

  • Host-szintű port használat: ha megpróbáltad a curl telnet://localhost:3306 parancsot, és a db szolgáltatás nem tesz közzé host portot, a kapcsolatot tervezett módon elutasítják. Teszteld a konténereken belül, vagy tedd lehetővé a portot a docker-compose.yml-ben (ports: - "3306:3306") csak helyi hibakeresés céljából.

Engedély- és fájlrendszer-problémák (tárolás, gyorsítótár, naplófájlok)

Tünetek:

  • A Laravel kivételeket dob a gyorsítótár vagy a naplók írásával kapcsolatban: A "/var/www/storage/logs/laravel.log" áramlás vagy fájl nem nyitható meg.
  • A tárolófolyamatok által létrehozott fájlok tulajdonosa a root, és a gazdafelhasználód nem írhatja őket.

Hogyan erősítsük meg:

  1. Ellenőrizze a fájlengedélyeket a hosztról:

    ls -l
    
    ls -l storage bootstrap/cache
    
    docker compose exec app id -u   # user id inside container
  2. Ellenőrizze a konténer naplóit jogosultsági hibák után.

Javítások:

  • Győződj meg róla, hogy a Dockerfile a felhasználót és a UID-t állítja be, amely megfelel a hoszt felhasználódnak (a Dockerfile-od már létrehoz egy felhasználót a ARG uid segítségével). Ellenőrizd, hogy a docker-compose.yml build argumentumai közötti uid megegyezik-e a hoszt UID-jával (általában 1000).

  • A tulajdonjog javítása a hosztról vagy a konténer belsejéből:

    docker compose exec app chown -R sammy:sammy /var/www/storage /var/www/bootstrap/cache

    vagy a gazdától:

    sudo chown -R $(id -u):$(id -g) storage bootstrap/cache
  • Fejlesztés során a bind mountok jogosultsági eltéréseket okozhatnak; érdemes inkább a konténerek indítása után futtatni konténerparancsokat a tulajdonjog beállításához.

Zeneszerzővel vagy szállítóval kapcsolatos hibák

Tünetek:

  • A composer install parancs a app könyvtárban sikertelen, vagy a hiányzó vendor mappa miatt az osztály nem található.
  • A composer memóriahiányt jelez a konténerben.

Hogyan erősítsük meg:

  • Futtasd a composert az app konténerben, és rögzítsd a kimenetet:

    docker compose exec app composer install --no-interaction --prefer-dist

Javítások:

  • Ha a composer memóriahatárait elérik, engedélyezzen több memóriát, vagy állítsa be a composer környezeti változót:

    docker compose exec app php -d memory_limit=-1 /usr/bin/composer install
  • Győződj meg róla, hogy a Composer futtatható fájl jelen van (a Dockerfile-od másolja a composert). Ha nincs, építsd újra a képet a composer réteggel.

  • Ha a vendor hiányzik a bind mount overlay miatt, győződj meg róla, hogy a bind mount nem takarja el a képfájlban létrehozott vendor mappát. A legjobb gyakorlat, ha a composer install parancsot a konténerek elindítása után futtatod, így a vendor a csatolt mappában jön létre, vagy a vendor mappát a képfájl létrehozásakor adod hozzá a konténerhez éles környezetben.

Az alkalmazás üres oldalt vagy 500-as hibákat ad vissza

Tünetek:

  • A böngésző üres választ vagy HTTP 500-at jelenít meg.
  • Az Nginx naplók 200-at jeleznek, de az oldal üres; az app naplók végzetes kivételeket mutatnak.

Hogyan erősítsük meg:

  • Ellenőrizze az alkalmazás naplóit:

    docker compose exec app tail -n 200 storage/logs/laravel.log
    
    docker compose logs app --tail=200
  • Ellenőrizze a környezetet: a APP_DEBUG=true a .env fájlban részletes hibákat fog megjeleníteni a Laravel-ben fejlesztés közben (ne engedélyezze éles környezetben).

Javítások:

  • Javítsa az alapul szolgáló kivételt, amely a laravel.log fájlban van feltüntetve.

  • Győződj meg róla, hogy a .env létezik és a APP_KEY be van állítva:

    docker compose exec app php artisan key:generate
  • Futtasd a migrációkat, töröld a gyorsítótárat:

    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

Konténerépítési hibák (hibák a docker compose build során)

Tünetek:

  • docker compose build hibát jelez az apt vagy a build lépések során.

Hogyan erősítsük meg:

  • Futtassa újra a buildet a naplókkal:

    docker compose build app

Javítások:

  • Olvassa el a sikertelen lépés kimenetét. Tipikus problémák:

    • Hálózat/DNS az építési környezetben: próbálkozzon újra, vagy győződjön meg róla, hogy a Docker hozzáfér az internethez.
    • Hiányzó csomagok vagy helytelen apt-forrás: telepítés előtt futtassa a apt-get update-et, majd utána tisztítsa meg az apt listákat.
    • A képbe másolt fájlok engedélyei: ügyelj a helyes COPY útvonalakra.

Példa Dockerfile részlet megbízható telepítésekhez:

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/*

Hálózati vagy DNS problémák a konténerek között

Tünetek:

  • Egy konténer nem tud elérni egy másikat szolgáltatásnév alapján (például az app nem érheti el a db-t a db:3306 címen).
  • ping a szolgáltatás név alapján nem működik.

Hogyan erősítsük meg:

docker compose exec app ping -c 3 db

docker compose exec app getent hosts db

docker network inspect travellist

Javítások:

  • Erősítsd meg, hogy a szolgáltatások ugyanazt a hálózatot használják a docker-compose.yml fájlban (mindkettőnek a travellist-re kell hivatkoznia).

  • Ha megváltoztattad a szolgáltatások vagy hálózatok neveit, frissítsd ennek megfelelően a DB_HOST értékét és az Nginx upstream-eket.

  • Hálózat újraalkotása (ez megszünteti az átmeneti konténereket, ezért legyél óvatos):

    docker compose down
    
    docker network prune   # optional and destructive
    
    docker compose up -d

Hasznos diagnosztikai parancsok

Futtassa ezeket célzott ellenőrzésre:

  • Futó konténerek és portok megjelenítése:

    docker compose ps
  • Egy szolgáltatás naplóinak megtekintése:

    docker compose logs -f --tail=200 nginx
  • Futtass egy shellt egy konténerben:

    docker compose exec app sh
    
    docker compose exec db bash
  • Konténer környezeti változóinak ellenőrzése:

    docker compose exec app env | sort
    
    docker compose exec db env | grep MYSQL
  • Ellenőrizze a konténer folyamatlistáját:

    docker compose exec app ps aux
    
    docker compose exec app ss -ltnp
  • Ellenőrizze a MySQL állapotát:

    docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping

Mikor érdemes a hosztportokat kitenni hibakereséshez

Alapértelmezés szerint a db szolgáltatás ebben a beállításban nincs köthető a hoszt portjaihoz. A portokat csak helyi hibakereséshez tegye hozzá. Ahhoz, hogy ideiglenesen a MySQL-t elérhetővé tegye a hoszton, adja hozzá a docker-compose.yml-hez a db alatt:

ports:
  - "3306:3306"

Ezután indítsa újra:

docker compose up -d db

A hibakeresés után távolítsa el a ports leképezést, hogy elkerülje az adatbázis hálózatra történő kitettségét.

GYIK

1. Szükségem van a Composer telepítésére a gazdagépen?

Nem. Teljesen a konténeren belül is futtathatod a Composert, ami ez esetben a javasolt megközelítés a Compose munkafolyamathoz. A tutorialban szereplő Dockerfile már tartalmazza a Composert, ezért olyan parancsokat használj, mint docker compose exec app composer install vagy docker compose run --rm app composer require vendor/package. A Composer a konténerben történő futtatása biztosítja a megfelelő PHP verziót és kiegészítőket, és elkerüli, hogy a vendor fájlok eltérő tulajdonjoggal jöjjenek létre a host rendszeren.

2. Futtathatok Laravel migrációkat a konténeren belül?

Igen. Futtassa a migrációkat az alkalmazás konténeréből, így ugyanazt a futtatókörnyezetet és hálózatot használják, mint az alkalmazása: docker compose exec app php artisan migrate. Egyszeri vagy CI feladatokhoz használhatja a docker compose run --rm app php artisan migrate --force parancsot. A migrációk futtatása előtt győződjön meg róla, hogy az adatbázis konténer egészséges és elfogadja a kapcsolatokat, például a docker compose exec db mysqladmin -u$ {DB_USERNAME} -p$ {DB_PASSWORD} ping paranccsal, vagy ismételje meg, amíg válaszol.

3. Hogyan telepíthetek további PHP-bővítményeket?

Adja hozzá a szükséges rendszercsomagokat és kiterjesztésparancsokat a Dockerfile-hoz, majd építse újra a képet. Például telepítse a függőségeket és építsen közös kiterjesztéseket valami ilyesmivel:

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

Ha PECL kiegészítőre van szükséged, használd a pecl install és a docker-php-ext-enable parancsokat. A Dockerfile szerkesztése után futtasd a docker compose build app parancsot, majd a docker compose up -d app parancsot a változtatások alkalmazásához.

4. Hogyan tehetem elérhetővé az Nginx konténert HTTPS-en keresztül?

Adj hozzá egy HTTPS szerverblokkot az Nginx konfigurációdhoz, csatold a tanúsítványodat és a kulcsodat a konténerbe, és nyisd meg a 443-as portot a docker-compose-ban. Íme egy példa minimális változtatásokkal a docker-compose.yml fájlban:

services:
  nginx:
    ports:
      - "8000:80"
      - "443:443"
    volumes:
      - ./docker-compose/nginx:/etc/nginx/conf.d
      - ./certs:/etc/nginx/certs:ro

Ezután adj hozzá egy SSL szerverblokkot, amely a /etc/nginx/certs/fullchain.pem és a /etc/nginx/certs/privkey.pem fájlokra hivatkozik. Éles környezetben használd inkább egy reverz proxy-t vagy tanúsítványkezelőt, például Traefik-et, vagy egy külső terheléselosztót a tanúsítványok biztonságos beszerzéséhez és megújításához, ahelyett hogy a privát kulcsokat az alkalmazás stackben tárolnád.

5. Hogyan építhetem újra a Laravel-t a kód módosítása után?

Attól függ, mi változott. Ha a projekt könyvtárához bind mountokat használsz, a PHP, sablonok, útvonalak és kontrollerek módosításai azonnal látszanak; ha szükséges, futtasd a Laravel cache törlést, például:

docker compose exec app php artisan config:clear

docker compose exec app php artisan route:clear

docker compose exec app php artisan view:clear

Ha megváltoztattad a Composer függőségeket vagy a Dockerfile-t (új kiterjesztések vagy rendszercsomagok), telepítsd újra vagy építsd újra: docker compose exec app composer install a függőségváltozásokhoz, és docker compose build app && docker compose up -d a Dockerfile változásokhoz. Indítsd újra az érintett szolgáltatást, amikor a PHP-FPM vagy az Nginx konfigurációját változtatod: docker compose restart app vagy docker compose restart nginx.

Következtetés

Ebben az útmutatóban egy Docker környezetet állítottunk be három konténerrel, a Docker Compose segítségével, hogy YAML fájlban definiáljuk az infrastruktúránkat.

Innét kezdve dolgozhatsz a Laravel alkalmazásodon anélkül, hogy telepítened és beállítanod kellene egy helyi webkiszolgálót a fejlesztéshez és teszteléshez. Ráadásul egy eldobható környezettel fogsz dolgozni, amely könnyen reprodukálható és terjeszthető, ami hasznos lehet az alkalmazás fejlesztése során, valamint a produkciós környezet felé történő lépéskor is.

További Laravel oktatóanyagokért tekintse meg a következő cikkeket:

  • Tedd közzé Laravel alkalmazásodat a Linux-Console.net-en
  • Hogyan telepítsük és konfiguráljuk a Laravelt Nginx-szel Ubuntu alatt (LEMP stack)
  • Hogyan hozzunk létre Laravel Eloquent API erőforrásokat modellek JSON-formátumba történő átalakításához
  • Hogyan indítsunk új Laravel alkalmazást Docker Compose-szal

Köszönjük, hogy a Linux-Console.net közösséggel tanultál.