Symfony4をHerokuにデプロイしてみる

 

Symfony Advent Calendar 2019の14日目です。(間に合わすつもりでしたが、過ぎてしまいました…)

 

ほとんど、Herokuのドキュメント通りですが、 Apache設定に関して忘れがちなので同じ経験をしている方の助けになればと思います!

Githubにコミットしてるので、参考にどうぞ!
kin29/symfony4-heroku

 

使うもの

– Symfony4.4
– Heroku (Apacheを想定)

 

確認事項

Symfony4.4はPHP7.1.3以上が必要です。

$ php -v  //ローカルのPHPのバージョンを確認
PHP 7.1.30 (cli) (built: Jul 4 2019 21:55:42) ( NTS )

 

※ 今のHerokuのデフォルトPHPバージョンは7.3.12でした!

-----> PHP app detected
-----> Bootstrapping...
-----> Installing platform packages...
       - php (7.3.12)
       - apache (2.4.41)
       - nginx (1.16.1)

 

手順

1.composer経由でプロジェクトの作成

$ composer create-project symfony/website-skeleton symfony4-heroku/

ビルドインサーバーを立ててローカルで確認してみる。

$ cd symfony4-heroku/
$ php -S 127.0.0.1:8888 -t public/

welcomeページ見れましたー!

 

2.Herokuにデプロイしてみる

Githubにpushして、masterをdeployしてみます。

なんかエラーになって、deployできない。

...
     Script cache:clear returned with error code 255
       !!  Symfony\Component\ErrorHandler\Error\ClassNotFoundError {#29
       !!    #message: """
       !!      Attempted to load class "WebProfilerBundle" from namespace "Symfony\Bundle\WebProfilerBundle".\n
       !!      Did you forget a "use" statement for another namespace?
       !!      """
       !!    #code: 0
       !!    #file: "./src/Kernel.php"
       !!    #line: 23
       !!    trace: {
       !!      ./src/Kernel.php:23 {
       !!        App\Kernel->registerBundles(): iterable
       !!        › if ($envs[$this->environment] ?? $envs['all'] ?? false) {
       !!        ›     yield new $class();
       !!        › }
       !!      }
       !!      ./vendor/symfony/http-kernel/Kernel.php:449 { …}
       !!      ./vendor/symfony/http-kernel/Kernel.php:133 { …}
       !!      ./vendor/symfony/framework-bundle/Console/Application.php:169 { …}
       !!      ./vendor/symfony/framework-bundle/Console/Application.php:75 { …}
       !!      ./vendor/symfony/console/Application.php:148 { …}
       !!      ./bin/console:42 { …}
       !!    }
       !!  }
       !!  2019-12-14T12:26:54+00:00 [critical] Uncaught Error: Class 'Symfony\Bundle\WebProfilerBundle\WebProfilerBundle' not found
       !!  
       Script @auto-scripts was called via post-install-cmd
 !     WARNING: There was a class not found error in your code
 !     ERROR: Dependency installation failed!
 !     
 !     The 'composer install' process failed with an error. The cause
 !     may be the download or installation of packages, or a pre- or
 !     post-install hook (e.g. a 'post-install-cmd' item in 'scripts')
 !     in your 'composer.json'.
 !     
 !     Typical error cases are out-of-date or missing parts of code,
 !     timeouts when making external connections, or memory limits.
 !     
 !     Check the above error output closely to determine the cause of
 !     the problem, ensure the code you're pushing is functioning
 !     properly, and that all local changes are committed correctly.
 !     
 !     For more information on builds for PHP on Heroku, refer to
 !     https://devcenter.heroku.com/articles/php-support
 !     
 !     REMINDER: the following warnings were emitted during the build;
 !     check the details above, as they may be related to this error:
 !     - There was a class not found error in your code
 !     Push rejected, failed to compile PHP app.
 !     Push failed

 

herokuのdeployではcomposer require-devのほうは、インストールしてくれないそうなので、symfony/profiler-packがないよーって言っています。

横着ですが、
require-devのパッケージを、requireの方にも入れます。

       !!  Symfony\Component\ErrorHandler\Error\ClassNotFoundError {#29
       !!    #message: """
       !!      Attempted to load class "WebProfilerBundle" from namespace "Symfony\Bundle\WebProfilerBundle".\n
       !!      Did you forget a "use" statement for another namespace?
       !!      """

 

こっちも、composer.jsonのscript部分の消しちゃって逃げます💦

-    "scripts": {
-        "auto-scripts": {
-            "cache:clear": "symfony-cmd",
-            "assets:install %PUBLIC_DIR%": "symfony-cmd"
-        },
-        "post-install-cmd": [
-            "@auto-scripts"
-        ],
-        "post-update-cmd": [
-            "@auto-scripts"
-        ]
-    },

で、どうにかHerokuにデプロイできるようになりました😎

 

3.env=prodにする

heroku config:set APP_ENV=prod --app [herokuのapp名]

4.Apacheの設定 ←ここ大事💡

以下コマンドでProcfileを作成します。

$ echo 'web: heroku-php-apache2 public/' > Procfile

さらに、composer require apache-packを実行し、質問にはyesで答えます。
そうすると、.htaccessが追加されます。

git pushしてherokuにdelpoyされたら、ブラウザで確認してみます。
env=prodでは、welcomeページはないので404になります。

 

5.コントローラー作成

下記コマンドで、コントローラを作成することができます。

$ php bin/console make:controller HogeController

 created: src/Controller/HogeController.php
 created: templates/hoge/index.html.twig

           
  Success! 
           

 Next: Open your new controller class and add some pages!

deploy後にheroku bashで、routerを一応確認してみます。良さそう😏

~ $  bin/console debug:router
 ------ -------- -------- ------ -------
  Name   Method   Scheme   Host   Path
 ------ -------- -------- ------ -------
  hoge   ANY      ANY      ANY    /hoge
 ------ -------- -------- ------ -------

6.ブラウザチェック

作成した/hogeにアクセスしてみると、、、見れたー!!!!!🎉

つまづきポイント

deployできたはずなのに、herokuでsymfonyコマンド使ってみると、 最初のエラーが再び….
Attempted to load class “WebProfilerBundle” from namespace “Symfony\Bundle\WebProfilerBundle”.\n
Did you forget a “use” statement for another namespace?
heroku run bashして、サーバに入ってrm -rf vendor/からのcomposer installでどうにかsymfonyコマンドは動作するようになりました。

 

参考

https://devcenter.heroku.com/articles/deploying-symfony4
https://github.com/heroku/heroku-buildpack-php/issues/278#

 

Ubuntu環境構築してみる。

どうも!わたしはlinuxばかり触ってきた身なもので、
今回はubuntuを触ってみます!
わたしの妄想では、この2つにあんまり違いはないんでないかなって思ってました。
構築しただけだと、その認識のままです。
触りこんでくと違うんですかね。

<使うもの>
・Mac
・Vagrant
・VirtualBox

<構築環境>
・ubuntu
・Apache
・ホストOSとの共有ディレクトリ → ubuntu_share/
・(おまけ)pythonをデフォルトで3の方にする。

ubuntu環境構築

ubuntu環境との共有フォルダーをホスト側に作成

$ mkdir ubuntu_share

 

ubuntu環境用のディレクトリ作成、そのディレクトリ内に移動

$ mkdir ubuntu_dev
$ cd ubuntu_dev

 

ubuntu-18.04をいれて、立ち上げて、SSHで入ってみる。

$ vagrant init bento/ubuntu-18.04
$ ll  //Vagrantfileができてることを確認。
$ vagrant up
$ vagrant ssh
vagrant@vagrant:~$ exit //一旦出る。

 

設定ファイルVagrantfileよりIP・共有ディレクトリを設定し、

再起動後、SSHで入ってみる。

$ vi Vagrantfile

Vagrantfile

...
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"   //コメントアウト(#)を外す
....
  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
config.vm.synced_folder "../ubuntu_share", "/home/vagrant/ubuntu_share"
...
$ vagrant reload
$ vagrant ssh
vagrant@vagrant:~$ ll  

ubuntu_share/があることを確認し、

テストファイルを作って、ホスト側にもあったら\(^^)/よし

 

Apache導入(サーバ)

/var/www/html/がルートになるはず。
Vagrantfileにて ip: “192.168.33.10”としてるので、
http://192.168.33.10でアクセスできるようになります。

$ sudo apt-get update
$ sudo apt-get install apache2
$ sudo /etc/init.d/apache2 start

 

pythonをデフォでPython3の方にする

元から Python 3.6.5/Python 2.7 は入ってます。 デフォルトをPython 3の方にする。

$ python -V
Python 2.7.15rc1
$ python3 -V
Python 3.6.5

 

デフォルトでは pip がインストールされてないので、インストールする。
pip とは…
The Python Package Index に公開されているPythonパッケージ・ライブラリのインストールなどが行える
らしい。

$ pip install {入れたいパッケージ名}
$ sudo apt install python3-pip python3-dev
$ sudo apt install python-pip python-dev

 

pyenvインストール

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
## 環境変数の設定とか(上手く行くことを確認したら、~/.bash_profileなどに書いておく。)
$ export PYENV_ROOT=$HOME/.pyenv
$ export PATH=$PYENV_ROOT/bin:$PATH
$ eval "$(pyenv init -)"
$ source ~/.bashrc
$ pyenv --version
# 使えるもの一覧を表示する
$ pyenv install --list
# インストールしてみる
$ pyenv install -v 3.6.6
# デフォルトに設定する。
$ pyenv global 3.6.6
 
python -V
-> 3.6.6

 

ついでに、よく使うやついれておく

$ sudo apt-get install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
$ sudo apt-get install python3-tk tk-dev python-tk libfreetype6-dev

 

こんな感じでできました。
pythonも使ったことないので、
自分的疑問で、なんでpythonとpython3があるんだよ、統一させちゃいかんの?
ややこしんだよっって思ってます。。
なにか理由はあるんでしょうね、きっと。