Laravelで作ったWebアプリを公開

作成: 2020年03月28日

更新: 2021年03月29日

経緯

かつてはDjangoでこのサイトを作成していたが、VueやらWebpackやらの新しい技術を使ってみようとするたび壁にぶち当たってしまうため
laravelで移行した。

デプロイ方法

ローカルでの起動方法およびデプロイ方法は以下のREADME参照。
bana118/banatech_laravel
ドメイン等は変更する必要がある。
laravelのほかにnginx、php-fpm、supervisor(nginx、php-fpm実行用)を用いた。
本番環境の構築方法を忘れると困るのでDockerを主に使用して再現性をもたせた。

Dockerfile

docker-composeなどを用いればより簡潔に記述できるがここでは泥臭くDockerfileに手順を一つ一つ記述した。

Dockerfile
#imagename: banatech_laravel FROM ubuntu:18.04 # avoid freeze while configuring tzdata ENV DEBIAN_FRONTEND=noninteractive #Author MAINTAINER banatech CMD echo "now running..." # Install required packages and remove the apt packages cache when done. RUN apt update && \ apt upgrade -y && \ apt install -y \ curl \ git \ nano \ vim-nox \ nginx \ supervisor \ nodejs \ npm \ composer \ php \ php-zip \ php-xml \ php-json \ php-mbstring \ php-mysql \ php-sqlite3 \ php-bcmath \ php-fpm \ certbot \ sqlite3 && \ rm -rf /var/lib/apt/lists/* # update node npm RUN npm install n -g RUN n stable RUN apt purge -y nodejs npm ENV PATH $PATH:/usr/local/bin/node # add our code COPY . /home/docker/code/banatech_laravel # install packages, but it doesn't work so do it manually in docker # install laravel and etc # RUN cd /home/docker/code/banatech_laravel && composer install --optimize-autoloader --no-dev # install npm packages # RUN cd /home/docker/code/banatech_laravel && npm install # clear laravel caches # This app doesn't seem to delete the route cache... # RUN cd /home/docker/code/banatech_laravel && php artisan config:cache # RUN cd /home/docker/code/banatech_laravel && php artisan config:cache && php artisan route:cache # generate app key # RUN cd /home/docker/code/banatech_laravel && php artisan key:generate # migrate # RUN cd /home/docker/code/banatech_laravel && php artisan migrate # compile css and js # RUN cd /home/docker/code/banatech_laravel && npm run prod # setup all the configfiles RUN echo "daemon off;" >> /etc/nginx/nginx.conf COPY nginx-app.conf /etc/nginx/sites-available/default COPY supervisor-app.conf /etc/supervisor/conf.d/ # create socket file for php-fpm RUN mkdir /var/run/php RUN touch /var/run/php/php7.2-fpm.sock RUN chmod 777 /var/run/php/php7.2-fpm.sock # run nginx EXPOSE 80 EXPOSE 443 CMD ["supervisord", "-n"]

必要なものをaptでインストールしてsupervisorを用いてnginx, php-fpmを実行した。
supervisord-app.confは以下

supervisor-app.conf
[supervisord] nodaemon=true [program:php-fpm] command = /usr/sbin/php-fpm7.2 -c /etc/php/7.2/fpm autostart=true autorestart=true [program:nginx] command=/usr/sbin/nginx autostart=true autorestart=true

またnginxは一度以下のnginx-app.conf.tempを設定ファイルとして用いてhttpのみでデプロイし、letsencryptで証明書を取得してからnginx-app.conf.prodに切り替えてhttpsに対応した。

nginx-app.conf.temp
# nginx-app.conf #letsencrypt認証用 # configuration of the server server { # the port your site will be served on, default_server indicates that this server block # is the block to use if no blocks match the server_name listen 80; # the domain name it will serve for server_name banatech.net; # substitute your machine's IP address or FQDN root /home/docker/code/banatech_laravel/public; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } index index.php index.html index.htm; #letsencrypt認証用 location /.well-known { root /home/docker/code/banatech_laravel/public; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }
nginx-app.conf.prod
# nginx-app.conf # 本番用 # http redirect server { listen 80; listen [::]:80; server_name banatech.net; location /.well-known { root /home/docker/code/banatech_laravel/public; } #sitemap location /sitemap.xml { return 301 https://banatech.net/sitemap.xml; } #robots location /robots.txt { return 301 https://banatech.net/robots.txt; } location / { return 301 https://banatech.net; } } # configuration of the server server { # the port your site will be served on listen 443 ssl http2; listen [::]:443 ssl http2; # ssl config ssl_certificate /etc/letsencrypt/live/banatech.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/banatech.net/privkey.pem; #config https://jyn.jp/ssl-aplus/ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; #add_header Strict-Transport-Security 'max-age=31536000;'; #ssl_dhparam /home/docker/code/dhparam/dhparam1024.pem; #ssl_dhparam /home/docker/code/dhparam/dhparam2048.pem; ssl_dhparam /home/docker/code/dhparam/dhparam4096.pem; ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/banatech.net/chain.pem; # the domain name it will serve for server_name banatech.net; # substitute your machine's IP address or FQDN charset utf-8; root /home/docker/code/banatech_laravel/public; location / { try_files $uri $uri/ /index.php?$query_string; } # max upload size client_max_body_size 75M; # adjust to taste index index.php index.html index.htm; location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }

https用のnginxの設定に関してはMozilla SSL Configuration Generatorおよびデプロイ 6.x Laravel - ReaDoubleを参考にした。
これで定番のssl評価サイトSSL Server Testで評価Aを取得できる。
screen.png
HSTS(HTTP Strict Transport Security)というhttp接続をほとんど拒否する設定などをしていないのでA+にはできていないがこれで十分だと思う。

詰まったところ

できればdocker runするだけでデプロイしたかったがdockerでマウントするとホスト側のファイルでコンテナ側のファイルが上書きされてしまうため、composerやnpmでインストールしたものがすべて消えてしまう。アップロードファイルの管理のためマウントは行いたいので仕方なくデプロイ後にコンテナに入ってcomposer install やnpm install を行った。dockerでマウントしたときにファイルはできるだけマージして欲しかった。
またデプロイ後にsupervisorctl statusするとどうもphp-fpmが死んでいるが、supervisor
からphp-fpmを外すとエラーがでる。これは何が原因かわからないがまあ動いているからヨシ!