使用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官方文档中的扩展列表, 以查看每个扩展的基本要求。



Leave a Comment

在CentOS 7上使用Docker Swarm(CE)进行粘性会话

在CentOS 7上使用Docker Swarm(CE)进行粘性会话

使用其他系统?简介Docker Swarm将您的单个服务器转变为计算机集群,从而促进扩展,高可用性和扩展性。

通过iPXE安装Rancher OS

通过iPXE安装Rancher OS

Rancher OS是围绕Docker构建的非常轻量级的Linux发行版。操作系统本身的重量约为20MB。本教程将帮助您入门和运行

两种Docker图形化管理工具:DockerUI和Shipyard

两种Docker图形化管理工具:DockerUI和Shipyard

借助Vultr Docker应用程序,您可以轻松地在Vultr服务器实例上部署Docker。同时,您可以方便地进行Docker管理任务

在Ubuntu 18.04上安装Docker CE

在Ubuntu 18.04上安装Docker CE

简介Docker是一个应用程序,可让我们部署作为容器运行的程序。它是用流行的Go编程语言编写的

在RancherOS上安装Rancher Server

在RancherOS上安装Rancher Server

概述RancherOS是一个非常轻量级的操作系统(仅约60 MB),它以PID 0作为运行系统服务的方式运行系统Docker守护程序。

在CoreOS上,设置您自己的Docker注册表

在CoreOS上,设置您自己的Docker注册表

我们都知道并喜欢Docker,这是一个在多台机器上创建,管理和分发应用程序容器的平台。Docker Inc.提供服务

在Debian 9上安装Docker CE

在Debian 9上安装Docker CE

使用其他系统?简介Docker是一个允许在虚拟容器内部署软件的应用程序。它写在G

在Ubuntu 14.04上安全地部署和管理LXC容器

在Ubuntu 14.04上安全地部署和管理LXC容器

LXC容器(Linux容器)是Linux中的一种操作系统功能,可用于在单个主机上运行多个隔离的Linux系统。塞斯

如何使用Docker:创建第一个Docker容器

如何使用Docker:创建第一个Docker容器

本教程介绍了Docker入门的基础知识。我假设您已经安装了Docker。本教程中的步骤将适用于

使用Docker部署Node.js应用程序

使用Docker部署Node.js应用程序

本文将向您展示如何在Docker容器中部署Node应用程序。注意:本教程假定您已安装Docker并已阅读

Docker的负载均衡

Docker的负载均衡

在运行Web应用程序时,通常希望充分利用资源,而不必转换软件以使用多线程处理程序。

在CentOS 7上安装Rancher

在CentOS 7上安装Rancher

使用其他系统?简介Rancher是一个用于运行容器和构建私有容器服务的开源平台。牧场主是基地

CentOS 7上的Kubernetes入门

CentOS 7上的Kubernetes入门

Kubernetes是Google开发的开放源代码平台,用于跨服务器集群管理容器化应用程序。它以十年为基础

在Alpine Linux 3.9.0上创建Docker Swarm

在Alpine Linux 3.9.0上创建Docker Swarm

简介本指南将向您展示如何使用多个Alpine Linux 3.9.0服务器和Portainer创建和配置Docker群。请注意

在Debian 9上使用Docker Swarm(CE)进行粘性会话

在Debian 9上使用Docker Swarm(CE)进行粘性会话

使用其他系统?简介Docker Swarm将您的单个服务器转变为计算机集群。便于扩展,高可用性和

如何在CentOS 7上安装Harbor

如何在CentOS 7上安装Harbor

Harbor是一个开放源代码的企业级注册服务器,用于存储和分发Docker映像。Harbor扩展了开源Docker Distribution b

在CentOS 7上使用Kubeadm部署Kubernetes

在CentOS 7上使用Kubeadm部署Kubernetes

概述本文旨在帮助您立即建立Kubernetes集群并使用kubeadm运行。本指南将在以下位置部署两台服务器

使用Docker在CentOS 7上开始使用SQL Server 2017(MS-SQL)

使用Docker在CentOS 7上开始使用SQL Server 2017(MS-SQL)

前提条件Docker引擎1.8+。至少4GB的磁盘空间。至少4GB的RAM。步骤1.安装Docker为了安装SQL-Server,Docker mus

在Ubuntu 14.04上安装Docker

在Ubuntu 14.04上安装Docker

使用其他系统?Docker是一个允许部署作为容器运行的程序的应用程序。它是用流行的Go程序编写的

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 機器變磚。閱讀這篇文章以了解更多信息

大數據的13個商業數據提取工具

大數據的13個商業數據提取工具

大數據的13個商業數據提取工具

什麼是日誌文件系統,它是如何工作的?

什麼是日誌文件系統,它是如何工作的?

我們的計算機以稱為日誌文件系統的有組織的方式存儲所有數據。這是一種有效的方法,可以讓計算機在您點擊搜索時立即搜索和顯示文件。 https://wethegeek.com/?p=94116&preview=true

技術奇點:人類文明的遙遠未來?

技術奇點:人類文明的遙遠未來?

隨著科學的快速發展,接管了我們的大量工作,我們陷入無法解釋的奇點的風險也在增加。閱讀,奇點對我們意味著什麼。

洞察 26 種大數據分析技術:第 1 部分

洞察 26 種大數據分析技術:第 1 部分

洞察 26 種大數據分析技術:第 1 部分

2021 年人工智能對醫療保健的影響

2021 年人工智能對醫療保健的影響

過去幾十年,醫療保健領域的人工智能取得了巨大飛躍。因此,醫療保健中人工智能的未來仍在日益增長。