1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GAE Flexでphp + phalcon + CloudSQLの環境を構築する

Last updated at Posted at 2018-12-12

Google Cloud Platform その2 Advent Calendar 2018の13日目の投稿です

次案件ではAWSではなくGCP(Google Cloud Platform)を使うことになり、
GAE(Google App Engine)で環境を構築してます。

前提条件として
GCPのGAEAPIの有効化とCloudSQLにDBを作成していることとします。
ここら辺は特にハマる場所もないかとおもいます。

フォルダ構成

新構成(抜粋)

app.yaml
composer.json
cron.yaml
nginx-app.conf
php.ini
source/
└ public/
 └ info.php
vendor/
└ autoloader.php

app.yaml

app.yaml
env: flex

# サービス名
service: "default"

# ランタイムPHP(デフォルトは7.1が指定される)
runtime: php

# unix_socketソケット
beta_settings:
  cloud_sql_instances: [project_name]:asia-northeast1:[mysqlインスタンス名]

# ドキュメントルート
runtime_config:
  document_root: source/public
  enable_stackdriver_integration: true  //stack_driverの許可

# ビルド必要のないファイルがある場合は指定
skip_files:

# 並列処理の許可
threadsafe: true

# 環境変数
env_variables:
  MYSQL_USER: '****'
  MYSQL_PASSWORD: '********'
  MYSQL_DSN: '/cloudsql/[project_name]:asia-northeast1:[mysqlインスタンス名]'

※変更箇所は適宜書き換えてください

compose.json

composer.json
{
    "require": {
        "php": "7.0.*",
        "google/cloud-logging": "^1.11",
        "google/cloud-error-reporting": "^0.10.0",
        "ext-yaml": "*"
    }
}

phalconは現在php7.0でしか対応されていないため、バージョン指定します
yamlを使いたいのでextensionを読み込ませます

nginx-app.conf

nginx-app.conf
    location / {
        try_files $uri $uri/ /index.php?_url=$uri&$args;
    }

    location ~ \.php {
        fastcgi_pass localhost:9000;
        fastcgi_index /index.php;

        include fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }

php.ini

php.ini
extension=phalcon.so

これでphalconextensionが使えるようになります。

info.php

public/info.php
<?php
phpinfo(); 

反映

$ gcloud app deploy

phpinfoの確認

https://[project_name].appspot.com/info.php
にアクセスしてみましょう

181203-0001.png
181203-0002.png
181203-0003.png

ハマりやすい場所

DB接続時にNo such file or directoryって言われる

app.yamlに記載されている

MYSQL_DSN: '/cloudsql/[project_name]:asia-northeast1:[mysqlインスタンス名]'

を接続情報として記載していますが、そもそも作られたコンテナに/cloudsql/[project_name]:asia-northeast1:[mysqlインスタンス名]ファイルが存在しなくてはお話になりません

このファイルが存在しているかを確認します

コンソール上からインスタンスに入ります
181203-0004-2.png

181203-0005.png

VMへのSSH接続を押すとインスタンスにはいれます

コンテナに入る

プロセスを確認して見るとNAMESに記載されている「gaeapp」と言うコンテナ名だとわかります

$ docker ps
CONTAINER ID        IMAGE                                                                                                                           COMMAND                  CREATED             STATUS              PORTS                                                                  NAMES
6a6888acd69a        asia.gcr.io/[project_name]/appengine/default.20181127t164715@sha256:9da1cd92a7ed1b616bd76c700a67406483877a12c0884e4a007f6f872759fc05   "/usr/bin/supervis..."   6 days ago          Up 6 days           172.17.0.1:8080->8080/tcp                                              gaeapp
a55365a7197c        gcr.io/google-appengine/cloud-sql-proxy                                                                                         "/cloud_sql_proxy ..."   6 days ago          Up 6 days                                                                                  cloudsql
42609bb8968f        gcr.io/google-appengine/api-proxy                                                                                               "/proxy"                 6 days ago          Up 6 days                                                                                  api
d12fd39d166e        gcr.io/google-appengine/nginx-proxy                                                                                             "/var/lib/nginx/bi..."   6 days ago          Up 6 days           8080/tcp, 0.0.0.0:8443->8443/tcp, 8090/tcp, 0.0.0.0:10402->10402/tcp   nginx_proxy
9e6594b862d8        gcr.io/google-appengine/iap-watcher                                                                                             "./start_iap_watch..."   6 days ago          Up 6 days                                                                                  iap_watcher
71b8c45c76e0        gcr.io/google-appengine/fluentd-logger                                                                                          "/opt/google-fluen..."   6 days ago          Up 6 days                                                                                  fluentd_logger

gaeappコンテナ入り対象ファイルを確認します

$ docker exec -it gaeapp /bin/bash
root@6a6888acd69a:/app# cd /cloudsql/
root@6a6888acd69a:/cloudsql# ls -la
total 8
drwxr-xr-x 2 root root 4096 Nov 27 07:52 .
drwxr-xr-x 1 root root 4096 Nov 27 07:52 ..
srwxrwxrwx 1 root root    0 Nov 27 07:52 [project_name]:asia-northeast1:[DBインスタンス名]
root@6a6888acd69a:/cloudsql# 

これがない場合はAPIが有効化になっていない可能性が高いので
https://console.cloud.google.com/apis/api/sqladmin.googleapis.com/overview?project=raharu-project-3&authuser=0&duration=PT1H
で有効化されているか確認してください

php_network_getaddresses: getaddrinfo failed: Name or service not knownと言われる

この場合はFW側から生成している接続形式がおかしい場合があります

エラーを見ると

#0 [internal function]: PDO->__construct('mysql:host=mysq...', 'root', '*******', Array)

となっており、接続形式がまちがっています
mysql:host=mysq...省略されていますが、hostでは繋げません
mysql:unix_socket=/cloudsql/[project_name]:asia-northeast1:[DBインスタンス名]になるようにソースを変更します
(この形式になるようになんとかする全FW共通)

Phalconの場合

apps/config/services.php
$di->set('base_master', function () use ($config) {
    return new DbAdapter(array(
        'unix_socket' => $config->mysql_base_master->host,
        'username' => $config->mysql_base_master->username,
        'password' => $config->mysql_base_master->password,
        'dbname' => $config->mysql_base_master->dbname,
    ));
});
/app/config/config.php
    'mysql_base_master' => array(
        'adapter'     => 'Mysql',
        'host'        => getenv('MYSQL_DSN'),
        'username'    => getenv('MYSQL_USER'),
        'password'    => getenv('MYSQL_PASSWORD'),
        'dbname'      => '[db_name]',
        'charset'     => 'utf8',
    ),

自分の場合は環境差分を考えて、DbAdapterのkey部分も設定ファイルに落とし込んでいます

YAMLエクステンションの有効化について

composerのインストールを行う際にext-yamlはローカル環境ではyamlを先にインストールしておかないとextensionを引っ張ってこれずにインストールエラーになります、そのためあらかじめローカル環境でpeclからyamlをインストールしておく必要があります。(プロジェクトにyamlファイルを使わない場合は必要ありません)

Phalconのバージョンについて

現在提供されているphalconのバージョンは3.0.4です、
このバージョンのZephirにはExceptionを2重にスローされてしまうバグがあり、
PhalconのBeforeExptionでエラーハンドリングをした場合に問題が発生してしまい、
自分はここでかなり苦戦しました、一旦の解決だけを見るのであればpublic/index.phpでキャッチしたExceptionをごにょごよすればできますが、マルチモジュール構成にしている場合はちょっと困ったことになります。

Phalcon >= 3.2以上の対応が待たれます

まとめ

GAE Flexは複数のデプロイ方式にも対応されており、マシンスペックアップやスケーリングも容易にできます。
設定もapp.yamlに統一されており、本番環境で使用するにも十分に耐えうる環境だと思います。

インフラエンジニアがいない小さな会社や個人開発の場合非常に強い味方になってくれるはずです。

今後ともGCPもといGAEの発展にさらに期待しています

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?