---
title: "Cloud RunにデプロイしたLaravelアプリケーションをCloud Schedulerで定期実行 | grasys blog"
url: "https://blog.grasys.io/post/tomatsuri/cloud-run-cloud-scheduler-laravel"
description: "こんにちは、tomatsuriです。 Cloud Schedulerを触ってみたいという衝動に駆られ、Cloud RunにLaravelアプリケーションをデプロイし、Cloud Schedulerで定期実行するサンプルを作成してみました。 Laravelアプリケーションの作成 まず、Cloud Schedulerから…"
---

# Cloud RunにデプロイしたLaravelアプリケーションをCloud Schedulerで定期実行

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[tomatsuri](/authors/tomatsuri/)
-   公開日：2021年5月14日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#Cloud Run](/tags/cloud-run/)[#cloud-scheduler](/tags/cloud-scheduler/)[#Laravel](/tags/laravel/)

![Cloud RunにデプロイしたLaravelアプリケーションをCloud Schedulerで定期実行](/_astro/og-image.DDSiu2Ny_XHpDd.webp)

こんにちは、tomatsuriです。

Cloud Schedulerを触ってみたいという衝動に駆られ、Cloud RunにLaravelアプリケーションをデプロイし、Cloud Schedulerで定期実行するサンプルを作成してみました。

## Laravelアプリケーションの作成

まず、Cloud Schedulerから定期的にアプリケーションが実行されていることを確認するために、`/batch`にGETリクエストをしたらログに“batch executed.“と出力するだけの簡単な機能を用意しておきます。

Cloud Runは標準出力に出力したログはCloud Loggingによって自動的に取得されるため[1](#user-content-fn-1)、Laravelから標準出力にログを出力するために`config/logging.php`のchannelsに以下を追加します。

Plain textcontent\_copy

```
'stdout' => [
    'driver' => 'monolog',
    'handler' => StreamHandler::class,
    'with' => [
        'stream' => 'php://stdout',
    ],
],
```

（Laravel8系を使用）

あとは環境変数のLOG\_CHANNELをstdoutに書き換えればOKです。 環境変数はCloud Run上で設定が可能です。[2](#user-content-fn-2)

## Dockerイメージの作成

以下のようなDockerfileをプロジェクトのルートに用意します。 Cloud RunにLaravelをデプロイする方法としてApacheを使用している例をいくつか見たので、 今回はnginxでやってみました。

Plain textcontent\_copy

```
FROM php:8.0-fpm-alpine

RUN apk add --no-cache nginx wget

RUN mkdir -p /run/nginx
COPY docker/nginx.conf /etc/nginx/nginx.conf

RUN mkdir -p /app
COPY . /app

RUN sh -c "wget http://getcomposer.org/composer.phar && chmod a+x composer.phar && mv composer.phar /usr/local/bin/composer"
RUN cd /app && \
    /usr/local/bin/composer install --no-dev

RUN chown -R www-data: /app

CMD sh /app/docker/startup.sh
```

nginx.confとstartup.shはこちら。 ドキュメント[3](#user-content-fn-3)に従い、PORT環境変数で定義されたポートをリッスンするように構成しています。

Plain textcontent\_copy

```
worker_processes  1;

events {
    worker_connections  1024;
}
http {
    include mime.types;
    keepalive_timeout 65;

    server {
        listen LISTEN_PORT default_server;
        server_name _;
        root /app/public;
        index index.php;
        charset utf-8;
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
        access_log /dev/stdout;
        error_log /dev/stderr;

        client_max_body_size 100m;

        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
        }
    }
}

daemon off;
```

Plain textcontent\_copy

```
#!/bin/sh

sed -i "s,LISTEN_PORT,$PORT,g" /etc/nginx/nginx.conf

php-fpm -D

nginx
```

startup.shは`chmod a+x docker/startup.sh`でパーミッションを変更しておきます。

これらはプロジェクトのルートにdockerフォルダを作成し、その中に配置しています。

Dockerfile、nginx.conf、startup.shが用意できたら`docker build -t laravel-batch01 .` を実行してビルドします。

ビルドが完了したら、`docker run -e PORT=80 -p 8080:80 laravel-batch01`で起動し、localhost:8080でアクセスして確認してみましょう。

## Container Registryへイメージをpush

まずはビルドしたイメージにレジストリ名をタグ付けします。[4](#user-content-fn-4)

`docker tag laravel-batch01 asia.gcr.io/[PROJECT-ID]/laravel-batch01`

次に、Container Registryへアクセスするための認証を行います。今回は推奨とされているgcloud 認証情報ヘルパーを使用します。[5](#user-content-fn-5)

ユーザーまたはサービスアカウント（推奨）で認証を行い、`gcloud auth configure-docker`でgcloudをDockerの認証ヘルパーとして設定します。

これでタグ付きイメージをContainer Registryにpushできるようになりました。

`docker push asia.gcr.io/[PROJECT-ID]/laravel-batch01`

でpushし、Cloud ConsoleのContainer Registry上で確認できればOKです。

## Cloud Runを作成

laravel-batch01という名前のCloud Run サービスを作成します。

Cloud Console上でCloud Runのページにアクセスし、サービスの作成へ進みます。

![Cloud Runを作成の画面（1）](/_astro/01-04-4-1024x1011-0c427855.9emMgEsr_VxEmz.webp)

「サービスの最初のリビジョンの構成」のコンテナイメージのURLは、先程pushしたイメージを選択します。

Container Registryのイメージ詳細から直接作成することも可能です。

![Cloud Runを作成の画面（2）](/_astro/02-05-4-0f987357.D2HET1cC_1CMgDq.webp)

最後の「このサービスをトリガーする方法の構成」では、 Ingressは「すべてのトラフィックを許可する」を選択します。

現時点(2021/05/14)ではCloud Schedulerから内部サービスに対してhttpリクエストすることはできません。[6](#user-content-fn-6)

認証は「認証を必要とする」を選択し、作成します。

![Cloud Runを作成の画面（3）](/_astro/03-06-4-1024x864-36062c98.C1r9jEYC_2m8SwU.webp)

## Cloud SchedulerからCloud Runを起動するためのサービスアカウントを作成

このままCloud SchedulerからCloud Runへhttpリクエストをしても、権限がなく失敗してしまいます。

そこで、作成したCloud Runを起動する権限を持つサービスアカウントを作成し、それを使用してCloud SchedulerからCloud Runへリクエストするように設定します。

ここではlaravel-batch01-invokerという名前のサービスアカウントを作成し、以下のコマンドで権限を付与します。

Plain textcontent\_copy

```
gcloud run services add-iam-policy-binding laravel-batch01 \
    --member=serviceAccount:[サービスアカウントのメールアドレス] \
    --role=roles/run.invoker
```

Cloud Run詳細ページの権限タブを開き、Cloud Run 起動元の権限を持つサービスアカウントが追加されていればOKです。

## Cloud Schedulerの設定

「ジョブを定義する」で名前、頻度（unix-cron形式）、タイムゾーンを設定します。

「ジョブのターゲットを構成する」で、どこにどのようなリクエストを送信するのかを設定します。 今回は以下のようになります。

-   ターゲットタイプ：HTTP
-   URL：Cloud Runにデプロイしたアプリケーションのエンドポイント
-   HTTPメソッド：GET

Authヘッダーは「OIDC トークンを追加」を選択し、先程作成したサービスアカウント(laravel-batch01-invoker)のメールアドレスを入力します。

![Cloud Schedulerの設定の画面](/_astro/04-07-2-1024x970-e49fa13b.BaQcQ4v0_ZJqtGc.webp)

「詳細設定を構成する」でリトライ回数などを設定できますが、今回はデフォルトのままにします。

ジョブを作成したら、ジョブが実行されるまで待ってもよいですし、「今すぐ実行」ボタンで任意のタイミングで実行することもできます。

## 実行結果

ジョブの結果が「成功」となり、Cloud Runのログにアプリケーションで実装したログのメッセージが出力されていれば完了です。

![実行結果の画面](/_astro/05-08-2-1024x167-ee054e45.B-vjsEb8_ZGF4qy.webp)

## おわり

Cloud Run、Cloud Schedulerを使用して手軽にバッチ処理のサンプルを作成できました。

ちなみにCloud Scheduler料金は実行単位ではなくジョブ単位です。

請求アカウント毎（プロジェクト毎ではない）に3ジョブの無料枠があり、課金対象となってもジョブあたり$0.10/月とお手頃です。

今後はCloud Schedulerのhttp以外のターゲットを使ってみたり、他のサービスを使用したバッチ処理のアーキテクチャなど色々試していけたらなと思います。

## 脚注

* * *

## Footnotes

1.  [Cloud Run ドキュメント ログの記録と表示 コンテナログを作成する](https://cloud.google.com/run/docs/logging?hl=ja#container-logs) [↩](#user-content-fnref-1)
    
2.  [Cloud Run ドキュメント 環境変数の使用](https://cloud.google.com/run/docs/configuring/environment-variables?hl=ja) [↩](#user-content-fnref-2)
    
3.  [Cloud Run ドキュメント コンテナポートの構成](https://cloud.google.com/run/docs/configuring/containers?hl=ja#configure-port) [↩](#user-content-fnref-3)
    
4.  [Container Registry ドキュメント ローカル イメージにレジストリ名でタグ付けする](https://cloud.google.com/container-registry/docs/pushing-and-pulling?hl=ja#tag_the_local_image_with_the_registry_name) [↩](#user-content-fnref-4)
    
5.  [Container Registry ドキュメント gcloud 認証情報ヘルパー](https://cloud.google.com/container-registry/docs/advanced-authentication?hl=ja#gcloud-helper) [↩](#user-content-fnref-5)
    
6.  [Cloud Run ドキュメント 内部サービスへのアクセス](https://cloud.google.com/run/docs/securing/ingress?hl=ja#internal-services) [↩](#user-content-fnref-6)
    

## この記事を書いた人

[![](/_astro/noicon.CTHOhNiB_Z24aAgM.webp)](/authors/tomatsuri/)

### [tomatsuri](/authors/tomatsuri/)

tomatsuriのプロフィールと執筆記事をご覧いただけます。

[プロフィールと記事一覧](/authors/tomatsuri/)