Implementer en PHP-applikation ved hjælp af Docker-compose

PHP-applikationer er normalt sammensat af en webserver, et relationsdatabasesystem og selve sprogfortolkeren. I denne tutorial vil vi udnytte en fuld PHP-applikationsstak ved hjælp af docker. Dette er en dybdegående tutorial, hvor vi skal bygge og orkestrere containere til Nginx (webserveren), MySQL (databasesystemet) og PHP.

Af hensyn til denne vejledning vil vi skrive en simpel applikation, der læser en liste over byer fra en database og viser den på en webside, på denne måde vil vi demonstrere en grundlæggende, men fungerende, PHP-applikation.

Denne vejledning antager, at du allerede har Docker-CE installeret og i det mindste et minimalt kendskab til docker. For den sags skyld kan du gennemgå følgende tutorials:

Konfiguration af vores arbejdsmiljø

En real life docker-baseret applikation vil typisk være sammensat af flere containere. Håndtering af disse manuelt kan nemt blive ret rodet og besværligt. Det er her docker-compose kommer ind i billedet. Det hjælper dig med at administrere en række containere gennem en simpel yamlkonfigurationsfil.

Installer docker-compose.

curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Opret en mappe til at indeholde alle de nødvendige filer i dette eksempel og derefter cdind i den. Fra nu af er dette vores arbejdsmappe, og hver kommando vil blive udført inde i denne mappe, og hver sti vil blive refereret til den. Denne mappe kan senere henvises til som WORKING_DIR.

mkdir ~/docker
cd ~/docker

Opret nu yderligere tre mapper.

mkdir php nginx app

Den phpmappe er, hvor vi vil bygge vores brugerdefinerede PHP billede, nginxvil mappen holde de nødvendige filer til vores brugerdefinerede nginx image og den appmappe er, hvor vi vil lægge kildekoden og konfiguration af vores stikprøve ansøgning.

Konfiguration af PHP-beholderen

I dette eksempel skal vi bruge php-fpmtil at oprette forbindelse til Nginx-webserveren. Vi vil bruge det officielle PHP-basebillede. Vi skal dog også installere og aktivere nogle udvidelser, så vi kan få adgang til databasen. phpOpret en fil med navnet inde i mappen, Dockerfileog læg følgende indhold ind i den.

FROM php:7.1-fpm-alpine3.4
RUN apk update --no-cache \
    && apk add --no-cache $PHPIZE_DEPS \
    && apk add --no-cache mysql-dev \
    && docker-php-ext-install pdo pdo_mysql

Bemærk, at vi bruger Alpine-versionen af ​​det officielle PHP-billede. Alpine er en meget lille distribution rettet mod containere ved at give meget mindre fodspor. Bemærk også brugen af ​​kommandoen docker-php-ext-install, det officielle PHP-billede giver denne kommando for at lette processen med at installere og konfigurere PHP-udvidelser.

Lad os nu bygge dette Docker-billede ved at udstede følgende (inde i vores WORKING_DIR):

docker build -t vultr-php php/

den docker-compose.ymlfil

Som allerede nævnt docker-composegiver det dig mulighed for at administrere et antal containere gennem en simpel konfigurationsfil. Denne konfigurationsfil hedder typisk docker-compose.yml. Opret denne fil inde i appmappen.

touch app/docker-compose.yml

Indsæt nu følgende indhold i denne fil.

version: '2'
services:
  php:
    image: vultr-php
    volumes:
      - ./:/app
    working_dir: /app

Vi vil forklare denne syntaks. Bemærk først den første linje.

version: '2'

Dette angiver versionen af ​​den anvendte docker-compose.ymlkonfigurationsfil. Den næste linje specificerer tjenesterne, eller med andre ord, de containere, der skal klargøres.

services:
  php:
    image: vultr-php
    volumes:
      - ./:/app
    working_dir: /app

Bemærk, at hver tjeneste har en specifik nøgle inde i servicesblokken. Det navn, der er angivet her, vil blive brugt til at henvise til denne specifikke container senere. Bemærk også, at inde i phpkonfigurationen definerer vi det billede, der bruges til at køre containeren (dette er det billede, vi byggede tidligere). Vi definerer også en volumenmapping.

volumes:
  - ./:/app

Dette fortæller, docker-composeat den aktuelle mappe ( ./) skal tilknyttes /appmappen inde i containeren. Den sidste linje sætter /appmappen inde i containeren som arbejdsbiblioteket, hvilket betyder, at dette er mappen, hvorfra alle fremtidige kommandoer inde i en container som standard udføres.

Vi kan nu orkestrere vores containere.

cd ~/docker/app
docker-compose up -d

Du kan køre følgende kommando for at sikre, at PHP-beholderen blev udført:

docker ps

Sådan udføres kommandoer inde i containerne

Stadig inde i appmappen kan vi køre enhver kommando inde i en defineret servicecontainer ved hjælp af docker-composekommandoen.

docker-compose exec [service] [command]

Den [service]pladsholder refererer til tjenesten tasten. I vores tilfælde var dette php. Lad os køre en kommando inde i containeren for at tjekke vores PHP-version.

docker-compose exec php php -v

Du vil se følgende output.

PHP 7.1.14 (cli) (built: Feb  7 2018 00:40:45) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

Konfiguration af Nginx-beholderen

Ligesom PHP-containeren skal vi oprette et brugerdefineret billede til webserveren. Men i dette tilfælde skal vi blot levere en konfiguration til vores virtual host. Sørg for at du er inde i vores WORKING_DIRog opret en Dockerfileinde i nginxmappen:

cd ~/docker
touch nginx/Dockerfile

Læg nu følgende indhold ind i dette Dockerfile:

FROM nginx:1.13.8-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf

Vi bruger standard Nginx-billedet baseret på Alpine. På denne Docker-fil kopierer vi simpelthen en konfigurationsfil til vores applikationsopsætning. Før du bygger dette billede, skal du oprette en konfigurationsfil.

touch nginx/default.conf

Udfyld det nu med dette indhold.

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /app;
    index index.php;

    #server_name server_domain_or_IP;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Bemærk, at på fastcgi_pass php:9000linjen henviser vi til PHP-beholderen ved dets navn inde i serviceblokken af docker-compose.ymlkonfigurationsfilen. docker-composeOpretter internt et netværk og tildeler tjenestenavnet som værtsnavn til hver af de definerede tjenester. Vi kan nu bygge Nginx-billedet.

docker build -t vultr-nginx nginx/

Opdatering docker-compose.yml

Opdater nu app/docker-compose.ymlfilen.

version: '2'
services:
  php:
    image: vultr-php
    volumes:
      - ./:/app
    working_dir: /app
  web:
    image: vultr-nginx
    volumes:
      - ./:/app
    depends_on:
      - php
    ports:
      - 80:80

Vi har kun tilføjet en ny tjeneste. Konfigurationen er næsten den samme, bortset fra følgende.

depends_on:
  - php
ports:
  - 80:80

Once the Nginx container needs the PHP service to be fully initialized, we force this requirement in the depends_on option. The ports configuration key maps a host port to a container port, here we map the port 80 in the host to the port 80 in the container.

Now create a file called index.php inside the app folder and put the following in it.

<?php phpinfo();

Make sure the port 80 is accessible through your firewall and execute the following.

cd ~/docker/app
docker-compose up -d

Once again, double check that the service is up.

docker ps

Open a browser and access [vultr-instance-ip]. You may find out your Vultr instance IP address by running the following.

hostname -I

You will see the PHP info page.

Configuring the MySQL container

Det officielle MySQL-billede giver dig mulighed for at konfigurere containeren gennem simple miljøvariabler. Dette kan gøres med en environmentmulighed inde i serviceblokdefinitionen. Opdater ~/docker/app/docker-compose.ymlfilen til følgende.

version: '2'
services:
  php:
    image: vultr-php
    volumes:
      - ./:/app
    working_dir: /app
  web:
    image: vultr-nginx
    volumes:
      - ./:/app
    depends_on:
      - php
    ports:
      - 80:80
  mysql:
    image: mysql:5.7.21
    volumes:
      - ./:/app
      - dbdata:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=world
      - MYSQL_ROOT_PASSWORD=root
    working_dir: /app
volumes:
  dbdata:

Nu har vi defineret en ny service til databasen. Læg mærke til linjen dbdata:/var/lib/mysql. Dette monterer stien på containeren /var/lib/mysqltil en vedvarende volumen, der administreres af Docker, på denne måde bevarer databasedataene, efter at containeren er fjernet. Denne volumen skal defineres i en blok på øverste niveau, som du kan se i slutningen af ​​filen.

Før vi orkestrerer vores nye konfiguration, lad os downloade et eksempel på en MySQL-database. Den officielle MySQL-dokumentation indeholder nogle eksempeldatabaser. Vi vil bruge den velkendte verdensdatabase. Denne database giver en liste over lande og byer. For at downloade denne prøve skal du udføre følgende i vores app-mappe.

curl -L http://downloads.mysql.com/docs/world.sql.gz -o world.sql.gz
gunzip world.sql.gz

Lad os nu orkestrere vores containere.

docker-compose up -d

Som du måske allerede har bemærket, starter docker-compose upkommandoen kun de containere, der ikke allerede er startet. Den tjekker for forskellene mellem din docker-compose.ymlfil og den aktuelle konfiguration af kørende containere.

En gang mere skal du kontrollere, at MySQL-beholderen er startet.

docker ps

Udfyld nu verdensdatabasen.

docker-compose exec -T mysql mysql -uroot -proot world < world.sql

Du kan kontrollere, at databasen er udfyldt ved at vælge data direkte fra databasen. Få først adgang til MySQL-prompten inde i containeren.

docker-compose exec mysql mysql -uroot -proot world

Kør følgende i MySQL-prompten.

select * from city limit 10;

Du vil se en liste over byer. Afslut nu MySQL-prompten.

mysql> exit

Opbygning af vores applikation

Nu hvor alle de nødvendige beholdere er oppe at køre, kan vi fokusere på vores eksempelapplikation. Opdater app/index.phpfilen til følgende.

<?php

$pdo = new PDO('mysql:host=mysql;dbname=world;charset=utf8', 'root', 'root');

$stmt = $pdo->prepare("
    select city.Name, city.District, country.Name as Country, city.Population
    from city
    left join country on city.CountryCode = country.Code
    order by Population desc
    limit 10
");
$stmt->execute();
$cities = $stmt->fetchAll(PDO::FETCH_ASSOC);

?>

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vultr Rocks!</title>
</head>
<body>
    <h2>Most Populous Cities In The World</h2>
    <table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Country</th>
            <th>District</th>
            <th>Population</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($cities as $city): ?>
            <tr>
                <td><?=$city['Name']?></td>
                <td><?=$city['Country']?></td>
                <td><?=$city['District']?></td>
                <td><?=number_format($city['Population'], 0)?></td>
            </tr>
        <?php endforeach ?>
    </tbody>
    </table>
</body>
</html>

Hvis du åbner [vultr-instance-ip]i en webbrowser, vil du se en liste over de mest folkerige byer i verden. Tillykke, du har implementeret et fuldt fungerende PHP-program ved hjælp af docker.

Konklusion

I denne tutorial har jeg demonstreret trin for trin, hvordan man konfigurerer en fuldt fungerende PHP-applikation. Vi byggede brugerdefinerede billeder til PHP og Nginx og konfigurerede docker-compose til at orkestrere vores containere. På trods af at den er meget grundlæggende og enkel, afspejler denne opsætning et scenarie fra det virkelige liv.

I denne guide har vi bygget og tagget vores billeder lokalt. For en mere fleksibel opsætning kan du skubbe disse billeder til et docker-register . Du kan skubbe til det officielle docker-register eller endda opsætte dit eget docker-register. Under alle omstændigheder vil dette give dig mulighed for at bygge dine billeder på én vært og bruge dem på en anden.

For en mere detaljeret brug af docker-compose, skal du henvise til den officielle dokumentation .

Afhængigt af dine applikationskrav og den PHP-ramme, du bruger, vil du måske tilføje flere udvidelser. Dette kan nemt gøres ved at ændre det Dockerfilebrugte til at bygge vores brugerdefinerede PHP-billede. Nogle udvidelser har dog brug for ekstra afhængigheder for at blive installeret i containeren. Du bør henvise til listen over udvidelser i den officielle PHP-dokumentation for at gennemgå de grundlæggende krav til hver udvidelse.

Efterlad en kommentar

The Rise of Machines: Real World Applications of AI

The Rise of Machines: Real World Applications of AI

Kunstig intelligens er ikke i fremtiden, det er her lige i nuet I denne blog Læs, hvordan kunstig intelligens-applikationer har påvirket forskellige sektorer.

DDOS-angreb: et kort overblik

DDOS-angreb: et kort overblik

Er du også et offer for DDOS-angreb og forvirret over forebyggelsesmetoderne? Læs denne artikel for at løse dine spørgsmål.

Har du nogensinde spekuleret på, hvordan tjener hackere penge?

Har du nogensinde spekuleret på, hvordan tjener hackere penge?

Du har måske hørt, at hackere tjener mange penge, men har du nogensinde spekuleret på, hvordan tjener de den slags penge? lad os diskutere.

Revolutionære opfindelser fra Google, der vil gøre dit liv lettere.

Revolutionære opfindelser fra Google, der vil gøre dit liv lettere.

Vil du se revolutionerende opfindelser fra Google, og hvordan disse opfindelser ændrede livet for ethvert menneske i dag? Læs derefter til bloggen for at se opfindelser fra Google.

Fredag ​​Essential: Hvad skete der med AI-drevne biler?

Fredag ​​Essential: Hvad skete der med AI-drevne biler?

Konceptet med selvkørende biler til at køre på vejene ved hjælp af kunstig intelligens er en drøm, vi har haft i et stykke tid nu. Men på trods af flere løfter er de ingen steder at se. Læs denne blog for at lære mere...

Teknologisk singularitet: En fjern fremtid for menneskelig civilisation?

Teknologisk singularitet: En fjern fremtid for menneskelig civilisation?

Efterhånden som videnskaben udvikler sig i et hurtigt tempo og overtager en stor del af vores indsats, stiger risikoen for at udsætte os selv for en uforklarlig Singularitet. Læs, hvad singularitet kunne betyde for os.

Funktioner af Big Data Reference Architecture Layers

Funktioner af Big Data Reference Architecture Layers

Læs bloggen for at kende forskellige lag i Big Data-arkitekturen og deres funktionaliteter på den enkleste måde.

Udvikling af datalagring – Infografik

Udvikling af datalagring – Infografik

Opbevaringsmetoderne for dataene har været under udvikling, kan være siden fødslen af ​​dataene. Denne blog dækker udviklingen af ​​datalagring på basis af en infografik.

6 fantastiske fordele ved at have smarte hjemmeenheder i vores liv

6 fantastiske fordele ved at have smarte hjemmeenheder i vores liv

I denne digitalt drevne verden er smarte hjemmeenheder blevet en afgørende del af livet. Her er et par fantastiske fordele ved smarte hjemmeenheder om, hvordan de gør vores liv værd at leve og enklere.

macOS Catalina 10.15.4-tillægsopdatering forårsager flere problemer end at løse

macOS Catalina 10.15.4-tillægsopdatering forårsager flere problemer end at løse

For nylig udgav Apple macOS Catalina 10.15.4 en supplerende opdatering for at løse problemer, men det ser ud til, at opdateringen forårsager flere problemer, hvilket fører til mursten af ​​mac-maskiner. Læs denne artikel for at lære mere