hkのweblog

ひよっこエンジニアがにわとりになるまでの軌跡

Docker上にrails環境を作ろうとして苦労した話

先日、Docker上にrailsの開発環境を作ったのですが、やたら苦労して丸一日を費やしてしまいました。ということで簡単に手順をまとめておきます。

Dockerfileを作るまで

  • Dockerのインストール
    まず、Dockerをインストールします。今回はWindows10にインストールしました。こちらの公式サイト「Get Docker for Windows[stable]」からインストーラーをDLしてそれに沿って進めました。簡単ですね。

  • Dockerfileを書く
    今回ベースとなるDockerイメージはCentOS6.5にしました。rubyのバージョンは2.3.3です。 ここに必要なものを入れていくためのDockerfileを書きます。今回はDockerfileが社内に用意されていたのですが、こいつがあちこちひっかかり、丸一日苦しむことになりました。。
    以下にDockerfileの一部を書いておきます。長いのでだいぶ端折ってます。

FROM hasedon/centos6.5.1:latest

#色々インストール
RUN yum install -y tar
RUN yum install -y openssl-devel readline-devel zlib-devel
RUN yum install -y git
# 中略

# rubyインストール
RUN git clone git://github.com/rbenv/rbenv.git /usr/local/rbenv
RUN git clone git://github.com/rbenv/ruby-build.git /usr/local/rbenv/plugins/ruby-build
ENV PATH=$PATH:~/.rbenv/bin:~/.rbenv/shims
RUN rbenv install 2.3.3
RUN rbenv rehash
RUN rbenv install global 2.3.3
RUN gem update --system
RUN gem install --no-ru --nordoc rails
RUN gem install bundler
RUN rbenv rehash

コンテナを実行する

  • docker buildする
    先に書いたDockerfileを任意の場所に配置し、コマンドラインツールでDockerfileのある場所に移動、以下のコマンドを実行します。 こんな感じでユーザー名も設定することも可能です。(不要の場合は–build-arg name=[user name]を削ればOK)
docker build --build-arg name=[user name] ./

ここで docker image を実行すると、今buildしたイメージを確認できます。

が!自分の場合、RUN rbenv install 2.3.3のところでこけました…
色々調べたところ、インストールの際にcurlが走るようなのですが、こいつのバージョンが古すぎてダウンロードに失敗するようです。ググってみると同じ問題に直面している方を何人か見つけました。
Dockerfileの途中にRUN curl --versionと書いてビルドするとcurlのバージョンが表示されます。自分の場合は7.19.4でした。2017年8月時点で7.55.1が最新版です。

仕方ないので DockerfileのRUN rbenv install 2.3.3以下こけてしまう行はコメントアウトしてビルドし、問題を先送りします()。これでとりあえずは新しいイメージができます。

  • docker runする
    まず、 docker ps を実行すると、実行中のコンテナが表示されます。現時点で何も動いていないことが確認できるはず。 次に
docker run -v [ホストディレクトリのパス]:[コンテナのパス] [イメージ名] /bin/bash

ここでコンテナIDが返されると実行できているはずです。上記のようにマウントしなくても良いのですが、マウントしておくと後々windows上から触れるので便利です。
当然何らかのエラーを返す場合もあるようです。自分の場合はエラーは返さないけど、入力待ちにもならず…みたいな状態になりました。
原因究明に半日費やしましたが、ヤケクソでwindowsごと再起動したらうまくいくようになりました。Dockerそのものがうまく動いてなかったのか何なのか。

rubyを入れるまで

  • curlのバージョンをあげる
    先ほど後回しにした問題を解決すべく、まずは実行中のコンテナに入ります。 docker -it exec [コンテナID] /bin/bashで入れます。
    続いてcurlのバージョンを上げていきます。以下を実行していけばOK。
wget https://curl.haxx.se/download/curl-7.55.1.tar.gz
tar xfvz curl-7.55.1.tar.gz
cd curl-7.55.1 
/.cofigure --enable-libcurl-option
make
make install
  • 環境変数の設定
    これでrbenvが入れられそうなものですが、その前にrbenv周りの環境変数を設定してやる必要があります。
    どうもDockerfileに書いたやり方ではうまくいきませんでした。.bashrcとかに書いてやってもいいと思います。
    export PATH=$PATH:~/.rbenv/bin:~/.rbenv/shimsでとりあえず設定。

  • rubyのインストール
    ようやくrubyを入れられます。 先ほど後回しにしたrbenv install 2.3.3以降を実行すれば完了です。 おつかれさまでした。

やってみての所感

いきなりDockerfileを書いてbuildするとあちこち問題が起こるので、ベースのイメージを持ってきて、そこに一つ一つ入れたいものを入れていくほうがいいのかもしれません。
で、うまくできたらDockerfileにまとめておく、と。環境変数は結局どうやって書けばいいのか分からず…

Cookieを使ってユーザーごとに表示を出し分けてみた

あっという間に7月も終わりですね。目標にしていた月2更新が早くも途絶えそうなので記事を書きます。

先日、仕事で
「うちのサイトに登録して2週間以内の人にはこのポップを表示するようにしてほしい。でも、そのポップの隅の×印を押したら2週間以内だとしてもポップが表示されないようにしてほしい。クッキーとか使えばできるんでしょ?」
みたいな依頼を受けました。

でも、僕Cookie使った実装をしたことがなかったんですよね…恥ずかしながら。

今回は自前フレームワーク的なものが用意されていたので簡単に実装できたのですが、一度簡単にCookieの基礎知識をまとめておいたほうがいいなあと思って、今この記事を書いているわけです。


そもそもCookieとは

  • WebサーバーからブラウザへのHTTPレスポンスのヘッダーを利用した小さな情報(ファイル)。key-value型(クッキー名-値)の情報。
  • サイトアクセス時にWebサーバー側がCookieをsetし、ブラウザにはCookieファイルが保存される。
  • サイト再訪時、ブラウザはHTTPリクエストのヘッダーにCookieを入れてWebサーバーに送信する。
  • Cookieを使えばWebサーバー側はそのアクセスが初めてのアクセスなのか再訪なのかを判断できる。
  • PHPでは以下のようにCookieをsetする(らしい)。
setcookie(クッキー名, 値, Cookieの保存期間);
例えばこんな感じ
setcookie('hoge', 'fuga', time() + 60 * 60 * 24 * 30);
タイムスタンプの部分は
time();で現在日時を取得。その後は「秒 * 分 * 時間 * 日」。
上記の例では30日間Cookieを保存することになります。
なお、
setcookie('hoge', 'fuga', time() - 1);
のように現在より前の時間を設定してやるとCookieを削除することができます。

setcookieはドメイン名とかこれ以外にも引数をつけることができるらしいのですが、あんまり使わないようですね。
わざわざDBにデータ持たせるほどでもないかなーという時(今回のケース)や、まだログインはしていないけど再訪者をチェックして表示を出し分けたい時、ECサイトのカート機能やレコメンド機能で使うことが多いようです。


今回の場合、

  1. サイトアクセス時にCookieをgetする(close_pushed=1を持っているかチェックする)。
  2. Cookieがあった場合
    1. ポップを表示しないよう、jsでポップ部分のdiv要素を削除する。
  3. Cookieがなかった場合
    1. ポップ部分はそのまま表示する。
    2. ×ボタンが押された場合、ボタンのクリックイベントで関数を実行。その中でCookieをsetする(close_pushed=1をsetする)。と同時にjsでポップ部分のdiv要素を削除する。

という流れになりました。

前述の通り、今回はjsで作った自前フレームワーク的なものが用意されていたので、それを使って以下のような感じで簡単に書けました(一部にjQuery使用)。

<!-- 帯の部分のみ抜粋 -->
<div id="pop">
  <p>会員登録ありがとうございます。</p>
  <span><a href="#" onclick="closePop();return false;">×</a></span>
</div>
// アクセス時に実行
(function () {
  var cookie = new FwCookie(); // フレームワークの呼び出し
  // getCookie(クッキー名);でCookieの値を取れる
  if (cookie.getCookie('close_pushed')) {
    $('#pop').remove();
  }
}());

// ×ボタンがクリックされたら実行
function closePop() {
  var cookie = new FwCookie();
  // setCookie(クッキー名, 値);でCookieをsetできる
  cookie.setCookie('close_pushed', 1); 
  $('#pop').remove();
}

因みにCookieの保存期間はフレームワーク側で一律に設定しており、使う際にいちいち記述する必要が無いようになっていました。


セッションとの違いとかもまとめたかったのですが、長くなりそうなのでとりあえずこんなところで。

書いている人&このブログについて

書いている人について

こんにちは。hkと申します!

経歴

ECやFintech関連のサービスを展開する都内のIT企業でwebエンジニアをしています。職業エンジニア歴は(この記事を書いている時点で)まだ3ヶ月です。

学生時代に金融や経済を学んだものの興味が持てず、新卒でシステムベンダーに就職。過酷な環境に心を折られて1ヶ月で退職するも慌てて受けた公務員試験に合格。官公庁で3年働く間にプログラミングを独学し、今の会社に採ってもらいました。よかったよかった。

使っている言語・技術

現在の仕事はJava(Spring, Seasar2)、PHP(Zend Framework)あたりを使ったサーバーサイドの開発が中心です。OracleMySQLは触りますが、インフラは疎めです。フロント方面ではjQueryくらいしか触りません。

社内では他にRubyやAngular、Go、Pythonあたりを書く人もいますが、今私の携わっているサービスは比較的歴史が古いため、仕方ない気もします。

プライベートではPHPPythonでサイトを作ったことがあります。他には過去にRaspberryPiを弄ったり、iOSに手を出したり。最近はJS全般に興味津々、といったところです。

 

このブログについて

アウトプットによるスキルの定着を図りつつ、備忘録を兼ねてこのブログを始めることにしました。月2回の更新が目標です。

基本的にはその時々に学んだ技術をソースコードを交えてまとめていく感じのブログになると思います。「最近読んだ本や技術書でこれが良かった」みたいな記事も書くかもしれません。

正直なところ、ブログはほとんど書いたことがない上にマークダウンも書けるか怪しいので最初のうちは読み辛いブログになってしまうかもしれません。レベル的には未熟でも無味乾燥な記事にならないようにしたいです。少しずつ頑張っていこうと思います。

以上どうぞよろしくお願いします。