Murayama blog.

プログラミング教育なブログ

Vagrant+VirtualBoxでUbuntuを起動する

何をするのか

WindowsとかMacの中でLinuxUbuntu)を起動します。

Linuxの学習にもオススメです。

手順

  1. VirtualBoxをインストール
  2. Vagrantをインストール
  3. ターミナルソフトをインストール(Windowsのみ)
  4. VagrantUbuntuを起動する
  5. Ubuntuに接続する

1. VirtualBoxのインストール

VirtualBoxORACLEの提供する仮想化ソフトです。VirtualBoxを使えば現在実行中のOSの上で、別のOSを起動できます。たとえば、Macの中でLinuxを動かすみたいなことができます。

ちなみにパソコンに直接インストールしているOSをホストOS、仮想化ソフトによってインストールされたOSをゲストOSと呼びます。

VirtualBoxは以下のサイトからダウンロードします。

https://www.virtualbox.org/

インストールはウィザードに従って進めましょう。

2. Vagrantをインストール

VagrantVirtualboxのような仮想化ソフトを便利に扱うためのツールです。Vagrantをインストールすると、コマンドライン上でvagrantコマンドを利用できるようになります。vagrantコマンドを使えばゲストOSイメージのダウンロード、ゲストOSの起動、ゲストOSへの接続といったあらゆる操作を実行できます。

Vagrantは以下のサイトからダウンロードします。

https://www.vagrantup.com/

こちらもインストールはウィザードに従って進めましょう。

3. ターミナルソフトをインストール(Windowsのみ)

ターミナルソフトというのは、ホストOSからゲストOSに接続するためのものです。WindowsだとPuttyか何かで良いと思います。

http://ice.hotmint.com/putty/

4. VagrantUbuntuを起動する

VagrantはゲストOSのイメージをBoxという単位で扱います。UbuntuCentOSといった一般的なBoxは以下のWebサイト(Vagrantbox.es)で公開されているので利用すると便利です。

http://www.vagrantbox.es/

ここでは以下の手順でゲストOS(Ubuntu)を起動します。

  • VagrantにBoxを追加する
  • Vagrantfileを作成する
  • VagrantfileからゲストOSを起動する

VagrantにBoxを追加する

Vagrantbox.esで公開されているUbuntu(Precise 32bit)を追加します。

$ vagrant box add precise32 http://files.vagrantup.com/precise32.box

Boxのダウンロードには数分かかります。ダウンロード完了後、追加済みのBox一覧を確認できます。

$ vagrant box list

Vagrantfileを作成する

任意のフォルダに移動してVagrantfileを作成します。

$ vagrant init precise32

上記のコマンドでカレントフォルダにVagrantfileが生成されます。

VagrantfileからゲストOSを起動する

Vagrantfileが作成できたので、Ubuntuを起動してみましょう。

$ vagrant up

数秒待つとUbuntuが起動します。

5. Ubuntuに接続する

Macの場合はターミナル上で以下のコマンドを実行します。

$ vagrant ssh

Windowsの場合は、Puttyを起動して以下のとおり接続します。

  • 接続先ホスト・・・127.0.0.1
  • 接続先ポート・・・2222
  • ユーザ名・・・vagrant
  • パスワード・・・vagrant

ゲストOSを停止するには

ホストOS上で次のコマンドを実行します。

$ vagrant halt

EC2にDockerをインストールしてRedmineを起動する

EC2(Amazon Linux)上にDockerをインストールして、Redmineを起動するまでのまとめです。たぶん9分くらいでできます。

Dockerのインストール

詳細は公式のドキュメントに載ってるとおり。

Docker Basics - Amazon EC2 Container Service

要点だけ抜粋すると、

yumのアップデートして

[ec2-user ~]$ sudo yum update -y

Dockerのインストールして

[ec2-user ~]$ sudo yum install -y docker

Dockerサービスを起動する。

[ec2-user ~]$ sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:                                       [  OK  ]

あとはec2-userをdockerグループに追加すればOK。

[ec2-user ~]$ sudo usermod -a -G docker ec2-user

ここで一旦ログアウトして再度ログインする。先のグループ権限を有効にするため。

docker infoコマンドでインストールを確認する。

[ec2-user ~]$ docker info
Containers: 2
Images: 24
Storage Driver: devicemapper
 Pool Name: docker-202:1-263460-pool
 Pool Blocksize: 65.54 kB
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 702.3 MB
 Data Space Total: 107.4 GB
 Metadata Space Used: 1.864 MB
 Metadata Space Total: 2.147 GB
 Library Version: 1.02.89-RHEL6 (2014-09-01)
Execution Driver: native-0.2
Kernel Version: 3.14.27-25.47.amzn1.x86_64
Operating System: Amazon Linux AMI 2014.09

以上でDockerのインストールは完了です。

Redmineのインストール

DockerでRedmineをインストールします。ここではDocker Hubで公開されているsameersbn/redmineにお世話になります。

docker pull sameersbn/redmine:latest
docker pull sameersbn/mysql:latest
docker run --name=mysql -d -e 'DB_NAME=redmine_production' -e 'DB_USER=redmine' -e 'DB_PASS=password' sameersbn/mysql:latest
docker run --name=redmine -it --rm -p 80:80 --link mysql:mysql  sameersbn/redmine:latest

ここではMySQLRedmineのDockerイメージをPULLしています(これには数分かかります)。

Dockerコンテナが起動した後、ブラウザでアクセスすると初期アカウントadmin / adminでログインできます。

EC2の起動時間は無視するとここまでで4分くらい。EC2の起動時間合わせても9分でいける、、かな。

バックグラウンドでRedmineを起動するには

先のやり方だと、Redmineのコンテナがフォアグラウンドで起動しているので、バックグラウンドで起動したい場合は、一回止めて次のように起動します。

docker run --name=redmine -d -p 80:80 --link mysql:mysql  sameersbn/redmine:latest

起動中のコンテナの中でごにょごにょしたい場合はdocker execコマンドを使います。

docker exec -it redmine /bin/bash

参考

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!]

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!]

CronでMySQLのデータをエクスポートしてS3にアップするまで

MySQLのデータをエクスポートしたいで。

qiita.com

Cronの登録するで。

www.server-memo.net

たしかcrontabコマンドは気をつけなあかんで。

d.hatena.ne.jp

Cronで動いたで。でもダンプファイルあれへんで。。

qiita.com

次はコマンドラインでS3にアップしたいで。

s3tools.org

s3cmdよさそうやで。使い方調べるで。

d.hatena.ne.jp

シークレットキーがいるやで。

awsのs3を操作する為のaccess keyとsecret keyを取得する(IAM)

、、とりあえず警告は/dev/nullや、、で。

いい加減、>/dev/null 2>&1と書くのをやめたらどうか (追記あり) · DQNEO起業日記

ApacheでLaravel5アプリケーションを動かす

Laravel5を使ったWebアプリケーションを開発しています。

開発時はビルトインサーバで開発して、運用時はApacheでということがやりたかったのでまとめです。OSにはUbuntu14.04を使っています。Vagrantも使ってます。

開発時 - ビルトインサーバの起動

開発時はphp artisan serveでビルトインサーバを使ってます。手軽で便利です。

$ php artisan serve

IP指定で起動することもできます。

$ php artisan serv --host 192.168.33.10

運用時 - Apacheで動かすには

基本的にはApacheでLaravelアプリケーションのバーチャルホストを定義するだけ。Laravelアプリケーションのpublicフォルダをドキュメントルートに指定します。

バーチャルホストの定義

Apacheにバーチャルホストの定義を追加します。

Ubuntu14の場合、/etc/apache2/sites-available/ディレクトリにバーチャルホストの定義ファイルを新規作成します。

ここでは/etc/apache2/sites-available/myapp.confを次のように作成します。

<VirtualHost *:80>
        ServerName myapp.com
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/myapp/public

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory "/var/www/myapp/public">
                AllowOverride All
        </Directory>
</VirtualHost>

ここでは/var/www/myapp/にLaravelアプリケーションが存在するものとしています。

DocumentRootにはmyapp/publicを指定します。 またLaravelは.htaccessを利用するので、myapp/publicディレクトリにAllowOverride Allを定義します。

/etc/apache2/sites-available/に作成したmyapp.confはこのままではApacheにロードされません。そのため、/etc/apache2/sites-enabled/からシンボリックリンクを定義します。

$ cd /etc/apache2/sites-enabled/
$ sudo ln -s ../sites-available/myapp.conf

変更を反映するためにApacheを再起動します。

$ sudo service apache2 restart

Apacheの実行ユーザを変更する

Vagrant上で開発している場合は、Apacheの実行ユーザをvagrantに変更します。Ubuntu14のApacheにはenvvarsというファイルで実行ユーザを変更できます。envvarsは環境変数を管理するファイルのようです。

$ sudo vi /etc/apache2/envvars

envvarsを以下のとおり変更します。

export APACHE_RUN_USER=vagrant
export APACHE_RUN_GROUP=vagrant

.htaccessが機能しない問題

Laravelアプリケーションにはpublicディレクトリ下に.htaccessファイルが用意されています。.htaccessファイルではmod_rewriteによるURLの書き換えが定義されています。

ちょっとはまったのは、デフォルトのApacheだとmod_rewriteが無効になっていた件です。そのため、URLの書き換えが機能せず、以下のような問題に遭遇しました。

laravel 4 all routes except home result in 404 error

Laravelアプリケーションのルートディレクトリ以外は404になってしまうという。。 このときの現象として、以下のURLでログイン画面にアクセスしたいのに404になってしまいます。

http://myapp.com/auth/login

その代わり、次のURLでアクセスできるという。。index.phpて。。

http://myapp.com/index.php/auth/login

この場合、mod_rewriteを有効にすると解決します。

$ sudo a2enmod rewrite

Apacheの再起動も忘れずに。

$ sudo service apache2 restart

Laravelアプリケーションの設定

Laravelアプリケーションに特に変更箇所はありませんが、Gitのようなバージョン管理システムからコードを取得して来た場合、composer isntallを叩いて、それから.envファイルを作成する必要があります。

$ composer install

このへんは必要に応じてsudoするかんじで。

$ cp .env.example .env

.envに定義するAPP_KEYはphp artisan key:generateで取得できます。

$ php artisan key:generate
Application key [0wzwvICe8xa0vJ7RUpOM1z7F03NeZxxx] set successfully.

もう1つアプリケーションのログファイルを生成しておく必要がありました。

$ touch /var/www/myapp/storage/logs/laravel.log

これくらいでたぶん動くはず。

補足

Apacheのインストール

$ sudo apt-get install -y apache2

sudo apt-get updateもさきにしとくように。

PHPのインストール

sudo apt-get install php5-common libapache2-mod-php5 php5-cli php5-json php5-sqlite php-pear php5-dev

SQLiteならこんなかんじでいけます。

Composerのインストール

$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer

ログファイル

Apacheのログは/var/logs/apache2/error.log

Laravelのログは/var/www/myapp/storage/logs/laravel.log

DigitalOceanでやるときのメモ

とりあえずDigitalOcean(rootユーザ)で環境構築するときは、Laravelアプリケーションの所有者をApacheユーザ(www-data)にしていおいた。

$ chown -R www-data:www-date /var/www/myapp

Apache 2.4の場合

パーミッションの設定でエラーが出る。

AH01630: client denied by server configuration

stackoverflow.com

<VirtualHost *:80>
        ServerName myapp.com
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/myapp/public

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory "/var/www/myapp/public">
                AllowOverride All
                Require all granted
        </Directory>
</VirtualHost>

JAX-RS 非同期処理 Asynchronous Services

JAX-RSの非同期処理の実装サンプルです。

参考記事

JerseyのTutorialを参考にしました。

Asynchronous Server API

まずはベタな実装から。こんなふうにするとサーバースレッドはすぐに終わるので再利用できる。

  • @Suspendアノテーションを付与したAsyncResponse引数を用意する
  • 別スレッドの処理終了時にasyncResponse.resume(response);でレスポンスを返す

タイムアウトの設定は次のように実装する。

Asynchronous Server-side Callbacks

非同期処理のコールバックメソッドを作る場合は次のように実装する。

  • asyncResponse.registerでコールバックを登録する
  • このサンプルではCompletionCallbackを実装して登録している
  • CompletionCallbackのonCompleteメソッドはThrowable型の引数を受け取る(正常な場合はnull)

ちょっとだけはまったのが、別スレッドでWebApplicationExceptionのような例外をスローすると引数に代入されないところ。

Interface CompletionCallbackを参照すると、引数Throwableにはunmapped exception instanceが代入される的なことが書いている。

コールバックには以下の2種類がある。

  • CompletionCallback リクエスト終了時に呼び出される(正常でも、異常でも)
  • ConnectionCallback クライアントコネクションがクローズされるときに呼び出される(正常なクローズの場合は呼ばれない)

Servletの非同期処理

JAX-RSの非同期処理を実装しようと思ったけど、そもそもServletの非同期処理を実装したことなかったのでそっちの復習から。

参考記事

こちらの記事を参考にしてみました。

ちなみに参考にしたページではServletContextListenerでThreadPoolExecutor作ってる。要るのかわからんのでひとまずなしで。

動作確認

Tomcatを起動してブラウザでこんなかんじでアクセスする。

http://localhost:8080/async_servlet/AsyncLongRunningServlet?time=3000

この場合処理に3秒かかるわけですが、サーバのコンソールをみるとサーブレットスレッドがすぐ終了してるのがわかる。

AsyncLongRunningServlet Start::Name=25::ID=25
AsyncLongRunningServlet End::Namehttp-nio-8080-exec-3::ID=25::Time=13ms.

ちょっと疑問

サーバのコンソールを見ると、StartとEndの出力でスレッド名が変わってるんだけどこういうもんなのかな。

20分くらいでできるVagrantによるRails開発環境の構築

はじめに

Railsの環境をパパっと作りたい。でもVagrantもChefもよくわからない。そんな私でもすぐできました。

こちらが参考になりました。

以下内容をまとめてみました。

Using Vagrant for Rails Development

Overview

読み終えるまでにかかる時間は20分くらい

Vagrantは開発環境のセットアップを自動化するツールです。あなたのコンピュータ上に仮想環境を構築します。Vagrantを使えば開発環境とプロダクションサーバの整合性を保ったり、同僚と同じ環境で開発したりできるようになります。

仮想環境上に構築したRails開発環境は、ホストコンピュータの設定がいかなる状態になろうとも、同じ状態を維持できます。もし、1年後に開発プロジェクトを再度稼働する必要が生じた場合にも、数分でプロジェクトを起動できます。これは大変便利なことです。

ここでは仮想環境上の開発環境の自動構築にChefを使用します。ホストコンピュータ上にRubyと依存するパッケージがセットアップされているか注意してください。

セールストークは十分でしょう。それでは始めましょうか。

Setting Up Vagrant

Vagrantで仮想環境上でRailsアプリケーションを起動するためにはゲストOSを起動しなければなりません。そのため、ホストコンピュータ上で1GB、2GB程度のRAMが利用できることを確認しておいてください。

最初のStepはコンピュータ上にVagrantVirtualBoxをインストールしてください。

  1. Install Vagrant
  2. Install VirtualBox

VirtualBox仮想マシンを実行するソフトウェアです。VirtualBoxはバックグラウンドで動作するヘッドレスなソフトウェアとして起動できるので、ゲストOSとSSHを使ってインタラクティブにやりとりすることができます。

次はVagrantに2つのプラグインをインストールします。

  • vagrant-vbguest VirtualBox Guest Additionsを自動的にインストールします
  • vagrant-librarian-chef マシンの起動時にchefを自動的に実行します
vagrant plugin install vagrant-vbguest
vagrant plugin install vagrant-librarian-chef

インストールには少し時間がかかるでしょう。

Create the Vagrant config

ChefをセットアップするためにRailsプロジェクトのトップに移動し、次のコマンドを実行します。

cd MY_RAILS_PROJECT # Change this to your Rails project directory
vagrant init
touch Cheffile

ここで作成されたVagrantfileとCheffileをカスタマイズすることになります。

Your Cheffile

ここではCheffileを定義します。CheffileはRailsのGemfileとよく似ています。このファイルにはプロジェクトに必要なChefのクックブックを定義します。後ほど作成するVagrantfileによって、Vagrantはこれらのクックブックを参照することで環境を構築するようになります。

Cheffileに次のコードをペーストすると良いでしょう。

site "http://community.opscode.com/api/v1"

cookbook 'apt'
cookbook 'build-essential'
cookbook 'mysql'
cookbook 'ruby_build'
cookbook 'nodejs', git: 'https://github.com/mdxp/nodejs-cookbook'
cookbook 'rbenv', git: 'https://github.com/fnichol/chef-rbenv'
cookbook 'vim'

Your Vagrantfile

Vagrantfileには仮想マシン上のOSとChefの設定を定義します。

ゲストOSにはUbuntu 14.04 trusty 64-bitを使用します(32-bitがよければtrusty32でもOKです)。ここでは2GBのメモリを定義しています。続いてrails serverを実行した際、ブラウザでアクセスしやすくするため、ホストOS上の3000番ポートを仮想マシンの3000番ポートにフォワードするように設定しています。最後に仮想マシン内にChef、Ruby2.1.2、MySQLをセットアップしています。

Vagrantfileは次のように変更してください。

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Use Ubuntu 14.04 Trusty Tahr 64-bit as our operating system
  config.vm.box = "ubuntu/trusty64"

  # Configurate the virtual machine to use 2GB of RAM
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end

  # Forward the Rails server default port to the host
  config.vm.network :forwarded_port, guest: 3000, host: 3000

  # Use Chef Solo to provision our virtual machine
  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks", "site-cookbooks"]

    chef.add_recipe "apt"
    chef.add_recipe "nodejs"
    chef.add_recipe "ruby_build"
    chef.add_recipe "rbenv::user"
    chef.add_recipe "rbenv::vagrant"
    chef.add_recipe "vim"
    chef.add_recipe "mysql::server"
    chef.add_recipe "mysql::client"

    # Install Ruby 2.1.2 and Bundler
    # Set an empty root password for MySQL to make things simple
    chef.json = {
      rbenv: {
        user_installs: [{
          user: 'vagrant',
          rubies: ["2.1.2"],
          global: "2.1.2",
          gems: {
            "2.1.2" => [
              { name: "bundler" }
            ]
          }
        }]
      },
      mysql: {
        server_root_password: ''
      }
    }
  end
end

Running Vagrant

以上でVagrantとChefの設定は完了です。Vagrant仮想マシンを起動してsshで接続してみましょう。

# The commented lines are the output you should see when you run these commands

vagrant up
#==> default: Checking if box 'ubuntu/trusty64' is up to date...
#==> default: Clearing any previously set forwarded ports...
#==> default: Installing Chef cookbooks with Librarian-Chef...
#==> default: The cookbook path '/Users/chris/code/test_app/site-cookbooks' doesn't exist. Ignoring...
#==> default: Clearing any previously set network interfaces...
#==> default: Preparing network interfaces based on configuration...
#    default: Adapter 1: nat
#==> default: Forwarding ports...
#    default: 3000 => 3000 (adapter 1)
#    default: 22 => 2222 (adapter 1)
#==> default: Running 'pre-boot' VM customizations...
#==> default: Booting VM...
#==> default: Waiting for machine to boot. This may take a few minutes...
#    default: SSH address: 127.0.0.1:2222
#    default: SSH username: vagrant
#    default: SSH auth method: private key
#    default: Warning: Connection timeout. Retrying...
#==> default: Machine booted and ready!
#==> default: Checking for guest additions in VM...
#==> default: Mounting shared folders...
#    default: /vagrant => /Users/chris/code/test_app
#   default: /tmp/vagrant-chef-1/chef-solo-1/cookbooks => /Users/chris/code/test_app/cookbooks
#==> default: VM already provisioned. Run `vagrant provision` or use `--provision` to force it
vagrant ssh
#Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.13.0-24-generic x86_64)
#
# * Documentation:  https://help.ubuntu.com/
#
# System information disabled due to load higher than 1.0
#
#  Get cloud support with Ubuntu Advantage Cloud Guest:
#    http://www.ubuntu.com/business/services/cloud
#
#
#vagrant@vagrant-ubuntu-trusty-64:~$

初めてvagrant upコマンドを実行するときは時間がかかります。これはChefの設定ファイルに従って仮想マシンをプロビジョニングするためです。次回以降のvagrant upコマンドはChefを実行する必要なくなるため、起動に時間はかからなくなるでしょう。

VagrantfileやCheffileを編集した場合は、次のコマンドを実行してマシンを再設定しなければなりません。

vagrant provision

Using Rails inside Vagrant

Vagrantは/vagrantフォルダを仮想マシンとホストOS間で共有します。cd /vagrantで移動してlsコマンドを叩けばRailsアプリケーションのファイルを確認できるでしょう。

このディレクトリでbundleコマンドを実行すればgemをインストールできますし、rake db:create && rake db:migrateを実行すればデータベースを構築しマイグレーションも行えます。

このディレクトリでrails serverコマンドを実行すればRailsアプリケーションが3000番ポートで起動します。いつもどおりlocalhost:3000にアクセスすればRailsアプリケーションを操作できます。

Conclusion

Vagrantはポータブルな開発環境を作成するソフトウェアツールです。そこにはあなたのコードを含むこともできます。Chefを使ってシンプルな設定を施すだけで、ほとんど時間をかけずに仮想マシンを起動することができます。

もし、あなたが再びVagrantマシンをセットアップする必要がでてきたり、同僚がセットアップを必要とする場合は、vagrant upコマンドを実行するだけで仮想マシンを手に入れることができます。