けけずんセルフハッキング

忘れそうなことをメモる。

PHP7.1 + Laravel5.x + Nginx + php-fpmな仮想環境構築

概要

vagrant仮想マシンを立ち上げ、ansibleでPHP7.1 + Laravel5.x + Nginx + php-fpmな環境を構築する。

時間のない人向け

リポジトリは以下に公開している。

github.com

以下のコマンドをぽちぽちっとすれば動く。

$ git clone https://github.com/kkznch/laraveltestvm.git
$ cd laraveltestvm
$ vagrant up
$ ansible-playbook -i playbook/inventory/hosts playbook/provisioning/setup.yaml

あとは以下のURLにアクセスするだけ。

http://192.168.16.132:9000

環境

ホスト

ゲスト

構築手順

vagrantでOS起動、SSHログインまで

boxファイルを追加する

boxファイルをインストールする。

$ vagrant box add bento/centos-7

boxファイルがインストールされたか確認する。

$ vagrant box list
bento/centos-7 (virtualbox, 201710.25.0)

Vagrantfileを設置する

vagrantファイルを設置したいフォルダに移動する。

$ mkdir /path/to/laraveltestvm
$ cd /path/to/laraveltestvm

Vagrantfileを作成する。

$ vagrant init bento/centos-7

作成されたファイルを確認する。

$ ls
Vagrantfile

Vagrantfileを編集する

Vagrantfileをエディタで開いて編集する。

$ emacs Vagrantfile
# coding: utf-8
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
    # 使用するboxファイル
    config.vm.box = "bento/centos-7"

    # ゲストOSのホスト名とプライベートIP
    config.vm.define "laraveltestvm" do |lvm|
        lvm.vm.network "private_network", ip: "192.168.16.132"
    end

    # ゲストOS毎に異なる公開鍵を使用しない
    config.ssh.insert_key = false
end

vagrantでOSを起動する

以下のコマンドでOSを起動する。

$ vagrant up

SSHの設定をする

vagratで使用するSSHの設定を表示する。

$ vagrant ssh-config >> ~/.ssh/config

# 以下の内容が.ssh/configに書き込まれる
Host laraveltestvm
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kkznch/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

これをそのまま書いても指定したIPアドレス(192.168.16.132)でログインできないため、HostNamePortの欄を書き換える。

$ emacs ~/.ssh/config
Host laraveltestvm
  HostName 192.168.16.132
  User vagrant
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kkznch/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

SSHの接続確認をする。

$ ssh laraveltestvm
[vagrant@localhost ~]$

ansibleで構成管理する

構成管理用フォルダを作成する

ansible実行時に指定するファイルを格納するフォルダを作成する。

$ cd /path/to/laraveltestvm
$ mkdir -p playbook/{inventory,provisioning}

inventoryはansibleで構成管理する対象を指定するファイルを置く場所、provisioningは構成管理の内容を記述するファイルを置く場所。

構成管理対象ホストを指定する

構成管理の対象となるホスト名を指定する。 ホスト名には先程~/.ssh/configに指定した名前laraveltestvmを指定すること。

$ emacs playbook/inventory/hosts
[laraveltestvm]
laraveltestvm

[laraveltestvm]は構成管理対象のグループ名、laraveltestvmは構成管理対象となるホスト名が入る。 今回は単一のホストに対してのみ構成管理を行うため、グループ名とホスト名は同じにしてる。

構成管理内容を作成する

PHP + Laravelな環境を構築するための構成管理内容を記述したファイルを作成する。

$ emacs playbook/provisioning/setup.yaml
# Playbook
---
- hosts: laraveltestvm
  become: yes
  user: vagrant
  tasks:
    - name: add yum repository
      yum: name="{{ item }}" state=latest
      with_items:
        - epel-release
        - http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
    
    - name: yum basic install
      yum: name="{{ item }}" state=latest
      with_items:
        - zip
        - unzip
        - git
        - mysql
        - nginx

    - name: yum php install
      yum: name="{{ item }}" enablerepo=remi-php71 state=latest
      with_items:
        - php
        - php-devel
        - php-mbstring
        - php-pdo
        - php-gd
        - php-mysql
        - php-xml
        - php-fpm

    - name: modify php.ini
      replace:
        dest: /etc/php.ini
        regexp: "{{ item.regexp }}"
        replace: "{{ item.replace }}"
      with_items:
        - { regexp: "^;date.timezone =", replace: "date.timezone = Asia/Tokyo" }
        - { regexp: "^expose_php = On", replace: "expose_php = Off" }
        
    - name: modify php-fpm config file
      replace:
        dest: /etc/php-fpm.d/www.conf
        regexp: "{{ item.regexp }}"
        replace: "{{ item.replace }}"
      with_items:
        - { regexp: "^user = apache", replace: "user = nginx" }
        - { regexp: "^group = apache", replace: "group = nginx" }
        - { regexp: "^listen = 127.0.0.1:9000", replace: "listen = /var/run/php-fpm/php-fpm.sock" }
        - { regexp: "^;listen.owner = nobody", replace: "listen.owner = nginx" }
        - { regexp: "^;listen.group = nobody", replace: "listen.group = nginx" }        
        
    - name: start php-fpm
      systemd:
        name: php-fpm.service
        state: restarted
        daemon_reload: yes
        enabled: yes
      
    - name: make nginx config file for laravel
      copy:
          dest: /etc/nginx/conf.d/laravel.conf
          mode: 0644
          content: |
            server {
              server_tokens off;

              root /var/www/laravel/public;
              
              listen 9000;
              server_name _;

              location / {
                index index.php index.html;
                try_files $uri $uri/ /index.php?$query_string;
              }

              location ~ \.php$ {
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                include /etc/nginx/fastcgi_params;                  
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              }
            }            

    - name: start nginx
      systemd:
        name: nginx.service
        state: restarted
        daemon_reload: yes
        enabled: yes

    - name: install composer
      command: "{{ item }}"
      with_items:
        - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
        - php composer-setup.php
        - php -r "unlink('composer-setup.php');"
        - mv composer.phar /usr/local/bin/composer

    - name: create laravel project
      command: /usr/local/bin/composer create-project --prefer-dist laravel/laravel /var/www/laravel
      
    - name: change the owner of laravel project
      file:
        path: /var/www/laravel
        owner: nginx
        group: nginx
        recurse: yes

    - name: change the permission of laravel project
      file:
        path: /var/www/laravel/"{{ item }}"
        mode: 0755
        recurse: yes
      with_items:
        - storage
        - bootstrap/cache

ansible-playbookコマンドを実行する

ansible-playbookコマンドを実行して先程作成した仮想環境の中の環境を構築する。

$ ansible-playbook -i playbook/inventory/hosts playbook/provisioning/setup.yaml

...[省略]

PLAY RECAP ************************************************************************************************
laraveltestvm                  : ok=13   changed=12   unreachable=0    failed=0

5分〜10分くらい時間がかかるかも。

接続確認

ブラウザで以下のURLにアクセスする。

http://192.168.16.132:9000

考察

Laravelに繋がらないよふぇ〜的なのはほとんど権限周りが原因だと思う。 大体は以下のが怪しい。

  • /var/run/php-fpm/php-fpm.sock
    • オーナー及びグループは nginx になっているか?
  • Laravelプロジェクトフォルダ
    • プロジェクトフォルダ以下のオーナー及びグループは nginx になっているか?
    • プロジェクトフォルダ直下のstorage及びbootstrap/cacheフォルダのパーミッション755 になっているか?

参考