VirtualBoxとVagrantを使ってコマンド1つでLAMP環境を構築させる

2度目の記事です。

先日vagrantをいろいろいじってvagrant upだけでlamp環境を作れるようなvagrantを設定したので完全自己満で共有します。

なんでnginxじゃなくてapacheやねんって、僕も思いますけど弊社では今のところapacheの方が需要が高いから(というかまだnginx使う案件はやってなさそう)必然的にapacheになりました。が、nginx版も作ってみたいなとは思っています。

dockerの方が利便性は高そうなんだけど、弊社にはwin10home勢多くてdocker難民なのでvagrantにしました。

vagrantの使い方

動作手順

  1. VirtualBoxのインストール
  2. Vagrantのインストール
  3. コマンドプロンプト(win) or ターミナル(mac)を開いてvagratn -vを実行。インストールされていることを確認
  4. vagrant plugin install vagrant-vbguestを実行。共有フォルダを使うためのプラグインをインストール
  5. cd vagrant_testディレクトリのダウンロード先による)このディレクトリがあるフォルダに移動。
  6. vagrant up Vagrantfileを実行してVMを立ち上げる。(初回は時間がかかる)
  7. vagrant sshこれで立ち上げたVMに対してssh接続できる
  8. vagrant halt VMをシャットダウンする

構成

  • CenOS7
  • php7.4
    • composer
  • mysql8.0
  • apache2.4

VirtualBox, Vagrantとは

VirtualBoxはホストOSの上にゲストOSとして新たに任意のOSを立ち上げることのできる仮想化ソフト。 VagrantVirtualBoxの立ち上げ、設定などもろもろ自動化する為のツール。

その他

  • 共有フォルダはホスト側はVagrantfileのあるディレクトリでゲスト側は/var/www/html
  • DocumentRoot /var/www/html
  • 実際にコードをいじる時は共有フォルダ内をいじる
  • git cloneはローカル側の共有フォルダにする
  • vagrant ssh-configでデフォで作られるssh設定を確認できる
  • composerなどのコマンドを使うときはvagrant sshVM内に入って叩く
  • DBクライアントにはsshで接続する
  • その他vagrantコマンド
  • vagrantのバージョンが最新でないと起動しないようなので注意

Vagrantfile

Vagrant.configure("2") do |config|
  ###
  # centos7をバージョン指定してインストール
  ###
  config.vm.box = "centos/7"
  config.vm.box_version = "1905.1"

  ###
  # HTTPのポートを設定
  ###
  config.vm.network "forwarded_port", guest: 80, host: 8080

  ###
  # private_networkを指定するとホストOSからのみアクセスできる
  ###
  config.vm.network "private_network", ip: "192.168.33.10"

  ###
  # 共有フォルダの設定(VagrantFileのディレクトリと/var/www/htmlを共有)
  ###
  config.vm.synced_folder ".", "/var/www/html"

  # ※以下はシンボリックリンクを使えるようにrsyncでやってるが調整中で動くかわからないのでコメントアウト
  #  config.vm.synced_folder ".", "/var/www/html", type: "rsync",
  #    rsync__exclude: ".git/",
  #    rsync__args: ["--verbose", "--rsync-path='sudo rsync'", "--archive", "--delete", "-z", "--copy-links"]

  ###
  # ツールをvirtualboxに指定
  ###
  config.vm.provider "virtualbox" do |vb|
  ### GUIは使わない
  vb.gui = false
  ### メモリは2048
  vb.memory = "2048"
  ### シンボリックリンク作成を許可(これも調整中の為コメントアウト)
  # vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
  end
  
  ###
  # その他のインストール項目をinstall.shから読み込む
  ###
  config.ssh.insert_key = false
  config.vm.provision :shell, keep_color: true, path: "install.sh"
end

install.sh

# 最初にyumをupdateしておく
yum update
yum -y install wget zip unzip

# selinux無効化 ※本来二重でやる必要はないがsedコマンドが効かなかったから二重でやってる。原因はわかっていない
# ※selinux無効化は開発環境だからいいと思っているが本来はちゃんと設定などしないといけない
setenforce 0
sed -i -e "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

# firewallのport開放
systemctl restart firewalld
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

# php install 初期設定
yum -y install epel-release
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum -y install --enablerepo=remi,remi-php74 php php-fpm php-pdo php-mbstring php-gd php-json php-mysql php-xml php-pecl-zip

# php.iniのバックアップ timezone設定 errorを画面に表示させる設定(開発環境のみ)
cp /etc/php.ini /etc/php.ini.org
sed -i -e "s/;date\.timezone =/date\.timezone = Asia\/Tokyo/g" /etc/php.ini
sed -i -e "s/display_errors = Off/display_errors = On/g" /etc/php.ini

# composer install
EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php

# どこからでもcomposerを使えるように
mv composer.phar /usr/local/bin/composer

# Apache起動、自動起動設定
systemctl start httpd
systemctl enable httpd

# httpd.confのバックアップ .htaccessの許可
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
sed -i -e "s/AllowOverride None/AllowOverride All/g" /etc/httpd/conf/httpd.conf
# httpd.confでphpを効かせる為の設定
sed -i -e "s/DirectoryIndex index.html/DirectoryIndex index.php index.html/g" /etc/httpd/conf/httpd.conf

# httpd.confの反映
systemctl reload httpd

# デフォで入ってるmariadbを削除してmysql8.0をinstall
yum remove mariadb-libs
rm -rf /var/lib/mysql/
yum -y install http://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
yum -y install mysql-community-server mysql-community-devel mysql-utilities

# my.cnfに文字コードと認証プラグインの設定(8.0では必須)を追記
sed -i -e "s/# default-authentication-plugin=mysql_native_password/default_authentication_plugin=mysql_native_password\ncharacter-set-server = utf8/g" /etc/my.cnf

# mysqldの自動起動を有効化
systemctl enable mysqld
systemctl restart mysqld

# 変数定義 => MySQLの設定で必須
database=test_db
user=db_user
host_name=localhost
# 初期パスワードを取得する
password=`cat /var/log/mysqld.log | grep "A temporary password" | tr ' ' '\n' | tail -n1`
new_password=passwordPASSWORD@999

# mysqlの初期設定 ※mysql8ではgrantコマンドでユーザーを作れない
mysql -u root -p${password} --connect-expired-password -e "alter user root@localhost identified by '${new_password}'"
mysql -u root -p${new_password} --connect-expired-password -e "create database $database"
mysql -u root -p${new_password} --connect-expired-password -e "create user $user@$host_name identified by '$new_password'"
mysql -u root -p${new_password} --connect-expired-password -e "grant all privileges on $database.* to $user@$host_name with grant option"
mysql -u root -p${new_password} --connect-expired-password < /vagrant/db/database.sql

今のところはこれで動いているけどもしかしたら何かしらの問題があるかもしれない。

...ないといいなぁ。。

もっとこうした方がいいよとかあればコメントでもtwitterでも教えていただけるととてもうれしいです。

この間先輩からvagrantでやるのはOS立てるまでにして、あとの細かい設定はansibleでやった方がいいと教えてもらったのでansibleに作り替えるかもしれない。 軽く調べてみた感じansibleだと上のinstall.shをymlでもっと簡単に書けそうでよさげだった。

ファイル共有の問題点

ゲスト、ホスト間でファイル共有する時に

ゲスト側で共有ディレクトリ外に張ったシンボリックリンクをホスト側から参照できない

という問題が発生するんですが、 この問題のいい解決方法が思い浮かばないのでどなたかご教授いただきたいです。

これの解決のためにvagrantのファイル共有をrsyncの方式に変えようとしてるんだけど、 (rsyncならシンボリックリンクのファイルもリンクだけでなく元のファイルを共有できるぽい)

vagrantに備わってるrsyncの問題点として

  • ホスト→ゲストの一方しか同期されない
  • vagrant rsync-autoというコマンドを一度叩かないと共有が始まらない
  • 共有フォルダ間でのシンボリックリンク作成は別途設定をするもしくはコマンドプロンプトを管理者権限で実行しないと作れない

というのがあるのでなんかいい感じにできるのないかなーーーという感じです。

この問題については引き続き検討していきます。何かいいアイデアがあれば教えてくださいな。

ばーっと書いたのでかなり雑で分かりづらい文章なきがしますが、、 ここまで読んでくださってありがとうございました。