---
title: "本番環境でのデプロイ"
description: "このチュートリアルでは、Docker Composeを使用して単一サーバーにPHPアプリケーションをデプロイする方法を学びます。"
sidebar:
  label: "本番環境でのデプロイ"
  order: 1
---
Symfonyを使用している場合は、FrankenPHPを使用しているSymfony Dockerプロジェクトの「[本番環境へのデプロイ](https://github.com/dunglas/symfony-docker/blob/main/docs/production.md)」ドキュメントを参照してください。

API Platform（FrankenPHPも使用）を使用している場合は、[フレームワークのデプロイドキュメント](https://api-platform.com/docs/deployment/)を参照してください。

## アプリの準備

まず、PHPプロジェクトのルートディレクトリに`Dockerfile`を作成します：

```dockerfile
FROM dunglas/frankenphp

# "your-domain-name.example.com" を実際のドメイン名に置き換えてください
ENV SERVER_NAME=your-domain-name.example.com
# HTTPSを無効にしたい場合は、次の値を代わりに使用してください：
#ENV SERVER_NAME=:80

# プロジェクトで "public" ディレクトリをWebルートとして使用していない場合、ここで設定できます:
# ENV SERVER_ROOT=web/

# PHPの本番設定を有効化
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# プロジェクトのPHPファイルをpublicディレクトリにコピー
COPY . /app/public
# Symfony や Laravel を使用している場合は、代わりにプロジェクト全体をコピーする必要があります：
#COPY . /app
```

より詳細な情報やカスタマイズ方法、PHP拡張モジュールやCaddyモジュールのインストール方法については、
「[カスタムDockerイメージのビルド](/ja/docs/docker)」を参照してください。

プロジェクトでComposerを使用している場合は、
DockerイメージにComposerを含め、依存関係をインストールしてください。

次に、 `compose.yaml` ファイルを追加します：

```yaml
services:
  php:
    image: dunglas/frankenphp
    restart: always
    ports:
      - "80:80" # HTTP
      - "443:443" # HTTPS
      - "443:443/udp" # HTTP/3
    volumes:
      - caddy_data:/data
      - caddy_config:/config

# Caddyの証明書と設定に必要なボリューム
volumes:
  caddy_data:
  caddy_config:
```

<div class="fp-callout" data-callout="note">
<p class="fp-callout-title">注記</p>

上記の例は本番環境向けです。
開発環境では、ボリューム、異なるPHP設定、`SERVER_NAME`環境変数の異なる値を使用したい場合があります。

[Symfony Docker](https://github.com/dunglas/symfony-docker)プロジェクト（FrankenPHPを使用）では、
マルチステージイメージ、Composer、追加のPHP拡張モジュールなどを活用した、
より高度な例を見ることができます。

</div>

最後に、Gitを使用している場合は、これらのファイルをコミットしてプッシュします。

## サーバーの準備

本番環境にアプリケーションをデプロイするには、サーバーが必要です。
このチュートリアルではDigitalOceanの仮想マシンを使用しますが、他のLinuxサーバーでも同様に動作します。
DockerがインストールされたLinuxサーバーが既にある場合は、[次のセクション](#ドメイン名の設定)に進んでください。

まだサーバーがない場合は、[このアフィリエイトリンク](https://m.do.co/c/5d8aabe3ab80)を使用して$200の無料クレジットを取得し、アカウントを作成してください。その後、「Create a Droplet」をクリックします。
次に、「Choose an image」セクションの下の「Marketplace」タブをクリックし、「Docker」という名前のアプリを検索します。
これにより、DockerとDocker Composeの最新バージョンが既にインストールされたUbuntuサーバーがプロビジョニングされます！

テスト目的であれば、最安のプランで十分です。
実際の本番使用では、おそらくニーズに合わせて「general purpose」セクションのプランを選びたいでしょう。

![FrankenPHPをDockerでDigitalOceanにデプロイ](/blume-assets/content/content/assets/digitalocean-droplet.png)

他の設定はデフォルトのままにするか、必要に応じて調整も可能です。
SSHキーを追加するかパスワードを作成することを忘れずに行い、「Finalize and create」ボタンをクリックしてください。

次に、Dropletがプロビジョニングされるまで数秒待ちます。
Dropletの準備ができたら、SSHを使用して接続します：

```console
ssh root@<droplet-ip>
```

## ドメイン名の設定

ほとんどの場合、サイトにドメイン名を関連付けたいでしょう。
まだドメイン名を所有していない場合は、レジストラーを通じて購入する必要があります。

次に、サーバーのIPアドレスを指すドメイン名のタイプ`A`のDNSレコードを作成します：

```dns
your-domain-name.example.com.  IN  A     207.154.233.113
```

DigitalOceanのドメインサービス（「Networking」 > 「Domains」）での例：

![DigitalOceanでのDNS設定](/blume-assets/content/content/assets/digitalocean-dns.png)

<div class="fp-callout" data-callout="note">
<p class="fp-callout-title">注記</p>

FrankenPHPがデフォルトで使用しているTLS証明書の自動生成サービスLet's Encryptは、IPアドレスの直接使用をサポートしていません。Let's Encryptを使用するにはドメイン名の使用が必須です。

</div>

## デプロイ

`git clone`や`scp`など、目的に合ったツールを使用してプロジェクトをサーバーにコピーします。
GitHubを使用している場合は、[deploy key](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys)の使用を検討してください。
deploy keyは[GitLabでもサポートされています](https://docs.gitlab.com/ee/user/project/deploy_keys/)。

Gitでの例：

```console
git clone git@github.com:<username>/<project-name>.git
```

プロジェクトディレクトリ（`<project-name>`）に移動し、本番モードでアプリを開始します：

```console
docker compose up --wait
```

サーバーが起動し、HTTPS証明書が自動的に生成されます。
`https://your-domain-name.example.com`にアクセスしてお楽しみください！

<div class="fp-callout" data-callout="caution">
<p class="fp-callout-title">注意</p>

Dockerはキャッシュレイヤーを持つ可能性があるため、各デプロイメントで正しいビルドを持っているか確認するか、キャッシュの問題を避けるために`--no-cache`オプションでプロジェクトを再ビルドしてください。

</div>

## リバースプロキシの背後で実行する

FrankenPHPがリバースプロキシまたはロードバランサー（例：Nginx、AWS ELB、Google Cloud LB）の背後で実行されている場合、Caddyが受信する`X-Forwarded-*`ヘッダーを信頼するように、Caddyfileで[`trusted_proxies`グローバルオプション](https://caddyserver.com/docs/caddyfile/options#trusted-proxies)を設定する必要があります：

```caddyfile
{
	servers {
		trusted_proxies static <your-IPs>
	}
}
```

`<your-IPs>`を必要に応じてプロキシの実際のIP範囲に置き換えてください。

さらに、PHPフレームワークもプロキシを信頼するように設定する必要があります。
例えば、Symfonyでは[`TRUSTED_PROXIES`環境変数](https://symfony.com/doc/current/deployment/proxies.html)を設定するか、Laravelでは[`trustedproxies`ミドルウェア](https://laravel.com/docs/trustedproxy)を設定します。

これらの両方の設定がない場合、`X-Forwarded-For`や`X-Forwarded-Proto`のようなヘッダーは無視され、HTTPS検出の誤りや不正なクライアントIPアドレスなどの問題を引き起こす可能性があります。

## 複数ノードへのデプロイ

複数のマシンクラスターにアプリをデプロイしたい場合は、提供されるComposeファイルと互換性のある[Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/)を
使用できます。
Kubernetesでデプロイするには、FrankenPHPを使用する[API Platformで提供されるHelmチャート](https://api-platform.com/docs/deployment/kubernetes/)をご覧ください。
