Vagrant仮想環境に Yesod-MySQL をインストール

HaskellのwebフレームワークYesodを使いこなすべく、気軽にいじれる環境が欲しかったので、

vagrant up一発で立ち上がることを目標に、仮想環境を作ってみました。

Yesodは、お世辞にもメジャーとは言えないですが、

この記事が敷居を下げる一助になれば幸いです。

daemon化するにあたっては、nginxやketerが必要なのですが、

今回はsshログイン後、フォアグラウンドでコマンドを叩いてのサーバー起動までを行います。

公式のyesodチュートリアルでは、関連する手順をシンプルに説明するためにsqliteを使っていましたが、

あえてMySQLを使ってみます。

vagrantfileとprovision.shですぐに環境を手に入れたい方はこちら


前提条件

Vagrant と VirtualBoxがインストールされていること


手順


1. 準備

適当な場所に仮想環境用のディレクトリを作ります。

$ mkdir yesod-demo

$ cd yesod-demo


2. Vagrantfile

ベースとなるVagrantfileを生成します。

$ vagrant init


Vagrantfile

# -*- mode: ruby -*-

# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.

# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "bento/centos-7.3"

# ~ 中略 ~

# 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"

# ~ 中略 ~

# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end


上記設定で、

config.vm.boxで仮想環境のOSを CentOS7.3に、

ホストOSからアクセスできるIPアドレスを 192.168.33.10 に設定したら、

$ vagrant up

を実行し、Vagrant環境を起動します。

起動完了後、以下を実行して、仮想環境にログインします。

$ vagrant ssh


3. MySQLインストール

仮想環境にログインしてから行う作業は、大きく分けると以下の4つになります。

1. MySQLインストール

2. Stack(Haskellのビルドツール)インストール

3. Yesod(Haskellのwebフレームワーク)インストール

4. ビルド実行&サーバーの起動

まず、 MySQLをインストールします。

$ sudo yum install http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm

$ sudo yum install mysql mysql-devel mysql-server

インストールが完了したら、デーモンを起動します。

$ sudo service mysqld start

初期パスワードをインストールログから取得し、

いったんrootユーザーのパスワードを期限なしの指定文字列に変更しています。

$ DB_PASSWORD=$(grep "A temporary password is generated" /var/log/mysqld.log | sed -s 's/.*root@localhost: //')

$ mysql -uroot -p${DB_PASSWORD} --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'rsYesodServer_2019'; flush privileges;"

webサーバからアクセスするためのDBを作成し、ユーザーと権限を設定します。

$ mysql -uroot -prsYesodServer_2019 -e "CREATE DATABASE yesod_db CHARACTER SET utf8mb4;"

$ mysql -uroot -prsYesodServer_2019 -e "GRANT ALL PRIVILEGES ON yesod_db.* TO 'rsyesodserver'@'%' IDENTIFIED BY 'UgwD9_hwn3'"

これでひとまず、DBの設定は完了になります。


4. Stack & Yesod のインストール

Stackのインストールは、下記コマンド1発で終わります。

$ curl -sSL https://get.haskellstack.org/ | sh

Yesod の前に、依存ライブラリをインストールします。

$ sudo yum install zlib-devel pcre-devel

入れ終わったら、下記コマンドで、Yesodをダウンロードします。

$ stack new rsyesodserver yesod-mysql 

$ cd rsyesodserver
$ stack install yesod-bin --install-ghc

15分近くかかるので、気長に待ちましょう。


5. ビルド & サーバ起動

DB接続のための環境変数を設定します。

$ export YESOD_MYSQL_USER='rsyesodserver'

$ export YESOD_MYSQL_PASSWORD='UgwD9_hwn3'
$ export YESOD_MYSQL_HOST='localhost'
$ export YESOD_MYSQL_DATABASE='yesod_db'

入力が面倒であれば、上記コマンドを ~/.bashrc などに記述するか、

~/rsyesodserver/config/settings.ymlを開き、以下の箇所を設定してください。


~/rsyesodserver/config/settings.yml

database:

user: "_env:YESOD_MYSQL_USER:reyesodserver"
password: "_env:YESOD_MYSQL_PASSWORD:UgwD9_hwn3"
host: "_env:YESOD_MYSQL_HOST:localhost"
port: "_env:YESOD_MYSQL_PORT:3000"
# See config/test-settings.yml for an override during tests
database: "_env:YESOD_MYSQL_DATABASE:yesod_db"
poolsize: "_env:YESOD_MYSQL_POOLSIZE:10"


$ stack build

で、ビルドしたら、以下を実行します。

$ stack exec -- yesod devel

これで、無事サーバを起動することが出来ました!

好きなブラウザから、 http://192.168.33.10:3000 にアクセスすると、ページが開きます。


Vagrantfile / provision.shによる自動セットアップリポジトリ

おもに自分用ですが、Vagrantfile と provision.shを使って、サーバー起動以外の部分を自動化したものを用意しました。

適当なところで以下のコマンドを叩き、リポジトリからソースをダウンロードしてください。

$ git clone https://github.com/rs0604/yesod-demo.git

$ cd yesod-demo
$ vagrant up

20分くらいかけて、MySQL, stack, yesod のインストールが自動で行われます。

その後、

$ vagrant ssh

でログインし、こちらの方法でDB接続設定を行い、

$ cd rsyesodserver

$ stack exec -- yesod devel

を実行すると、サーバが立ち上がります。


vagrant up 時に "/sbin/mount.vboxsf: mounting failed with the error: No such device"と表示されて失敗する場合

参考:https://qiita.com/chubura/items/4166585cf3f44e33271d

ホスト-ゲスト間のフォルダ共有の仕組み(Guest Addition)のバージョン不一致によるエラーです。

自動でバージョンアップを行うプラグインvagrant-vbguestをインストールするために以下コマンドを試みてください。

$ vagrant plugin install vagrant-vbguest && vagrant vbguest && vagrant up


TODO


  • 共有フォルダなどの設定

  • keter による daemon 化

  • SSL通信など、「まともなサーバが当たり前にやっていること」を一通り設定する