Konfigurering av arbeidsmiljøet vårt
Konfigurering av PHP-beholderen
Konfigurere Nginx-beholderen
Konfigurere MySQL-beholderen
Bygger vår applikasjon
Konklusjon
PHP-applikasjoner er vanligvis sammensatt av en webserver, et relasjonsdatabasesystem og selve språktolken. I denne opplæringen vil vi utnytte en full PHP-applikasjonsstabel ved hjelp av docker. Dette er en dybdeveiledning der vi skal bygge og orkestrere containere for Nginx (webserveren), MySQL (databasesystemet) og PHP.
For denne veiledningens skyld vil vi skrive en enkel applikasjon som leser en liste over byer fra en database og viser den på en nettside, på denne måten vil vi demonstrere en grunnleggende, men fungerende, PHP-applikasjon.
Denne veiledningen forutsetter at du har Docker-CE allerede installert og minst en minimal arbeidskunnskap om docker. For den saks skyld kan du se gjennom følgende opplæringsprogrammer:
Konfigurering av arbeidsmiljøet vårt
En virkelig docker-basert applikasjon vil typisk være sammensatt av flere containere. Å administrere disse manuelt kan lett bli ganske rotete og tungvint. Det er her docker-compose kommer inn i bildet. Det hjelper deg å administrere en rekke containere gjennom en enkel yaml
konfigurasjonsfil.
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
Opprett en mappe for å holde alle nødvendige filer i dette eksemplet og deretter cd
inn i den. Fra nå av er dette arbeidskatalogen vår, og hver kommando vil bli utført i denne mappen, og hver sti vil bli referert i forhold til den. Denne mappen kan bli referert til senere som WORKING_DIR
.
mkdir ~/docker
cd ~/docker
Lag tre mapper til.
mkdir php nginx app
Den php
mappen er der vi skal bygge vår skikk PHP bildet, nginx
vil mappen holde de nødvendige filene for våre gjester Nginx bildet og app
mappen er der vi vil være å sette kildekoden og konfigurasjon av vår prøveprogrammet.
Konfigurering av PHP-beholderen
I dette eksemplet skal vi bruke php-fpm
til å koble til Nginx-nettserveren. Vi vil bruke det offisielle PHP-basebildet. Vi må imidlertid også installere og aktivere noen utvidelser slik at vi kan få tilgang til databasen. php
Opprett en fil med navnet i mappen Dockerfile
og legg følgende innhold inn 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
Merk at vi bruker Alpine-versjonen av det offisielle PHP-bildet. Alpine er en veldig liten distribusjon rettet mot containere ved å gi mye mindre fotavtrykk. Legg også merke til bruken av kommandoen docker-php-ext-install
, det offisielle PHP-bildet gir denne kommandoen for å lette prosessen med å installere og konfigurere PHP-utvidelser.
La oss nå bygge dette Docker-bildet ved å utstede følgende (inne i vår WORKING_DIR
):
docker build -t vultr-php php/
den docker-compose.yml
filen
Som allerede nevnt, docker-compose
lar deg administrere en rekke containere gjennom en enkel konfigurasjonsfil. Denne konfigurasjonsfilen heter vanligvis docker-compose.yml
. Lag denne filen i app
mappen.
touch app/docker-compose.yml
Legg nå følgende innhold inn i denne filen.
version: '2'
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Vi vil forklare denne syntaksen. Legg først merke til den første linjen.
version: '2'
Dette spesifiserer versjonen av docker-compose.yml
konfigurasjonsfilen som brukes. Den neste linjen spesifiserer tjenestene, eller med andre ord, beholderne som skal klargjøres.
services:
php:
image: vultr-php
volumes:
- ./:/app
working_dir: /app
Merk at hver tjeneste har en spesifikk nøkkel inne i services
blokken. Navnet som er spesifisert her vil bli brukt til å referere til denne spesifikke beholderen senere. Merk også at inne i php
konfigurasjonen definerer vi bildet som brukes til å kjøre beholderen (dette er bildet vi bygde tidligere). Vi definerer også en volumkartlegging.
volumes:
- ./:/app
Dette forteller deg docker-compose
å kartlegge gjeldende katalog ( ./
) til /app
katalogen inne i beholderen. Den siste linjen setter /app
mappen inne i beholderen som arbeidskatalogen, noe som betyr at dette er mappen der alle fremtidige kommandoer i en beholder som standard utføres fra.
Vi kan nå orkestrere containerne våre.
cd ~/docker/app
docker-compose up -d
Du kan kjøre følgende kommando for å sikre at PHP-beholderen ble utført:
docker ps
Hvordan utføre kommandoer inne i containerne
Fortsatt inne i app
mappen kan vi kjøre en hvilken som helst kommando inne i en definert tjenestebeholder ved hjelp av docker-compose
kommandoen.
docker-compose exec [service] [command]
Den [service]
plassholder refererer til servicenøkkelen. I vårt tilfelle var dette php
. La oss kjøre en kommando inne i beholderen for å sjekke vår PHP-versjon.
docker-compose exec php php -v
Du vil se følgende utgang.
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
Konfigurere Nginx-beholderen
Akkurat som PHP-beholderen, må vi lage et tilpasset bilde for webserveren. Men i dette tilfellet trenger vi bare å gi en konfigurasjon for vår virtual host
. Sørg for at du er inne i vår WORKING_DIR
og lag en Dockerfile
inne i nginx
mappen:
cd ~/docker
touch nginx/Dockerfile
Legg nå følgende innhold inn i dette Dockerfile
:
FROM nginx:1.13.8-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Vi bruker standard Nginx-bilde basert på Alpine. På denne Docker-filen kopierer vi ganske enkelt en konfigurasjonsfil til applikasjonsoppsettet vårt. Før du bygger dette bildet, lag en konfigurasjonsfil.
touch nginx/default.conf
Fyll den nå med dette innholdet.
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;
}
}
Merk at på fastcgi_pass php:9000
linjen refererer vi til PHP-beholderen med dets navn inne i service
blokken til docker-compose.yml
konfigurasjonsfilen. docker-compose
Oppretter et nettverk internt og tildeler tjenestenavnet som vertsnavn til hver av tjenestene som er definert. Vi kan nå bygge Nginx-bildet.
docker build -t vultr-nginx nginx/
Oppdaterer docker-compose.yml
Oppdater nå 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 bare lagt til en ny tjeneste. Konfigurasjonen er nesten den samme, bortsett 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
The official MySQL image allows you to configure the container through simple environment variables. This can be done
with an environment
option inside the service block definition. Update the ~/docker/app/docker-compose.yml
file
to the following.
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:
Now we've defined a new service for the database. Notice the line dbdata:/var/lib/mysql
. This
mounts the path on the container /var/lib/mysql
to a persistent volume
managed by Docker, this way the database data persists after the container is removed. This
volume needs to be defined in a top-level block as you can see in the end of the file.
Før vi orkestrerer vår nye konfigurasjon, la oss laste ned et eksempel på en MySQL-database. Den offisielle MySQL-dokumentasjonen
gir noen eksempeldatabaser. Vi skal bruke den velkjente verdensdatabasen. Denne databasen gir en liste over land og byer. For å laste ned dette eksemplet, kjør følgende i app-mappen vår.
curl -L http://downloads.mysql.com/docs/world.sql.gz -o world.sql.gz
gunzip world.sql.gz
La oss nå orkestrere containerne våre.
docker-compose up -d
Som du kanskje allerede har lagt merke til, docker-compose up
starter kommandoen bare beholderne som ikke allerede er startet. Den ser etter forskjellene mellom docker-compose.yml
filen din og gjeldende konfigurasjon av kjørende containere.
En gang til, sjekk at MySQL-beholderen ble startet.
docker ps
Fyll nå verdensdatabasen.
docker-compose exec -T mysql mysql -uroot -proot world < world.sql
Du kan bekrefte at databasen ble fylt ut ved å velge data direkte fra databasen. Gå først til MySQL-ledeteksten inne i beholderen.
docker-compose exec mysql mysql -uroot -proot world
Kjør følgende i MySQL-ledeteksten.
select * from city limit 10;
Du vil se en liste over byer. Avslutt nå MySQL-ledeteksten.
mysql> exit
Bygger vår applikasjon
Nå som alle nødvendige beholdere er oppe og går, kan vi fokusere på prøveapplikasjonen vår. Oppdater
app/index.php
filen 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 åpner [vultr-instance-ip]
i en nettleser, vil du se en liste over de mest folkerike byene i verden. Gratulerer, du har distribuert en fullt fungerende PHP-applikasjon ved hjelp av docker.
Konklusjon
I denne opplæringen har jeg demonstrert trinn for trinn hvordan du konfigurerer en fullt fungerende PHP-applikasjon. Vi bygde tilpassede bilder for PHP og Nginx, og konfigurerte docker-compose for å orkestrere containerne våre. Til tross for at det er veldig grunnleggende og enkelt, gjenspeiler dette oppsettet et virkelighetsscenario.
I denne guiden har vi bygget og tagget bildene våre lokalt. For et mer fleksibelt oppsett kan du sende disse bildene til et docker-register . Du kan trykke til det offisielle docker-registeret eller til og med sette opp ditt eget docker-register. I alle fall vil dette tillate deg å bygge bildene dine på en vert og bruke dem på en annen.
For en mer detaljert bruk av docker-compose
, bør du se den offisielle dokumentasjonen .
Avhengig av applikasjonskravene dine og PHP-rammeverket du bruker, kan det være lurt å legge til flere utvidelser. Dette kan enkelt gjøres ved å endre det som Dockerfile
brukes for å bygge vårt tilpassede PHP-bilde. Noen utvidelser trenger imidlertid ekstra avhengigheter for å installeres i beholderen. Du bør se på listen over utvidelser i den
offisielle PHP-dokumentasjonen for å se de grunnleggende kravene til hver utvidelse.