使用Docker-compose部署PHP应用程序

PHP应用程序通常由Web服务器,关系数据库系统和语言解释器本身组成。在本教程中,我们将使用docker利用完整的PHP应用程序堆栈。这是一个深入的教程,我们将在其中构建和编排Nginx(Web服务器),MySQL(数据库系统)和PHP的容器。

为了本教程的缘故,我们将编写一个简单的应用程序,该应用程序从数据库中读取城市列表并将其显示在网页上,以此方式,我们将演示一个基本但有效的PHP应用程序。

本指南假定您已经安装了Docker-CE,并且至少对Docker有所了解。为此,您可以查看以下教程:

配置我们的工作环境

现实生活中基于docker的应用程序通常将由多个容器组成。手动管理这些内容很容易变得麻烦和麻烦。这就是docker-compose发挥作用的地方。它可以帮助您通过一个简单的yaml配置文件来管理多个容器。

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

创建一个文件夹来保存此示例的所有必需文件,然后cd将其放入其中。从现在开始,这是我们的工作目录,每个命令都将在此文件夹中执行,并且每个路径都将相对于它进行引用。以后可以将该文件夹引用为WORKING_DIR

mkdir ~/docker
cd ~/docker

现在再创建三个文件夹。

mkdir php nginx app

在该php文件夹中,我们将构建我们的自定义PHP映像,该nginx文件夹将保存我们的自定义nginx图像所需的文件,并且该app文件夹是我们将放置示例应用程序的源代码和配置的位置。

配置PHP容器

在此示例中,我们将php-fpm用于连接到Nginx Web服务器。我们将使用官方的PHP基本映像。但是,我们还需要安装并启用一些扩展,以便我们可以访问数据库。在php文件夹内创建一个名为的文件Dockerfile,并将以下内容放入其中。

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

请注意,我们使用的是官方PHP映像的Alpine版本。Alpine是一种面向容器的极小发行版,它提供的占地面积小得多。另外,请注意命令的使用docker-php-ext-install,官方的PHP映像提供了此命令,以简化安装和配置PHP扩展的过程。

现在,让我们通过发布以下代码(在我们的内部WORKING_DIR)来构建该Docker映像:

docker build -t vultr-php php/

docker-compose.yml文件

如前所述,docker-compose您可以通过一个简单的配置文件来管理多个容器。此配置文件通常名为docker-compose.yml。在app文件夹中创建此文件。

touch app/docker-compose.yml

现在将以下内容放入该文件。

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

我们将解释这种语法。首先,请注意第一行。

version: '2'

这指定docker-compose.yml使用的配置文件的版本。下一行指定服务,即要配置的容器。

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

请注意,每个服务在services块内都有一个特定的密钥。此处指定的名称将在以后用于引用此特定容器。还要注意,在php配置内部,我们定义了用于运行容器的映像(这是我们之前构建的映像)。我们还定义了一个体积映射。

volumes:
  - ./:/app

这告诉docker-compose将当前目录(./)映射到/app容器内的目录。最后一行将/app容器内的文件夹设置为工作目录,这意味着默认情况下将在此文件夹中执行容器内所有将来的命令。

现在,我们可以编排容器。

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

您可以运行以下命令以确保已执行PHP容器:

docker ps

如何在容器内执行命令

仍然在app文件夹内,我们可以在命令的帮助下在定义的服务容器内运行任何docker-compose命令。

docker-compose exec [service] [command]

[service]占位符是指服务的关键。在我们的例子中,这是php。让我们在容器内运行命令以检查我们的PHP版本。

docker-compose exec php php -v

您将看到以下输出。

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

配置Nginx容器

就像PHP容器一样,我们需要为Web服务器创建一个自定义图像。但是在这种情况下,我们只需要为我们提供一个配置即可virtual host。确保您在我们的文件夹中,WORKING_DIRDockerfilenginx文件夹中创建一个文件夹:

cd ~/docker
touch nginx/Dockerfile

现在将以下内容放入其中Dockerfile

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

我们正在使用基于Alpine的默认Nginx图像。在此Docker文件上,我们只需将配置文件复制到我们的应用程序设置中即可。构建此映像之前,请创建一个配置文件。

touch nginx/default.conf

现在,用此内容填充它。

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

请注意,在这一fastcgi_pass php:9000行中,我们通过配置文件service块内的名称引用PHP容器docker-compose.yml。在内部docker-compose创建一个网络,并将服务名称作为主机名分配给定义的每个服务。现在,我们可以构建Nginx图像。

docker build -t vultr-nginx nginx/

更新中 docker-compose.yml

现在更新app/docker-compose.yml文件。

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

我们仅添加了一项新服务。除了以下内容外,其他配置几乎相同。

depends_on:
  - php
ports:
  - 80:80

一旦Nginx容器需要完全初始化PHP服务,我们将在depends_on选项中强制执行此要求。该ports配置的关键主机端口映射到一个集装箱港口,在这里,我们的端口映射80在主机的端口80在容器中。

现在,在文件夹index.php内创建一个名为的app文件,并将以下内容放入其中。

<?php phpinfo();

确保80可通过防火墙访问该端口,然后执行以下操作。

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

再次仔细检查服务是否启动。

docker ps

打开浏览器并访问[vultr-instance-ip]。您可以通过运行以下命令找到Vultr实例的IP地址。

hostname -I

您将看到PHP信息页面。

配置MySQL容器

官方的MySQL映像允许您通过简单的环境变量配置容器。这可以通过environment服务块定义中的选项来完成。将~/docker/app/docker-compose.yml文件更新为以下内容。

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:

现在,我们为数据库定义了一项新服务。注意这一行dbdata:/var/lib/mysql。这会将容器上的路径安装/var/lib/mysql到Docker管理的持久卷上,这样,在删除容器后数据库数据将继续存在。如您在文件末尾所见,该卷需要在顶级块中定义。

在编排新配置之前,让我们下载一个示例MySQL数据库。在MySQL官方文档 提供了一些示例数据库。我们将使用著名的世界数据库。该数据库提供了国家和城市的列表。要下载此示例,请在我们的应用文件夹中执行以下操作。

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

现在,让我们编排容器。

docker-compose up -d

您可能已经注意到,该docker-compose up命令仅启动尚未启动的容器。它检查docker-compose.yml文件与正在运行的容器的当前配置之间的差异。

再过一遍,检查MySQL容器是否已启动。

docker ps

现在填充世界数据库。

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

您可以通过直接从数据库中选择数据来验证是否已填充数据库。首先访问容器内的MySQL提示符。

docker-compose exec mysql mysql -uroot -proot world

在MySQL提示符下,运行以下命令。

select * from city limit 10;

您将看到城市列表。现在退出MySQL提示符。

mysql> exit

建立我们的应用程序

现在,所有必需的容器都已启动并运行,我们可以集中精力研究示例应用程序。将app/index.php文件更新 为以下内容。

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

如果您使用[vultr-instance-ip]网络浏览器进行访问,则会看到世界上人口最多的城市的列表。恭喜,您已经使用docker部署了一个可以正常运行的PHP应用程序。

结论

在本教程中,我逐步演示了如何配置一个完全正常运行的PHP应用程序。我们为PHP和Nginx构建了自定义映像,并配置了docker-compose来协调我们的容器。尽管非常基本和简单,但此设置反映了现实生活中的情况。

在本指南中,我们已在本地构建并标记了图像。为了更灵活的设置,您可以将这些映像推送到docker Registry。您可以推送到官方Docker注册表,甚至可以设置自己的Docker注册表。无论如何,这将使您可以在一台主机上构建映像,并在另一台主机上使用它们。

有关的更详细用法docker-compose,请参考官方文档

根据您的应用程序要求和使用的PHP框架,您可能需要添加更多扩展。这可以通过修改Dockerfile用于构建自定义PHP映像的轻松完成。但是,某些扩展需要在容器中安装其他依赖项。您应该参考PHP官方文档中的扩展列表, 以查看每个扩展的基本要求。

留下評論

在Arch Linux上使用Makepkg

在Arch Linux上使用Makepkg

在Arch Linux上使用Makepkg可以避免系统污染,确保仅安装必要的依赖关系。

如何在Ubuntu 16.04上安装OpenSIPS控制面板

如何在Ubuntu 16.04上安装OpenSIPS控制面板

快速学习如何在Ubuntu 16.04上安装OpenSIPS控制面板,为VoIP提供商提供支持的功能。

在Fedora 28上安装Akaunting

在Fedora 28上安装Akaunting

学习如何在Fedora 28上安装Akaunting,一款适合小型企业和自由职业者的开源会计软件。

如何在CentOS 7上安装Mailtrain新闻通讯应用程序

如何在CentOS 7上安装Mailtrain新闻通讯应用程序

使用其他系统?Mailtrain是一个基于Node.js和MySQL / MariaDB构建的开源自托管新闻通讯应用程序。

诊断Minecraft服务器延迟和低TPS

诊断Minecraft服务器延迟和低TPS

了解導致Minecraft延遲的原因和解決方案,包括優化伺服器性能和減少滯後的步驟。

AI 能否應對越來越多的勒索軟件攻擊?

AI 能否應對越來越多的勒索軟件攻擊?

勒索軟件攻擊呈上升趨勢,但人工智能能否幫助應對最新的計算機病毒?AI 是答案嗎?在這裡閱讀知道是 AI 布恩還是禍根

ReactOS:這是 Windows 的未來嗎?

ReactOS:這是 Windows 的未來嗎?

ReactOS,一個開源和免費的操作系統,這裡有最新版本。它能否滿足現代 Windows 用戶的需求並打倒微軟?讓我們更多地了解這種老式但更新的操作系統體驗。

通過 WhatsApp 桌面應用程序 24*7 保持聯繫

通過 WhatsApp 桌面應用程序 24*7 保持聯繫

Whatsapp 終於為 Mac 和 Windows 用戶推出了桌面應用程序。現在您可以輕鬆地從 Windows 或 Mac 訪問 Whatsapp。適用於 Windows 8+ 和 Mac OS 10.9+

人工智能如何將流程自動化提升到新的水平?

人工智能如何將流程自動化提升到新的水平?

閱讀本文以了解人工智能如何在小型公司中變得流行,以及它如何增加使它們成長並為競爭對手提供優勢的可能性。

macOS Catalina 10.15.4 補充更新引發的問題多於解決

macOS Catalina 10.15.4 補充更新引發的問題多於解決

最近,Apple 發布了 macOS Catalina 10.15.4 補充更新以修復問題,但似乎該更新引起了更多問題,導致 mac 機器變磚。閱讀這篇文章以了解更多信息