検索
ホームページバックエンド開発PHPチュートリアルPHP プロジェクト開発環境での Docker の適用

この記事は、Wolong Pavilion の PHP と起業家精神に関する私のコラムで最初に公開されたものです。転載用に保管しておいてください。

環境の展開は、すべてのチームが直面しなければならない問題です。システムがますます大きくなるにつれて、次のような依存サービスが増えてきます。たとえば、現在のプロジェクトの 1 つは、

    を使用することになります。
  • Web サーバー: Nginx
  • Web プログラム: PHP + Node
  • データベース: MySQL
  • 検索エンジン: ElasticSearch
  • キュー サービス: Gearman
  • キャッシュ サービス: Redis + Memcache
  • フロントエンド ビルド ツール: npm + bower + gulp
  • PHP CLI ツール: Composer + PHPUnit

したがってその後、チームの開発環境の展開により、いくつかの問題が明らかになりました。

  • 依存するサービスが多く、ローカル環境を構築するコストがますます高くなっています。 若手スタッフが環境の展開に関するいくつかの問題を解決するのは困難です。
  • 🎜>
  • サービスのバージョンの違いや OS の違いにより、オンライン環境のバグが発生する可能性があります
  • プロジェクトで新しいサービスが導入されると、全員の環境を再構成する必要があります

    質問 1 については、Vagrant を使用できます-ベースの仮想マシン プロジェクトが解決され、チーム メンバーは一連の開発環境イメージを共有します。問題 2 については、PHPBrew のようなマルチバージョン PHP 管理ツールを導入することで解決できます。しかし、どちらも問題 3 を十分に解決することはできません。仮想マシン イメージにはバージョン管理の概念がないため、複数人でイメージを管理すると、構成漏れや競合が発生しやすくなり、大きなイメージを転送するのが不便になります。

    Docker の登場により、上記の問題に対するより良い解決策が提供されました。私は、実稼働環境への Docker の大規模な適用についてはまだ慎重ですが、テストと開発だけを考慮すると、Docker のコンテナ化は重要だと思います。このコンセプトはすでに、環境展開の問題を真に解決できる特効薬となっています。

    以下では、PHP プロジェクト開発環境の構築における Docker の進化について紹介します。この記事では、オペレーティング システムが Linux で、Docker がインストールされており、Docker とは何か、および Docker の基本的な使用方法をすでに理解していることを前提としています。コマンドライン この背景知識がない場合は、まず自分で理解することをお勧めします。

    Hello World

    まず、Docker コンテナー内の PHP の Hello World インスタンスから始めます。次のような PHP ファイル、index.php を準備します。
    <?phpecho "PHP in Docker";

    次に、同じディレクトリにテキスト ファイルを作成し、Dockerfile という名前を付けます。内容は次のとおりです。
    # 从官方PHP镜像构建FROM       php# 将index.php复制到容器内的/var/www目录下ADD        index.php /var/www# 对外暴露8080端口EXPOSE     8080# 设置容器默认工作目录为/var/wwwWORKDIR    /var/www# 容器运行后默认执行的指令ENTRYPOINT ["php", "-S", "0.0.0.0:8080"]

    このコンテナを構築します。
    docker build -t allovince/php-helloworld .

    このコンテナを実行します
    docker run -d -p 8080:8080 allovince/php-helloworld

    結果を表示します:
    curl localhost:8080PHP in Docker

    このようにして、PHP プログラムをデモするための Docker コンテナを作成しました。 Docker がインストールされているどのマシンでもこのコンテナを実行でき、同じ結果が得られます。上記の php ファイルと Dockerfile があれば誰でも同じコンテナを構築できるため、環境やバージョンの違いによって発生する可能性のあるさまざまな問題を完全に排除できます。

    プログラムがより複雑になると想像してください。どのように拡張すればよいでしょうか? 簡単なアイデアは、コンテナーに他の使用済みサービスをインストールし続け、すべてのサービスを実行することです。その場合、Dockerfile は次のような外観に発展する可能性があります。
    FROM       phpADD        index.php /var/www# 安装更多服务RUN        apt-get install -y \	mysql-server \	nginx \	php5-fpm \	php5-mysql# 编写一个启动脚本启动所有服务ENTRYPOINT ["/opt/bin/php-nginx-mysql-start.sh"]

    Docker で開発環境を構築しましたが、少し見慣れた感じがします。はい、実際、このアプローチは仮想マシン イメージの作成に似ています。このアプローチにはいくつかの問題があります。
    • PHP5.3 のテストなど、サービスの異なるバージョンを検証する必要がある場合。 / 5.4/5.5/5.6と4枚の画像を用意する必要がありますが、実はそれぞれの画像には小さな違いしかありません。
    • 新しいプロジェクトを開始すると、コンテナにインストールされているサービスがどんどん増えていき、最終的にはどのサービスがどのプロジェクトに属しているのか分からなくなります。

    単一のプロセス コンテナーを使用する

    すべてのサービスをコンテナーに配置する上記のモデルには、Fat Container という非公式の名前が付けられています。その逆は、サービスをコンテナに分割するパターンです。 Docker の設計から、イメージを構築するプロセス中に、コンテナーを起動するための独自の命令を指定できることがわかります。そのため、Docker は、1 つのコンテナーで 1 つのサービスのみを実行するのに当然適しており、これが関係者が好むことです。 。

    サービスを分割するときに最初に直面する問題は、各サービスの基本イメージがどこから来るのかということです。ここには 2 つのオプションがあります:

    オプション 1. 標準の OS イメージから拡張します。たとえば、以下はそれぞれ Nginx イメージと MySQL イメージです。
    FROM ubuntu:14.04RUN  apt-get update -y && apt-get install -y nginx
    FROM ubuntu:14.04RUN  apt-get update -y && apt-get install -y mysql

    このアプローチの利点は次のとおりです。サービスには統一された基本イメージを含めることができ、イメージを拡張および変更するときに同じ方法を使用できます。たとえば、ubuntu が選択されている場合は、apt-get コマンドを使用してサービスをインストールできます。

    問題は、多数のサービスを独自に保守する必要があること、特に特定のサービスの異なるバージョンが必要な場合、ソース コードを直接コンパイルする必要があり、デバッグと保守のコストがかかることです。とても高いです。

    オプション 2. Docker Hub から公式イメージを直接継承します。 以下も Nginx および MySQL イメージです。
    FROM nginx:1.9.0
    FROM mysql:5.6

    Docker Hub は、Docker の Github および Docker 公式とみなすことができます。一般的に利用されているサービス用の画像が多数ありますが、サードパーティから投稿された画像も多数あります。 Docker-Registry プロジェクトに基づいて、プライベート Docker Hub を短時間で構築することもできます。

    基于某个服务的官方镜像去构建镜像,有非常丰富的选择,并且可以以很小的代价切换服务的版本。这种方式的问题在于官方镜像的构建方式多种多样,进行扩展时需要先了解原镜像的Dockerfile。

    出于让服务搭建更灵活的考虑,我们选择后者构建镜像。

    为了分拆服务,现在我们的目录变为如下所示结构:

    ~/Dockerfiles├── mysql│   └── Dockerfile├── nginx│   ├── Dockerfile│   ├── nginx.conf│   └── sites-enabled│       ├── default.conf│       └── evaengine.conf├── php│   ├── Dockerfile│   ├── composer.phar│   ├── php-fpm.conf│   ├── php.ini│   ├── redis.tgz└── redis    └── Dockerfile

    即为每个服务创建单独文件夹,并在每个服务文件夹下放一个Dockerfile。

    MySQL容器

    MySQL继承自官方的 MySQL5.6镜像 ,Dockerfile仅有一行,无需做任何额外处理,因为普通需求官方都已经在镜像中实现了,因此Dockerfile的内容为:

    FROM mysql:5.6

    在项目根目录下运行

    docker build -t eva/mysql ./mysql

    会自动下载并构建镜像,这里我们将其命名为eva/mysql。

    由于容器运行结束时会丢弃所有数据库数据,为了不用每次都要导入数据,我们将采用挂载的方式持久化MySQL数据库,官方镜像默认将数据库存放在/var/lib/mysql,同时要求容器运行时必须通过环境变量设置一个管理员密码,因此可以使用以下指令运行容器:

    docker run -p 3306:3306 -v ~/opt/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -it eva/mysql

    通过上面的指令,我们将本地的3306端口绑定到容器的3306端口,将容器内的数据库持久化到本地的~/opt/data/mysql,并且为MySQL设置了一个root密码123456

    Nginx容器

    Nginx目录下提前准备了Nginx配置文件nginx.conf以及项目的配置文件default.conf等。Dockerfile内容为:

    FROM nginx:1.9ADD  nginx.conf      /etc/nginx/nginx.confADD  sites-enabled/*    /etc/nginx/conf.d/RUN  mkdir /opt/htdocs && mkdir /opt/log && mkdir /opt/log/nginxRUN  chown -R www-data.www-data /opt/htdocs /opt/logVOLUME ["/opt"]

    由于官方的 Nginx1.9 是基于Debian Jessie的,因此首先将准备好的配置文件复制到指定位置,替换镜像内的配置,这里按照个人习惯,约定/opt/htdocs目录为Web服务器根目录,/opt/log/nginx目录为Nginx的Log目录。

    同样构建一下镜像

    docker build -t eva/nginx ./nginx

    并运行容器

    docker run -p 80:80 -v ~/opt:/opt -it eva/nginx

    注意我们将本地的80端口绑定到容器的80端口,并将本地的~/opt目录挂载到容器的/opt目录,这样就可以将项目源代码放在~/opt目录下并通过容器访问了。

    PHP容器

    PHP容器是最复杂的一个,因为在实际项目中,我们很可能需要单独安装一些PHP扩展,并用到一些命令行工具,这里我们以Redis扩展以及Composer来举例。首先将项目需要的扩展等文件提前下载到php目录下,这样构建时就可以从本地复制而无需每次通过网络下载,大大加快镜像构建的速度:

    wget https://getcomposer.org/composer.phar -O php/composer.pharwget https://pecl.php.net/get/redis-2.2.7.tgz -O php/redis.tgz

    php目录下还准备好了php配置文件php.ini以及php-fpm.conf,基础镜像我们选择的是 PHP 5.6-FPM ,这同样是一个Debian Jessie镜像。官方比较亲切的在镜像内部准备了一个docker-php-ext-install指令,可以快速安装如GD、PDO等常用扩展。所有支持的扩展名称可以通过在容器内运行docker-php-ext-install获得。

    来看一下Dockerfile

    FROM php:5.6-fpmADD php.ini	/usr/local/etc/php/php.iniADD php-fpm.conf	/usr/local/etc/php-fpm.confCOPY redis.tgz /home/redis.tgzRUN docker-php-ext-install gd \	&& docker-php-ext-install pdo_mysql \	&& pecl install /home/redis.tgz && echo "extension=redis.so" > /usr/local/etc/php/conf.d/redis.iniADD composer.phar /usr/local/bin/composerRUN chmod 755 /usr/local/bin/composerWORKDIR /optRUN usermod -u 1000 www-dataVOLUME ["/opt"]

    在构建过程中做了这样一些事情:

  • 复制php和php-fpm配置文件到相应目录
  • 复制redis扩展源代码到/home
  • 通过docker-php-ext-install安装GD和PDO扩展
  • 通过pecl安装Redis扩展
  • 复制composer到镜像作为全局指令
  • 按照个人习惯,仍然设置/opt目录作为工作目录。

    这里有一个细节,在复制tar包文件时,使用的Docker指令是COPY而不是ADD,这是由于ADD指令会 自动解压tar文件 。

    现在终于可以构建+运行了:

    docker build -t eva/php ./phpdocker run -p 9000:9000 -v ~/opt:/opt -it eva/php

    在大多数情况下,Nginx和PHP所读取的项目源代码都是同一份,因此这里同样挂载本地的~/opt目录,并且绑定9000端口。

    PHP-CLI的实现

    php容器除了运行php-fpm外,还应该作为项目的php cli使用,这样才能保证php版本、扩展以及配置文件保持一致。

    例如在容器内运行Composer,可以通过下面的指令实现:

    docker run -v $(pwd -P):/opt -it eva/php composer install --dev -vvv

    这样在任意目录下运行这行指令,等于动态将当前目录挂载到容器的默认工作目录并运行,这也是PHP容器指定工作目录为/opt的原因。

    同理还可以实现phpunit、npm、gulp等命令行工具在容器内运行。

    Redis容器

    为了方便演示,Redis仅仅作为缓存使用,没有持久化需求,因此Dockerfile仅有一行

    FROM redis:3.0

    容器的连接

    上面已经将原本在一个容器中运行的服务分拆到多个容器,每个容器只运行单一服务。这样一来容器之间需要能互相通信。Docker容器间通讯的方法有两种,一种是像上文这样将容器端口绑定到一个本地端口,通过端口通讯。另一种则是通过Docker提供的 Linking功能 ,在开发环境下,通过Linking通信更加灵活,也能避免端口占用引起的一些问题,比如可以通过下面的方式将Nginx和PHP链接起来:

    docker run -p 9000:9000 -v ~/opt:/opt --name php -it eva/phpdocker run -p 80:80 -v ~/opt:/opt -it --link php:php eva/nginx

    在一般的PHP项目中,Nginx需要链接PHP,而PHP又需要链接MySQL,Redis等。为了让容器间互相链接更加容易管理,Docker官方推荐使用 Docker-Compose 完成这些操作。

    用一行指令完成安装

    pip install -U docker-compose

    然后在Docker项目的根目录下准备一个docker-compose.yml文件,内容为:

    nginx:    build: ./nginx    ports:      - "80:80"    links:      - "php"    volumes:      - ~/opt:/optphp:    build: ./php    ports:      - "9000:9000"    links:      - "mysql"      - "redis"    volumes:      - ~/opt:/optmysql:    build: ./mysql    ports:      - "3306:3306"    volumes:      - ~/opt/data/mysql:/var/lib/mysql    environment:      MYSQL_ROOT_PASSWORD: 123456redis:    build: ./redis    ports:      - "6379:6379"

    然后运行docker-compose up,就完成了所有的端口绑定、挂载、链接操作。

    更复杂的实例

    上面是一个标准PHP项目在Docker环境下的演进过程,实际项目中一般会集成更多更复杂的服务,但上述基本步骤仍然可以通用。比如 EvaEngine/Dockerfiles 是为了运行我的开源项目EvaEngine准备的基于Docker的开发环境,EvaEngine依赖了队列服务Gearman,缓存服务Memcache、Redis,前端构建工具Gulp、Bower,后端Cli工具Composer、PHPUnit等。具体实现方式可以自行阅读代码。

    经过团队实践,原本大概需要1天时间的环境安装,切换到Docker后只需要运行10余条指令,时间也大幅缩短到3小时以内(大部分时间是在等待下载),最重要的是Docker所构建的环境都是100%一致的,不会有人为失误引起的问题。未来我们会进一步将Docker应用到CI以及生产环境中。

    声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    誇大広告を超えて:今日のPHPの役割の評価誇大広告を超えて:今日のPHPの役割の評価Apr 12, 2025 am 12:17 AM

    PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

    PHPの弱い参照は何ですか、そしていつ有用ですか?PHPの弱い参照は何ですか、そしていつ有用ですか?Apr 12, 2025 am 12:13 AM

    PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

    PHPで__invoke Magicメソッドを説明してください。PHPで__invoke Magicメソッドを説明してください。Apr 12, 2025 am 12:07 AM

    \ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

    同時性については、PHP 8.1の繊維を説明します。同時性については、PHP 8.1の繊維を説明します。Apr 12, 2025 am 12:05 AM

    繊維はPhp8.1で導入され、同時処理機能が改善されました。 1)繊維は、コルーチンと同様の軽量の並行性モデルです。 2)開発者がタスクの実行フローを手動で制御できるようにし、I/O集約型タスクの処理に適しています。 3)繊維を使用すると、より効率的で応答性の高いコードを書き込むことができます。

    PHPコミュニティ:リソース、サポート、開発PHPコミュニティ:リソース、サポート、開発Apr 12, 2025 am 12:04 AM

    PHPコミュニティは、開発者の成長を支援するための豊富なリソースとサポートを提供します。 1)リソースには、公式のドキュメント、チュートリアル、ブログ、LaravelやSymfonyなどのオープンソースプロジェクトが含まれます。 2)StackOverFlow、Reddit、およびSlackチャネルを通じてサポートを取得できます。 3)開発動向は、RFCに従うことで学ぶことができます。 4)コミュニティへの統合は、積極的な参加、コード共有への貢献、および学習共有への貢献を通じて達成できます。

    PHP対Python:違いを理解しますPHP対Python:違いを理解しますApr 11, 2025 am 12:15 AM

    PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

    PHP:それは死にかけていますか、それとも単に適応していますか?PHP:それは死にかけていますか、それとも単に適応していますか?Apr 11, 2025 am 12:13 AM

    PHPは死にかけていませんが、常に適応して進化しています。 1)PHPは、1994年以来、新しいテクノロジーの傾向に適応するために複数のバージョンの反復を受けています。 2)現在、電子商取引、コンテンツ管理システム、その他の分野で広く使用されています。 3)PHP8は、パフォーマンスと近代化を改善するために、JITコンパイラおよびその他の機能を導入します。 4)Opcacheを使用してPSR-12標準に従って、パフォーマンスとコードの品質を最適化します。

    PHPの未来:適応と革新PHPの未来:適応と革新Apr 11, 2025 am 12:01 AM

    PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイラと列挙タイプを導入します。 3)パフォーマンスを継続的に最適化し、ベストプラクティスを促進します。

    See all articles

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    DVWA

    DVWA

    Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

    AtomエディタMac版ダウンロード

    AtomエディタMac版ダウンロード

    最も人気のあるオープンソースエディター

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    SublimeText3 英語版

    SublimeText3 英語版

    推奨: Win バージョン、コードプロンプトをサポート!

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    強力な PHP 統合開発環境