deploy
laravel

Deployerを使ってLaravelのenvファイルをデプロイする

はじめに

  • Deployerを使ってLaravelアプリケーションをデプロイする際に.envファイルの扱いに工夫が必要だったので内容をまとめておきます。
  • Deployerとはphp製のデプロイツールになります(capistranoのようなものです)

やりたいこと

  • デプロイ環境ごとに.envファイルを以下のようにつくっておき、デプロイ環境にあわせてそれぞれ有効になるようにします。
.env.development     # 開発環境
.env.staging         # 検証環境
.env.production      # 本番環境

問題点

  • Deployerにあらかじめ用意されているlaravelのrecipeを使ってデプロイする場合、以下の設定がされているので、プロジェクト内の.envファイルがsharedディレクトリにコピーされ、.envファイルとリンクされます。

      set('shared_files', [
        '.env',
      ])
    
  • ただし、はじめからプロジェクト内に.envファイルが存在しない場合、空の.envファイルが生成され、それがリンクされます

  • このため、sharedディレクトリにファイルがコピーされる前に環境にあわせた.envをファイルをプロジェクトディレクトリに生成しておく必要があります。

解決策

  • 上記の処理をDeployerのtaskとして定義して、sharedの処理が実行される前に実行されるように設定します
    • ただし、デプロイするごとに.envファイルが更新されないように、デプロイ実行時のオプションとして指定できるようにします
  • はじめにオプションの引数を定義します。
    • env-update=true のようにして指定します
option('env-update', null, InputOption::VALUE_OPTIONAL, 'update env file.');
  • taskを定義します
task('copy:env', function () {
    if (input()->hasOption('env-update')){
        $update = input()->getOption('env-update');
        if($update == 'true'){
            $stage = get('stage');
            $src = ".env.${stage}";
            $path = get('deploy_path');
            $shared_path = "${path}/shared";
            run("if [ -e $(echo ${shared_path}/.env ) ]; then cp {{release_path}}/${src} ${shared_path}/.env; fi");
            run("cp {{release_path}}/${src} {{release_path}}/.env");
        }
    }
});
  • deploy_pathは set('deploy_path', '/var/www/html')のように設定されていることを前提としています
  • 以下のようして recipe/laravel.phpdeploy:shared が実行される前に上記のタスクが実行されるようにしておきます
before('deploy:shared','copy:env');
  • あとは以下のようにしてデプロイを実行します
dep deploy production --env-update=true

最後に

  • Deployerには予めLaravel用のデプロイrecipeが用意されているので、簡単にデプロイ環境を構築出来てとても便利です!