Konfigurera vår arbetsmiljö
Konfigurera PHP-behållaren
Konfigurera Nginx-behållaren
Konfigurera MySQL-behållaren
Bygger vår applikation
Slutsats
PHP-applikationer är vanligtvis sammansatta av en webbserver, ett relationsdatabassystem och själva språktolken. I den här handledningen kommer vi att utnyttja en fullständig PHP-applikationsstack med docker. Det här är en djupgående handledning där vi ska bygga och orkestrera behållare för Nginx (webservern), MySQL (databassystemet) och PHP.
För den här handledningens skull kommer vi att skriva en enkel applikation som läser en lista över städer från en databas och visar den på en webbsida, på detta sätt kommer vi att demonstrera en grundläggande, men fungerande, PHP-applikation.
Den här guiden förutsätter att du har Docker-CE redan installerat och åtminstone en minimal kunskap om docker. För den delen kan du läsa följande tutorials:
Konfigurera vår arbetsmiljö
En hamnarbaserad applikation i verkligheten kommer vanligtvis att bestå av flera containrar. Att hantera dessa manuellt kan lätt bli ganska rörigt och krångligt. Det är där docker-compose kommer in i bilden. Det hjälper dig att hantera ett antal behållare genom en enkel yaml
konfigurationsfil.
Installera 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
Skapa en mapp för att hålla alla nödvändiga filer i detta exempel och sedan cd
in i den. Från och med nu är detta vår arbetskatalog och varje kommando kommer att köras i den här mappen och varje sökväg kommer att refereras till den. Denna mapp kan hänvisas till senare som WORKING_DIR
.
mkdir ~/docker
cd ~/docker
Skapa nu ytterligare tre mappar.
mkdir php nginx app
Den php
mapp är där vi kommer att bygga vår egen PHP image, nginx
kommer mappen att hålla nödvändiga filer för våra egna Nginx bilden och app
mappen är där vi kommer att lägga källkoden och konfiguration av vårt urval program.
Konfigurera PHP-behållaren
I det här exemplet kommer vi att använda för php-fpm
att ansluta till Nginx webbserver. Vi kommer att använda den officiella PHP-basbilden. Men vi måste också installera och aktivera vissa tillägg så att vi kan komma åt databasen. Inuti php
mappen skapa en fil med namnet Dockerfile
och lägg in följande innehåll 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
Observera att vi använder den alpina versionen av den officiella PHP-bilden. Alpine är en mycket liten distribution riktad mot containrar genom att ge mycket mindre fotavtryck. Notera också användningen av kommandot docker-php-ext-install
, den officiella PHP-avbildningen tillhandahåller detta kommando för att förenkla processen med att installera och konfigurera PHP-tillägg.
Låt oss nu bygga denna Docker-bild genom att utfärda följande (inuti vår WORKING_DIR
):
docker build -t vultr-php php/
den docker-compose.yml
filen
Som redan nämnts docker-compose
låter dig hantera ett antal behållare genom en enkel konfigurationsfil. Denna konfigurationsfil heter vanligtvis docker-compose.yml
. Skapa den här filen i app
mappen.
touch app/docker-compose.yml
Lägg nu följande innehåll i den här filen.
version: '2'
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Vi kommer att förklara denna syntax. Notera först den första raden.
version: '2'
Detta anger vilken version av docker-compose.yml
konfigurationsfilen som används. Nästa rad specificerar tjänsterna, eller med andra ord, behållarna som ska tillhandahållas.
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Observera att varje tjänst har en specifik nyckel inuti services
blocket. Namnet som anges här kommer att användas för att referera till denna specifika behållare senare. Observera också att inuti php
konfigurationen definierar vi bilden som används för att köra behållaren (detta är bilden vi byggde tidigare). Vi definierar också en volymkartläggning.
volumes:
- ./:/app
Detta talar om för docker-compose
att mappa den aktuella katalogen ( ./
) till /app
katalogen inuti behållaren. Den sista raden ställer in /app
mappen inuti behållaren som arbetskatalog, vilket betyder att detta är mappen där alla framtida kommandon inuti en behållare som standard körs från.
Vi kan nu orkestrera våra containrar.
cd ~/docker/app
docker-compose up -d
Du kan köra följande kommando för att se till att PHP-behållaren kördes:
docker ps
Hur man utför kommandon inuti behållarna
Fortfarande inne i app
mappen kan vi köra vilket kommando som helst i en definierad tjänstebehållare med hjälp av docker-compose
kommandot.
docker-compose exec [service] [command]
Den [service]
platshållare hänvisar till servicenyckeln. I vårt fall var detta php
. Låt oss köra ett kommando inuti behållaren för att kontrollera vår PHP-version.
docker-compose exec php php -v
Du kommer att se följande utdata.
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
Konfigurera Nginx-behållaren
Precis som PHP-behållaren måste vi skapa en anpassad bild för webbservern. Men i det här fallet behöver vi bara tillhandahålla en konfiguration för vår virtual host
. Se till att du är inne i vår WORKING_DIR
och skapa en Dockerfile
inuti nginx
mappen:
cd ~/docker
touch nginx/Dockerfile
Lägg nu följande innehåll i detta Dockerfile
:
FROM nginx:1.13.8-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Vi använder standard Nginx-bilden baserad på Alpine. På denna Docker-fil kopierar vi helt enkelt en konfigurationsfil till vår applikationsinställning. Innan du bygger den här bilden, skapa en konfigurationsfil.
touch nginx/default.conf
Fyll den nu med detta innehåll.
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;
}
}
Observera att på fastcgi_pass php:9000
raden hänvisar vi till PHP-behållaren med dess namn inuti service
blocket i docker-compose.yml
konfigurationsfilen. Skapar internt docker-compose
ett nätverk och tilldelar tjänstens namn som värdnamn till var och en av de definierade tjänsterna. Vi kan nu bygga Nginx-bilden.
docker build -t vultr-nginx nginx/
Uppdaterar docker-compose.yml
Uppdatera nu app/docker-compose.yml
filen.
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 bara lagt till en ny tjänst. Konfigurationen är nästan densamma, förutom följande.
depends_on:
- php
ports:
- 80:80
När Nginx-behållaren behöver PHP-tjänsten för att initieras helt, tvingar vi fram detta krav i depends_on
alternativet. Den ports
konfiguration nyckeln kartor en värd port till en containerhamn, här vi kartlägga hamnen 80
i värden till hamnen 80
i behållaren.
Skapa nu en fil som heter index.php
inuti app
mappen och lägg in följande i den.
<?php phpinfo();
Se till att porten 80
är tillgänglig via din brandvägg och utför följande.
cd ~/docker/app
docker-compose up -d
Återigen, dubbelkolla att tjänsten är uppe.
docker ps
Öppna en webbläsare och öppna [vultr-instance-ip]
. Du kan ta reda på din Vultr-instans-IP-adress genom att köra följande.
hostname -I
Du kommer att se PHP-infosidan.
Konfigurera MySQL-behållaren
Den officiella MySQL-avbildningen låter dig konfigurera behållaren genom enkla miljövariabler. Detta kan göras med ett environment
alternativ i serviceblockdefinitionen. Uppdatera ~/docker/app/docker-compose.yml
filen till följande.
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 definierat en ny tjänst för databasen. Lägg märke till linjen dbdata:/var/lib/mysql
. Detta monterar sökvägen på behållaren /var/lib/mysql
till en beständig volym som hanteras av Docker, på så sätt kvarstår databasdata efter att behållaren tagits bort. Denna volym måste definieras i ett block på översta nivån som du kan se i slutet av filen.
Innan vi orkestrerar vår nya konfiguration, låt oss ladda ner ett exempel på MySQL-databas. Den officiella MySQL-dokumentationen
tillhandahåller några exempeldatabaser. Vi kommer att använda den välkända världsdatabasen. Denna databas ger en lista över länder och städer. För att ladda ner detta exempel, kör följande i vår app-mapp.
curl -L http://downloads.mysql.com/docs/world.sql.gz -o world.sql.gz
gunzip world.sql.gz
Låt oss nu orkestrera våra containrar.
docker-compose up -d
Som du kanske redan har märkt docker-compose up
startar kommandot endast de behållare som inte redan har startat. Den letar efter skillnader mellan din docker-compose.yml
fil och den aktuella konfigurationen av körande behållare.
En gång till, kontrollera att MySQL-behållaren startades.
docker ps
Fyll nu i världsdatabasen.
docker-compose exec -T mysql mysql -uroot -proot world < world.sql
Du kan verifiera att databasen fylldes i genom att välja data direkt från databasen. Öppna först MySQL-prompten inuti behållaren.
docker-compose exec mysql mysql -uroot -proot world
Kör följande i MySQL-prompten.
select * from city limit 10;
Du kommer att se en lista över städer. Avsluta nu MySQL-prompten.
mysql> exit
Bygger vår applikation
Nu när alla nödvändiga behållare är igång kan vi fokusera på vår exempelapplikation. Uppdatera
app/index.php
filen till följande.
<?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>
Om du använder [vultr-instance-ip]
en webbläsare kommer du att se en lista över de mest folkrika städerna i världen. Grattis, du har distribuerat en fullt fungerande PHP-applikation med docker.
Slutsats
I den här handledningen har jag steg för steg demonstrerat hur man konfigurerar en fullt fungerande PHP-applikation. Vi byggde anpassade bilder för PHP och Nginx och konfigurerade docker-compose för att orkestrera våra containrar. Trots att den är väldigt enkel och enkel återspeglar den här inställningen ett verkligt scenario.
I den här guiden har vi byggt och taggat våra bilder lokalt. För en mer flexibel installation kan du skicka dessa bilder till ett dockningsregister . Du kan gå till det officiella docker-registret eller till och med ställa in ditt eget docker-register. I vilket fall som helst kommer detta att tillåta dig att bygga dina bilder på en värd och använda dem på en annan.
För en mer detaljerad användning av docker-compose
, bör du se den officiella dokumentationen .
Beroende på dina applikationskrav och PHP-ramverket du använder, kanske du vill lägga till fler tillägg. Detta kan enkelt göras genom att modifiera den som Dockerfile
används för att bygga vår anpassade PHP-bild. Vissa tillägg behöver dock extra beroenden för att installeras i behållaren. Du bör hänvisa till listan över tillägg i
PHP officiella dokumentation för att granska de grundläggande kraven för varje tillägg.