Webエンジニアの備忘録

およそ自己の作業メモとして残しております。

フロントエンド環境構築(node/nvm/npm/gulp)

以前のプロジェクトでgulpを利用していたのに、フロントエンド担当ではなかったため環境構築に携われませんでした。 正直よくわからないで使っていたので、自分で構築して何をやっていたのか考えてみます。 今回は「ドットインストール」を教材に習ったもののメモになります。

dotinstall.com ↑なので、普通にこっちをやったほうがいい。

やりたいこと

環境(ちょっとアレンジしています)

  • ubuntu(v14.04.4)
  • node(v5.12.0)
  • nvm(v0.31.2)※nodeのバージョン管理
  • npm(v3.8.6)※nodeのパッケージ管理(gulpもパッケージのひとつ)

nodeバージョンについて

  • 現時点で最新はv6.2.2だったがパッケージ対応が追いついていないものもあり、v5系で最新のバージョンを選択しました。
  • ちなみに、LTS(Long-Term Support)とstableについてもぶつかったのですが、こちらに説明がありました。

インストール

  • nvmを利用してnode/npmをインストール
$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ echo 'if [[ -s ~/.nvm/nvm.sh ]] ; then source ~/.nvm/nvm.sh ; fi' >> ~/.bashrc
$ source ~/.bashrc
$ nvm --version
0.31.2
$ nvm ls-remote
 : // 利用可能なバージョンが羅列される
$ nvm install v5.12.0
$ nvm use v5.12.0
Now using node v5.12.0 (npm v3.8.6)
$ nvm alias default v5.12.0 
default -> v5.12.0
$ node -v
v5.12.0
$ npm -v
3.8.6

プロジェクト作成

$ mkdir project
project $ cd project
project $ npm init
    :    // 以下、エンターでOK(package.jsonが作成される)
project $ npm install --save-dev gulp
project $ touch gulpfile.js // あとでgulp実行内容を書く
  • こんなファイル構成になりました。
project/
    |-- node_modules/
    |    |    :
    |    |-- gulp/
    |
    |-- gulpfile.js
    |-- package.json

スクランナー(gulp)の実装

  • gulpfile.js
// src -> dist

var gulp = require('gulp');
var pkg = require('./package.json');
var imagemin = require('gulp-imagemin');

var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');
var header = require('gulp-header');
var webserver = require('gulp-webserver');

// htmlファイルコピー
gulp.task('html', function() {
    gulp.src('./src/index.html')
        .pipe(gulp.dest('./dist'));     // htmlコピー
});

// 画像ファイルコピー
gulp.task('img', function() {
    gulp.src('./src/img/*.jpg')
        .pipe(imagemin())               // 画像圧縮
        .pipe(gulp.dest('./dist/img')); // 画像コピー
});

// JS作成
gulp.task('js', function() {
    gulp.src('./src/coffee/*.coffee')
        .pipe(plumber())
        .pipe(coffee())             // JS変換
        .pipe(concat('all.min.js')) // JS結合
        .pipe(uglify())             // JS圧縮
        .pipe(header('/* copyright <%= pkg.name %> */', {pkg: pkg})) // ヘッダー
        .pipe(gulp.dest('./dist/js'));
});

// watch
gulp.task('watch', function() {
    gulp.watch('./src/coffee/*.coffee', ['js'])
    gulp.watch('./src/*.html', ['html'])
});

// webserver reload
gulp.task('webserver', function() {
    gulp.src('./dist')
        .pipe(
            webserver({
                host: '192.168.33.10',
                livereload: true
            })
        );
});

gulp.task('default', ['html', 'img', 'js', 'watch', 'webserver']);

スクランナーの実行

$ gulp
  • 上記gulpfile.jsで実行される内容
    • src/ディレクトリ下のhtmlファイルをdist/下にコピー
    • src/img/ディレクトリ下のjpgファイルをdist/img/下に圧縮してコピー
    • src/coffee/ディレクトリ下のcoffeeファイルをdist/js/下にJSに変換、連結・圧縮してコピー
      • おまけでヘッダーにプロジェクト名を挿入している
    • 上記の一通りを実行しつつローカルサーバー起動、watch待機する。
      • JS/htmlファイル更新時にwatch
      • サーバーはwatch動作時にreload

画像ファイル名の難読化や、sassコンパイルなども同じ要領で追加していけると思います。 ざっくり何をやっているのか、どのようにやっているのかがわかりました。

PostgreSQLのインストール

UbuntuPostgreSQLをインストールしてみました。 使い方についてもあまり知らなかったので、メモがてらCUI操作まで描いておきます。

パッケージのインストール

  • こちらで本体、クライアントなど一通りの関連パッケージがインストールされます。
$ sudo apt-get update
$ sudo apt-get install postgresql
$ sudo aptitude install libpq-dev
  • libpq-devはGemにて導入する際に必要とされたので、一応入れておくことにしました。

起動・終了コマンド

  • MySQLやNginxとだいたい同じ
$ sudo service postgresql start
$ sudo service postgresql stop
$ sudo service postgresql restart

コンソール

  • postgreというユーザーが作成されるので、最初はこちらでアクセス
$ sudo su - postgres // スイッチユーザー
$ psql  // PostgreSQL起動

postgres=#
  • ついでにvagrantに権限付与(suしなくてすむようになる)
    • ロール作成と、ユーザー名と同一のDatabase作成をおこなう。
postgres=# create role vagrant with createdb login;
CREATE ROLE
postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of
-----------+------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication | {}
 vagrant   | Create DB                                      | {}

postgres=# create database vagrant;
CREATE DATABASE
postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 vagrant   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
(4 rows)

postgres=# \q
↑終了コマンド
  • ちなみに、権限削除は「drop role vagrant;」となる。

GUIツールの利用(Mac

こちらのツールを利用してみました。

f:id:tak_taniguchi:20160627165428p:plain

設定はこんな感じ、vagrantユーザーでvagrantSSHしつつ、ローカル(Vagrant内)のPostgreSQLにつなぐ感じです。 vagrantユーザーログイン時のデフォルトパスワードは「vagrant」です。

Vagrant上でNginx+Unicornサーバー設定

rails serverコマンドでアプリケーションサーバーを立ち上げるのも手間になってきたので、Unicornを入れてみました。 こちらは前回記事の続きの作業になります。

tak-taniguchi.hatenablog.com

Unicornをインストール

  • 以下、Vagrant内での作業になります。
  • Gemインストールをおこなう
gem install unicorn
  • bundle installをおこなう
$ cd /vagrant/myapp  # プロジェクトディレクトリ
$ vi Gemfile
gem 'unicorn' # 書き足す

$ bundle install
  • unicorn.rbコンフィグの作成
$ vi /vagrant/myapp/config/unicorn.rb # 以下のような内容で新規作成する
rails_root = File.expand_path('../../', __FILE__)
rails_env = ENV['RAILS_ENV'] || "development"

worker_processes 2
working_directory rails_root

listen "/tmp/#{rails_env}_unicorn.sock"
pid "/tmp/#{rails_env}_unicorn.pid"

stderr_path "#{rails_root}/log/#{rails_env}_unicorn_error.log"
stdout_path "#{rails_root}/log/#{rails_env}_unicorn.log"
  • Nginx側設定
  • conf作成
    • 以下の{RAILS_ROOT}はプロジェクトルート、{LOG_PATH}はnginxがログを残すパスを指定。
    • 指定ドメインはローカルなので、globalに存在しないドメインがよいです。
$ vi /etc/nginx/site_avabable/virtualhost-myapp.conf  # nginx.confでincludeされる
upstream unicorn {
  server unix:/tmp/development_unicorn.sock;
}

server {
  listen 80;
  server_name {指定ドメイン};
  root {RAILS_ROOT}/public;

  access_log {LOG_PATH}/access.log;
  error_log {LOG_PATH}/error.log;

  client_max_body_size 100m;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

$ ln -s /etc/nginx/site_avabable/virtualhost-myapp.conf /etc/nginx/site_enable/virtualhost-myapp.conf
$ sudo service nginx restart
  • Uniornを起動
$ bundle exec unicorn -D -c config/unicorn.rb -E development
  • ローカルPCのhosts修正
    • この時点でhttp://{指定ドメイン}/が閲覧可能になる。
    • 以下、ローカルPC(Mac)での作業になります。
$ sudo vi /etc/hosts
# VagrantIPアドレスと指定ドメインをスペースで区切り記載
# グローバルに存在するドメインを記載すると、アクセスがVagrantに向いてしまうので注意!
192.168.33.101  {指定ドメイン}

コンフィグ等はこちらの記事にあったものを少し書き換えました。 - Rails4.2 を Nginx + Unicorn で動作させる - Shred IT!!!! - rails + nginx + unicorn連携 - Qiita

動作確認方法

  • Unicornプロセス
    • 以下のコマンドでmaster及びworkerプロセスが確認できる。masterをkillでUnicornを終了できる。
$ ps aux|grep unicorn
  • Unicornで動いているか
    • デフォルトのままであればプロジェクト下のlog/development.logにアクセスログが落ちる。

developmentなんで開発系までですが、ざっくり動作しました。

Vagrant + Nginx + Ruby on Railsを動かしてみる

かなり遅まきながら、Rubyに触れる機会がありVagrantでのセットアップまでを試してみました。 RubyVagrantにインストールし、Railsの新規プロジェクトを起動・ブラウザ確認するまでの工程をざっくり記載しました。

コマンドで迷ったところをメインにまとめてあるので、パッケージ不足のエラーなどは出力から判断し都度いれることで解消できると思います。

Vagrant構築

大まかな流れは以前やったので割愛します。

Rails Server起動時にport:3000を利用するので、Vagrantfileの設定を事前におこないます。 port:8080 --> 80 に加えてport:3000 --> 3000を追記します。 (わたしの手元環境ではphp/ruby/golangが混在しています…)

  • ローカルPCのVagrantfile

    config.vm.network "forwarded_port", guest: 80, host: 8080, id: "http" config.vm.network "forwarded_port", guest: 3000, host: 3000, id: "http"

Rubyをインストール

  • 以下、Vagrant内での作業になります。
  • rbenvをインストールする(これでrubyのバージョン管理をさせる)
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
  • パスを通す
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
  • rubyバージョンを切り替える
$ rbenv install 2.3.0
$ rbenv global 2.3.0
$ rbenv rehash
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

プロジェクト構築

  • 引き続きVagrant内での作業になります。
  • まずはgemをインストールします。
    • Bundlerもここで入れてしまいました。
$ sudo aptitude install rubygems
$ gem install rubygems-update // 自分を更新
$ gem -v
2.5.1
$ gem install bundler
  • gemコマンドでrailsをインストール、プロジェクト作成
$ gem install rails
$ rails new myapp
  • 初回はbundle installでコケますので、以下のエラーに対処してリトライする
    • sqlite3をインストールする

      $ sudo apt-get install sqlite3 libsqlite3-dev

    • myapp/Gemfileでコメントされている'therubyracer'のコメント解除
$ cd myapp
$ bundle install // リトライする

bundleのインストールパスについて

後々知ったのですが、bundle管理のパスは設定でき、プロジェクト下のvendor/bundleに保持するのが定石のようです。

$ bundle install --path vendor/bundle

こちらを実行することで、プロジェクト下に.bundle/configファイルとvendor/bundleディレクトリが作成されます。 プロジェクト単位でパッケージ管理ができ、本来用途に近しい実装ができます。

rails serviceを起動

こちら最後につまずきました。 localhostruby専用だったら問題ないかと思いますが、今回は既存を残しつつport:3000を提供しているので、-bオプションで以下のIPを指定します。

vagrant: ~/myapp $ bundle exec rails server -b 0.0.0.0

こちらのブログで説明されていました。

Vagrant で Ruby on Rails 4 の環境構築 - Qiita

補足・RubyMineにてVagrantプロジェクトを設定

JetBrainのIDEを以前から利用していたのでRubyMineも使ってみたのですが、非常に便利に使えそうです。

  • Ruby SDK and Gems」の+アイコンから「new remote」を選択
  • Vagrant環境のRubyパスを指定(rbenvでバージョン管理しているので、そちらを選ぶ)

ここまでおこなうと、基底も含めてRailsのコードをメソッドジャンプできるようになります。 最初にフレームワークを把握するのに便利そうなので、ぜひとも最初に設定してみましょう。

f:id:tak_taniguchi:20160614160028p:plain

Unity Cloudで自動ビルドからSlack通知までを試してみました

Unityビルドの悩み

これまで実機での確認はPCにAndroid端末を接続して行っていました。 ただ、こちらの方法だと以下の懸念がつきまといます。

  • ビルドが環境に依存する。(ProjectやSceneを保存し忘れる、Unityバージョンを揃えそこねるなど)
  • 複数のプラットフォームでのビルドが手間。
  • ビルド中、何も出来ない。
  • テストビルドを他人に共有しづらい。

業務での開発であればビルドサーバーを用意することで連携をとっていると思いますが、個人開発だとそこまではなかなかできませんでした。 ところが最近、UnityのCloud Buildを利用することでこれらを一気に解決することができました。

https://unity3d.com/jp/services/cloud-build

基本的には無料で使える!

Asset Storeなどに登録していれば、同様のアカウントで利用が開始できます。 Unityでプロジェクトを作成し、Accountとのひも付けを行う方法がもっとも手っ取り早いです。

  • 右上ボタンからアカウントを設定できます。

f:id:tak_taniguchi:20160523172642p:plain

  • アカウントを設定すると、Serviceウィンドウ(⌘0キーで表示)にクラウドプロジェクトを作るボタンが出てきます。

f:id:tak_taniguchi:20160523172839p:plain

  • 既存プロジェクトと結びつける事もできます。
  • 「Select organization」ではプロジェクトの所属する組織を選択します。
  • こちらはアカウントに紐付く情報でチーム名など決めていただけば良いと思います。
  • 事前にクラウド側で設定しておくことでプルダウン選択できます。→ https://id.unity.com/organizations

  • 設定が完了すると、各ステータス表示画面になります。

f:id:tak_taniguchi:20160523172847p:plain

  • SETTINGタブで「UNITY PROJECT ID」が確認できます

この時点ではクラウド上にローカルプロジェクトと紐ついたシンボルができたに過ぎません。 Serviceウィンドウの右上に「Go to Dashboard」のリンクが出ていると思うので、そちらをクリックしウェブ側の設定ページを開きましょう。

GitHubやBitBucketと連携する!

上の続きで、Cloud Build設定ページから新規作成したプロジェクトを選んでください。 わたしは仮に「Test」を作成しました。 f:id:tak_taniguchi:20160523175022p:plain

「さあ、始めましょう」から順次、コード管理のサーバーURLやコラボレータの設定ができます。 (GitHubやBitBucketが使えます) サーバーURLはgit@github.com:user_name/project.git のようなパスを与えてやることでチェックアウトが可能かを調べてくれます。 Privateなリポジトリの場合はUnityが発行した公開鍵をコード管理プロジェクト側のデプロイ鍵に設定する必要があるのでご注意ください。

プラットフォームなどの設定も完了するとファーストビルドが行われます。

f:id:tak_taniguchi:20160523180254p:plain

フリープランのビルドはそこそこ時間がかかるのでしばらく放置しておきましょう。 グリーンのチェックが入ればビルドは成功です。 (失敗・成功かかわらずオーナーにはデフォルトで完了メールが飛んできます)

メールやSlackでビルド完了を通知、テストユーザーも複数登録できる!

メールはデフォルトでオーナーに送信、それ以外のアドレスも「コラボレータ」タブから追加できます。 Slackは「Notifications」タブにあるボタンから設定できます。

f:id:tak_taniguchi:20160523180702p:plain

開発用にチャンネルを作り、コードのコミット、ビルド結果などを纏めておくと非常に便利です! f:id:tak_taniguchi:20160523181651p:plain

現在の難点は無料だとビルドの連投ができず、1時間に1回程度までの制限があります。 とはいえ、これだけの機能が無料で利用できることは非常に便利ですし、個人開発も捗りますw

今後も良い機能がどんどん無料提供されていくことを願いつつ、技術習得に日々邁進していきたいと思います。

さくらVPSの独自ドメインサーバーからgmailにメールを転送

さくらVPS独自ドメインを取得していたのですが、メールアドレスとして利用していなかったのに気づき、せっかくなので設定してみました。 これまでメールサーバーを構築したことがなかったので、基本的なことから勉強しました。

今回の要件

  • さくらVPS独自ドメインでメールを受け取る。(仮にadmin@example.com
  • サーバー環境はubuntu独自ドメインの設定(Aレコード)は終わっている。
  • サーバーに持たず、gmailに転送する。
    • セキュリティやフィルタの実装を考えると楽そうだったから。

マイルストーン

  • SMTP(送信)にPostfixを入れる。
  • POP/IMAP(受信)にDovecotを入れる。
  • name serverの設定をおこなう。
  • 転送設定を設定する。

作業

PostfixDovecotをインストールする。

// インストール
$ sudo aptitude -y install postfix sasl2-bin dovecot-core dovecot-pop3d dovecot-imapd

// postfixのconfigをカスタマイズ
$ sudo cp /usr/lib/postfix/main.cf /etc/postfix/main.cf
$ sudo vi /etc/postfix/main.cf

// リスタート
$ sudo service postfix restart

// dovecotのconfigをカスタマイズ
$ sudo vi /etc/dovecot/dovecot.conf
$ sudo vi /etc/dovecot/conf.d/10-auth.conf
$ sudo vi /etc/dovecot/conf.d/10-mail.conf
$ sudo vi /etc/dovecot/conf.d/10-master.conf
$ sudo vi /etc/dovecot/conf.d/10-ssl.conf

// リスタート
$ sudo initctl start dovecot

いろいろ割愛しましたが、configの設定は以下を参考にさせていただきました。

MXレコードを追加

さくら会員メニュー「会員メニュー > ドメイン > ネームサーバメニュー」からMXレコードを追加する。 追加方法はさくらVPSにキャプチャー付きで掲載されていました。

f:id:tak_taniguchi:20160407175555p:plain

転送設定

$ sudo vi /etc/aliases
$ sudo cat /etc/aliases
# See man 5 aliases for format
admin:             xxxxxxxx@gmail.com # 転送元メールアカウント: 転送先にしたいメールアドレス
postmaster:    root

$ sudo newaliases

挙動確認

tail -f /var/log/mail.log

上記エイリアス設定で、admin@example.com宛メールがxxxxxxxx@gmail.comに転送されます。

Go言語を試してみる

PHPに飽きたので、Golangなどに手を出してみました。

インストール

Macで実行環境を構築するにはbrew installが簡単そうだったので、こちらを試しました。

$ $ brew install go
==> Downloading https://homebrew.bintray.com/bottles/go-1.5.2.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring go-1.5.2.el_capitan.bottle.tar.gz
==> Caveats
As of go 1.2, a valid GOPATH is required to use the `go get` command:
  https://golang.org/doc/code.html#GOPATH

You may wish to add the GOROOT-based install location to your PATH:
  export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> Summary
🍺  /usr/local/Cellar/go/1.5.2: 5336 files, 273M
$ go
Go is a tool for managing Go source code.
 :

入りました。

パスを通す

~/.bashrcなどに追記しておきます。

# golang
export GOPATH=$HOME/.go
export PATH=$GOPATH/bin:$PATH

Hello World

公式のコードをローカルで動かしてみます。 https://golang.org/

// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}

そのまま実行とビルドしてからの実行をテスト

$ go run hello.go
Hello, 世界
$ go build hello.go
$ ./hello
Hello, 世界

自動整形を試してみる

スペースを詰めてみる

func main(){

↓fmtを実行

$ go fmt
hello.go

戻される。

func main() {

改行してみる

func main()
{

↓fmtを実行

$ go fmt
hello.go:8:1: expected declaration, found '{'
exit status 2
$ go build hello.go
hello.go:8:1: expected declaration, found '{'
exit status 2

ビルドすらできない。

このあたりがPHPと違って素直に嬉しい。 しっかり基礎を覚えて、きれいにコードを書いてみたい。

日本語訳のチュートリアルを見つけた。 http://go-tour-jp.appspot.com/welcome/1 とりあえず、ここを頑張ってみようと思う。