Configurant el nostre entorn de treball
Configuració del contenidor PHP
Configuració del contenidor Nginx
Configuració del contenidor MySQL
Construint la nostra aplicació
Conclusió
Les aplicacions PHP solen estar compostes per un servidor web, un sistema de bases de dades relacionals i el propi intèrpret de llenguatge. En aquest tutorial aprofitarem una pila d'aplicacions PHP completa amb Docker. Aquest és un tutorial en profunditat en el qual construirem i orquestrarem contenidors per a Nginx (el servidor web), MySQL (el sistema de bases de dades) i PHP.
Pel bé d'aquest tutorial, escriurem una aplicació senzilla que llegeix una llista de ciutats d'una base de dades i la mostra en una pàgina web, d'aquesta manera demostrarem una aplicació PHP bàsica però funcional.
Aquesta guia suposa que ja teniu Docker-CE instal·lat i almenys un coneixement mínim de funcionament de Docker. Per això, podeu revisar els tutorials següents:
Configurant el nostre entorn de treball
Una aplicació basada en Docker de la vida real normalment estarà composta per diversos contenidors. Gestionar-los manualment pot esdevenir fàcilment bastant desordenat i feixuc. Aquí és on entra en joc docker-compose. Us ajuda a gestionar diversos contenidors mitjançant un yamlfitxer de configuració senzill .
Instal·leu 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
Creeu una carpeta per contenir tots els fitxers necessaris d'aquest exemple i després cddins-hi. A partir d'ara, aquest és el nostre directori de treball i totes les ordres s'executaran dins d'aquesta carpeta i es farà referència a cada camí en relació a ella. Aquesta carpeta es pot fer referència més endavant com a WORKING_DIR.
mkdir ~/docker
cd ~/docker
Ara creeu tres carpetes més.
mkdir php nginx app
La phpcarpeta és on construirem la nostra imatge PHP personalitzada, la nginxcarpeta conté els fitxers necessaris per a la nostra imatge personalitzada nginx i la appcarpeta és on posarem el codi font i la configuració de la nostra aplicació de mostra.
Configuració del contenidor PHP
En aquest exemple, utilitzarem php-fpmper connectar-nos al servidor web Nginx. Utilitzarem la imatge base oficial de PHP. Tanmateix, també hem d'instal·lar i habilitar algunes extensions perquè puguem accedir a la base de dades. Dins de la phpcarpeta, creeu un fitxer anomenat Dockerfilei poseu-hi el contingut següent.
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
Tingueu en compte que estem utilitzant la versió Alpine de la imatge oficial de PHP. Alpine és una distribució molt petita dirigida als contenidors, ja que proporciona petjades molt més petites. A més, tingueu en compte l'ús de l'ordre docker-php-ext-install, la imatge oficial de PHP proporciona aquesta ordre per facilitar el procés d'instal·lació i configuració d'extensions PHP.
Ara, anem a construir aquesta imatge de Docker emetent el següent (dins del nostre WORKING_DIR):
docker build -t vultr-php php/
El docker-compose.ymlfitxer
Com ja s'ha esmentat, docker-composepermet gestionar una sèrie de contenidors mitjançant un senzill fitxer de configuració. Aquest fitxer de configuració normalment s'anomena docker-compose.yml. Creeu aquest fitxer dins de la appcarpeta.
touch app/docker-compose.yml
Ara poseu el següent contingut en aquest fitxer.
version: '2'
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Explicarem aquesta sintaxi. Primer, tingueu en compte la primera línia.
version: '2'
Això especifica la versió del docker-compose.ymlfitxer de configuració utilitzada. A la següent línia s'especifiquen els serveis, és a dir, els contenidors que s'han de subministrar.
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Tingueu en compte que cada servei té una clau específica dins del servicesbloc. El nom especificat aquí s'utilitzarà per fer referència a aquest contenidor específic més endavant. Tingueu en compte també que dins de la phpconfiguració, definim la imatge utilitzada per executar el contenidor (aquesta és la imatge que hem creat anteriorment). També definim un mapeig de volum.
volumes:
- ./:/app
Això indica que docker-composecal assignar el directori actual ( ./) al /appdirectori dins del contenidor. L'última línia estableix la /appcarpeta dins del contenidor com a directori de treball, el que significa que aquesta és la carpeta des d'on s'executen per defecte totes les ordres futures dins d'un contenidor.
Ara podem orquestrar els nostres contenidors.
cd ~/docker/app
docker-compose up -d
Podeu executar l'ordre següent per assegurar-vos que el contenidor PHP s'ha executat:
docker ps
Com executar ordres dins dels contenidors
Encara dins de la appcarpeta, podem executar qualsevol ordre dins d'un contenidor de servei definit amb l'ajuda de l' docker-composeordre.
docker-compose exec [service] [command]
El [service]marcador de posició fa referència a la clau de servei. En el nostre cas, això va ser php. Executem una ordre dins del contenidor per comprovar la nostra versió de PHP.
docker-compose exec php php -v
Veureu la següent sortida.
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
Configuració del contenidor Nginx
Igual que el contenidor PHP, hem de crear una imatge personalitzada per al servidor web. Però en aquest cas, només hem de proporcionar una configuració per al nostre virtual host. Assegureu-vos que esteu dins de la nostra WORKING_DIRi creeu una Dockerfiledins de la nginxcarpeta:
cd ~/docker
touch nginx/Dockerfile
Ara poseu-hi el contingut següent Dockerfile:
FROM nginx:1.13.8-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Estem utilitzant la imatge Nginx predeterminada basada en Alpine. En aquest fitxer Docker, simplement copiem un fitxer de configuració a la configuració de la nostra aplicació. Abans de crear aquesta imatge, creeu un fitxer de configuració.
touch nginx/default.conf
Ara empleneu-lo amb aquest contingut.
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;
}
}
Tingueu en compte que a la fastcgi_pass php:9000línia estem fent referència al contenidor PHP pel seu nom dins del servicebloc del docker-compose.ymlfitxer de configuració. docker-composeCrea internament una xarxa i assigna el nom del servei com a nom d'amfitrió a cadascun dels serveis definits. Ara podem construir la imatge Nginx.
docker build -t vultr-nginx nginx/
Actualització docker-compose.yml
Ara actualitzeu el app/docker-compose.ymlfitxer.
version: '2'
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
web:
image: vultr-nginx
volumes:
- ./:/app
depends_on:
- php
ports:
- 80:80
Només hem afegit un nou servei. La configuració és gairebé la mateixa, excepte la següent.
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
La imatge oficial de MySQL us permet configurar el contenidor mitjançant simples variables d'entorn. Això es pot fer amb una environmentopció dins de la definició del bloc de servei. Actualitzeu el ~/docker/app/docker-compose.ymlfitxer al següent.
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:
Ara hem definit un nou servei per a la base de dades. Observeu la línia dbdata:/var/lib/mysql. Això munta el camí del contenidor /var/lib/mysqla un volum persistent gestionat per Docker, d'aquesta manera les dades de la base de dades persisteixen després d'eliminar el contenidor. Aquest volum s'ha de definir en un bloc de nivell superior com podeu veure al final del fitxer.
Abans d'orquestrar la nostra nova configuració, descarreguem una base de dades MySQL de mostra. La documentació oficial de MySQL
proporciona algunes bases de dades d'exemple. Farem servir la coneguda base de dades mundial. Aquesta base de dades proporciona una llista de països i ciutats. Per descarregar aquesta mostra, executeu el següent dins de la carpeta de l'aplicació.
curl -L http://downloads.mysql.com/docs/world.sql.gz -o world.sql.gz
gunzip world.sql.gz
Ara anem a orquestrar els nostres contenidors.
docker-compose up -d
Com potser ja heu notat, l' docker-compose upordre inicia només els contenidors que encara no s'han iniciat. Comprova les diferències entre el vostre docker-compose.ymlfitxer i la configuració actual dels contenidors en execució.
Una vegada més, comproveu que el contenidor MySQL s'ha iniciat.
docker ps
Ara ompliu la base de dades mundial.
docker-compose exec -T mysql mysql -uroot -proot world < world.sql
Podeu verificar que la base de dades s'ha emplenat seleccionant dades directament de la base de dades. Primer accediu al missatge de MySQL dins del contenidor.
docker-compose exec mysql mysql -uroot -proot world
A l'indicador de MySQL, executeu el següent.
select * from city limit 10;
Veureu una llista de ciutats. Ara sortiu del missatge de MySQL.
mysql> exit
Construint la nostra aplicació
Ara que tots els contenidors necessaris estan en funcionament, podem centrar-nos en la nostra aplicació de mostra. Actualitzeu el
app/index.phpfitxer al següent.
<?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>
Si accediu [vultr-instance-ip]en un navegador web, veureu una llista de les ciutats més poblades del món. Enhorabona, heu desplegat una aplicació PHP que funciona completament mitjançant Docker.
Conclusió
En aquest tutorial, he demostrat pas a pas com es configura una aplicació PHP que funcioni completament. Hem creat imatges personalitzades per a PHP i Nginx i hem configurat docker-compose per orquestrar els nostres contenidors. Tot i ser molt bàsica i senzilla, aquesta configuració reflecteix un escenari de la vida real.
En aquesta guia, hem creat i etiquetat les nostres imatges localment. Per a una configuració més flexible, podeu enviar aquestes imatges a un registre docker . Podeu enviar el registre oficial de docker o fins i tot configurar el vostre propi registre docker. En qualsevol cas, això us permetrà crear les vostres imatges en un host i utilitzar-les en un altre.
Per a un ús més detallat de docker-compose, hauríeu de consultar la documentació oficial .
Depenent dels requisits de l'aplicació i del marc PHP que utilitzeu, és possible que vulgueu afegir més extensions. Això es pot fer fàcilment modificant el que Dockerfiles'utilitza per crear la nostra imatge PHP personalitzada. Tanmateix, algunes extensions necessiten dependències addicionals per instal·lar-se al contenidor. Heu de consultar la llista d'extensions a la
documentació oficial de PHP per revisar els requisits bàsics de cada extensió.