【セキュリティ対策は大丈夫 ?】SSL証明書の新規発行、更新手順をまとめてみた。【POODLE, RC4, etc.】

こんにちは。TECH DRIVEの齋藤です。

先日、管理しているサイトのSSL証明書の期限が切れそうになっているのに気づき慌てて更新しました。

毎回思うのですがSSLの更新って結構面倒ですよね。
私自身も手順を忘れることがあるのでまとめてみました。

今回は更新でしたが新しくCSR*1を発行するので新規発行と手順にほぼ変わりはないです。

環境

  • OS - Amazon Linux
  • SSL認証局・種別 - COMODO・PositiveSSL
  • Web Server - Apache + OpenSSL
  • 証明書の販売サイト - SSLストア

 ※ 下記手順はCentOS、他の認証局でも使えるかと思います。

AWS Certificate Manager

AWS使っているならACM(AWS Certificate Manager) 使えよって思うかもしれません。

私も最初はACMを使おうと思いました。
ただACM利用には下の条件があります。

f:id:shoheis:20170313115403p:plain

今回設定するインスタンスはElastic Load Balancingを使っていませんでした。
なのでこれから書く手順が必要だったわけです。

バックアップをとる

運用しているサイトでSSL証明書の設定をする時は必ず事前にサーバーや編集するファイルのバックアップをして、いつでも元に戻せるようにしてから作業してください。

発行手順

  1. 証明書の購入(新規 or 更新)とアクティベート
  2. アクティベートに必要なCSRの作成
  3. ホスト証明書の設置
  4. 中間証明書の作成
  5. 中間証明書の設置
  6. SSLの設定
  7. セキュリティのテストと強化

証明書の購入とアクティベート

まずはお使いのSSLを管理しているウェブサイトで証明書を購入しましょう。
購入後は証明書のアクティベート(署名の申請)が必要です。

私はSSLストアというサイトを使っているので、証明書の購入とアクティベートは表の流れになりました。

項目 購入の参考サイト アクティベート
新規証明書の購入 こちら*2の手順7まで 左記「購入の参考サイト」の手順8から
更新用証明書の購入 こちら 新規証明書の「購入の参考サイトの手順8」から

またアクティベートの際にはCSRが必要になります。

CSRの作成

まずはCSR作成に必要なプライベートキーを作成します*3

サーバーに接続し、 /etc/pki/tls/private/ に移動しましょう。

$ cd /etc/pki/tls/private/

新しいプライベートキーを作成します*4

$ sudo openssl genrsa -out private.key 2048

プライベートキーにアクセス制限をかけます*5

$ sudo chown root.root private.key
$ sudo chmod 600 private.key

作成したプライベートキーを使いCSRを作成します。

$ sudo openssl req -new -key private.key -out csr.pem

CSR作成のための情報の入力します(下表はCSRの入力例)。

項目 意味
Country Name 国コード JP
State or Province Name 都道府県名 Tokyo
Locality Name 市区町村名 Chuo-Ku
Organization Name 組織名 Example Corp
Organizational Unit Name 部署名 Example Dept
Common Name コモンネーム*6 www.example.com
Email Address 管理者のメールアドレス someone@example.com

参考

アクティベート時に貼り付けるので作成したCSRの中身をコピーしておきましょう。

CSRが作成できたらそれを使ってアクティベート を完了します。
アクティベートが完了するとSSL認証局からメールが届きます。
メールに添付してある証明書(ウェブの管理画面からでもダウンロードできます)を設置していきましょう。

ホスト証明書の設置

ホスト証明書はCOMODOのPositiveSSLではメールでYour PositiveSSL Certificate となっているファイルです。 「www_example_co_jp.crt」のような名前かと思います。
/etc/pki/tls/certs に移動します。*7

$ cd /etc/pki/tls/certs

ホスト証明書をこのディレクトリにあげて*8、アクセス制限をかけます。

$ sudo chown root.root www_example_co_jp.crt
$ sudo chmod 600 www_example_co_jp.crt

ホスト証明書の設置は以上です。

中間証明書の作成

認証局によっては中間証明書(または、つなげて一つのファイルにする作業)が必要になります*9
つなげる際は順番が大事なようです(このままコピーして使えばOKです、中間証明書の名前は任意です)。

$ cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt > intermediate.crt

中間証明書の設置

再度サーバーに接続後、 /etc/pki/tls/certs に移動します。
中間証明書をこのディレクトリにあげて
ホスト証明書より緩い形ですが、アクセス制限をかけます。

$ sudo chown root.root intermediate.crt
$ sudo chmod 644 intermediate.crt

中間証明書の設置は以上になります。

SSLの設定

mod_ssl の設定ファイル/etc/httpd/conf.d/ssl.conf を編集します。
ssl.conf をエディタで開き、下記の設定を追加しましょう*10

SSLCertificateFile /etc/pki/tls/certs/www_example_co_jp.crt
SSLCACertificateFile /etc/pki/tls/certs/intermediate.crt

念のためhttpdの文法チェックをしておきましょう。

$ apachectl configtest

「Syntax OK」と出たらサーバーを再起動します。

$ sudo service httpd restart

SSLの設定は以上になります。


参考として、別のサイトではSSLの設定を下記のようにしていました。
場合によってはこの書き方をしないと設定できないのかもしれません。

SSLCertificateFile /etc/pki/tls/certs/www_example_co_jp.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key
SSLCertificateChainFile /etc/pki/tls/certs/intermediate.crt

これで「https」でサイトにアクセスできるようになっているはずです。

セキュリティのテストと強化

デフォルトの状態だとセキュリティが弱い場合があります。Qualys SSL Labs などを使用して現在のセキュリティの強さをチェックしましょう。


Amazon Linuxのデフォルトの設定だと下記の脆弱性に対処できていません。

  • POODLE脆弱性
  • RC4 暗号化方式の脆弱性
  • 前方秘匿性の欠落による脆弱性

私も最初にチェックした時はこのような状態でした(Future Grade やばいですね)。

f:id:shoheis:20170313200218p:plain

上から順に対処していきます*11

POODLE脆弱性

/etc/httpd/conf.d/ssl.conf を編集します。SSLProtocol ディレクティブをコメントアウトします。

# SSLProtocol all -SSLv2

その行のしたに下記を追加します。

SSLProtocol -SSLv2 -SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2
RC4 暗号化方式の脆弱性、前方秘匿性の欠落による脆弱性

「前方秘匿性の欠落による脆弱性」の対処が「RC4 暗号化方式の脆弱性」の対処を含む形になるので、変更は1箇所で大丈夫です。
SSLCipherSuite ディレクティブを探し、コメントアウトされていた場合はそのままの状態でその下に下記を追加します。

SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA


また再起動の前にはhttpdの文法チェックをしておきましょう。

$ apachectl configtest

「Syntax OK」と出たらサーバーを再起動します。

$ sudo service httpd restart

この状態で再度Qualys SSL Labs でチェックしてみましょう。ランクが上がっているはずです。

f:id:shoheis:20170313200958p:plain

以上でSSL証明書の設定は完了になります。お疲れ様でした!

主な参考サイト

今回は特にAWSのチュートリアルにお世話になりました。セキュリティの強化(特にRC4と前方秘匿性)は前回の更新時にはわからなかったので助かりました。下記サイト以外にも様々なサイトの助けを得ながら設定しました。

*1:認証局に提出する署名リクエストです。作成にはプライベートキーが必要で、セキュリティ上長年同じプライベートキーを利用するのは好ましくないのでそのキーと合わせて再作成します。参考

*2:RapidSSLですがPositiveSSLと手順に変わりはありません。

*3: Amazon Linux をお使いの方かつ新規作成時は既存のホストキー 「/etc/pki/tls/private/localhost.key」 をプライベートキーとして使ってもOKです

*4: よりセキュリティの強いキーの生成方法もあります。参考

*5: すでに private.key の所有者はrootなはずなので chownはやらなくていいのですが念のため書いています

*6:ユーザーがブラウザに入力するウェブアドレス

*7: 元の自己署名ホスト証明書 localhost.crt がある場合はそれを /etc/pki/tls/certs ディレクトリから削除します。

*8: 自分は scp でアップロードしました。 参考

*9:COMODOのPositiveSSLでは必要でした。他の認証局では必要がないかもしれません。適宜調べてみてください。

*10: 更新時に「ホスト証明書や中間証明書、プライベートキー」の「設置場所・ファイル名」が、前回の設定時と変わらない場合はssl.confを編集する必要はありません

*11:詳細はこのページを参考にしてください

ざっくりWebpack入門 Vol.2 babelでES6のトランスパイル

f:id:kabaneshi:20170307123107p:plain

こんにちは。TECH DRIVEの小笠原です。 Vol1につづき、本記事でもWebpackについてご紹介させていただきます。

今回はWebpackを使いES6で書かれたファイルのトランスパイルを行いたいと思います。

前提条件

  • 1.node.jsが導入済みのMac OSであること
  • 2.ES6やbabelが何か理解していること

Webpackについては、Vol1で触れておりますのでこちらに目を通していただければと。 dev.techdrive.top

また、本記事はWebpackでES6のトランスパイルを行うことに重きを置いておりますので、ES6やbabelの詳細に関しては割愛させていただきます。

Webpackの導入

今回はプロダクトが以下のディレクトリ構造であることを前提に進めます。

├── dist  // HTMLから呼び出されるJSファイル   
├── index.html  
├── src  
   └── js-es6 // ES6で書かれたJSファイル   
       └── person.js

まずは、前回同様にpackage.jsonファイルを作成しましょう。

npm init

つづけてWebpackのインストールを行います。

npm install --save-dev webpack

次に今回トランスパイルを行うために必要なloaderを導入します。

loaderについて

現状ES6を使用するには、babel等のトランスパイラが必要になります。
Webpackでは、loaderという機能を通しトランスパイラを使用します。

loaderは複数種類があり、npmとして提供されています。

loaderの導入

それでは、Webpack上でbabelを利用するために必要なloaderをインストールします。

npm install --save-dev babel-loader babel-preset-es2015

次にES6の文法を用いて書いたJSファイルを用意します。

src/js-es6/person.js

module.exports = function() {
    class Person {
        constructor(name) {
            this.name = name;
        }
        hello() {
            alert('My name is ' + this.name);
        }
    }

    var kevin = new Person('kevin')
    kevin.hello();
}

※ ES6の文法(class)を使用するため仰々しい書き方をしていますが、処理自体はブラウザ上でコードが実行された際、アラートダイアログが表示されるシンプルなものです。

設定ファイルの作成

続けてルートディレクトリ直下に設定ファイルを作成し、前回と同じようなノリでトランスパイル対象のファイル情報と出力先の情報等を書いていきます。
今回はloaderを使用するので、前回より設定項目が増えています。

webpack.config.js

module.exports = {
  // トランスパイル起点となるファイル(複数指定可)
  entry: {
    'person': './src/js-es6/person.js',
  },
  // トランスパイルされたファイルの出力先の情報
  output: { 
    path: __dirname + '/dist',  // パス情報
    filename: '[name].js'   // [name]には 、entryで指定したkey名が入る(今回の場合はperson)
  },
  module: {
    loaders: [  // 使用するloaderに関する情報を記載
      { 
        test: /\.js$/,  // トランスパイルを行うファイルの正規表現
        exclude: /node_modules/, // 除外ファイル 
        loader: "babel", // 使用するローダー
        query:{
          presets: ['es2015']
        }
      }
    ]
  }
};

loaderを扱うためmoduleloadersというプロパティを記載しています。
Webpackでは複数のloaderを利用することができるため、loadersの値は配列となり、loader毎に設定情報を記載します。

トランスパイル実行

これでトランスパイルを行うための準備ができました。
webpackコマンドを実行してみましょう。

webpack

dist直下にトランスパイルされたファイルが入っていれば成功です!
試しに出力されたJSファイルをHTMLファイルから呼び出し、期待通り動作することを確認してみましょう。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
</head>
<body>

<script src='./dist/person.js'></script>
</body>
</html>

アラートダイアログで「'My name is kevin」と出力されれば、今回の目的は達成です!

まとめ

いかがでしょうか?今回ご紹介させていただいたloaderという機能は、Webpackの核となる機能といっても過言ではありません。
今回は触れませんでしたが、loaderを使用することでJSファイルからHTML/CSSファイルや画像ファイルを呼び込むことができ、HTML/CSS/JSをまとめたコンポーネントを作成することも可能です。

loaderの詳細に関しては、今後の連載の中でも触れていきますが、まずは入門編として本記事をお役立ていただけたのなら幸いです。

初心者向けにできるだけ噛み砕いてみるオブジェクト指向 vol.2 言葉を整理してみる

はじめに

dev.techdrive.top

上記の続きです。規格化することで様々な恩恵があるということをたとえで書いてみたのですが、読んでくださった方から

「USBケーブルの話が実際のプログラミングでの言葉ともっと繋がっているとよりわかりやすそう」

との意見をいただいたので、当初予定していなかったこの回を挟んでみました。実際考えてみると、このようなブリッジになる回はあったほうが良さそうに感じます。

今回は言葉がたくさん出てきますが、今丸暗記する必要はありません。ただ、今後の説明の中にはこれらの言葉が出てきます(これらの言葉を出さずに説明していくと冗長になって、かえって分かりにくくなってしまうので、積極的に使っていきます)。もしも言葉に混乱してしまったら、ここへ戻ってきていただければイメージが掴みやすくなると思います。というわけで行ってみましょう。

オブジェクト指向の道具たち

クラス

オブジェクト指向という話が出てきた時に、クラスの話が出ないことはほぼないと思います。 クラスは独自に新しい型を作るための仕組みです*1。主に下記の二つが幹になっています。

プロパティ

あるオブジェクトが持っている変数です。 クラスによって複数の変数をまとめて扱える、と考えても大きな間違いではないと思います。構造体という言葉がわかる人には、この性質は構造体と同じ理解でも概ね問題ないでしょう*2。 USBケーブルの話だと、ケーブルの長さやケーブルの色などがプロパティになる可能性が高いです。 インスタンス(後述)が持つ変数なので「インスタンス変数」と呼ばれたりもします。

メソッド

あるオブジェクトが持っている関数です。 プロパティの説明に寄り添えば、クラスによって複数の関数をまとめて扱えるということになります。クラスが持っている機能と言っても良いかもしれません。 USBケーブルの話だと、ケーブルを挿して別のものと繋ぐことができるという「動作」がメソッドになると理解すると良いと思います。

インスタンス

クラスは設計図のようなものなので、実際に使う場合には製品をつくるような実体化が必要になります。 インスタンスは設計図を実体化したものです。当然設計図に書かれた内容の性質をインスタンスが持つことになります。インスタンスのことをオブジェクトという言葉で表現する場合もあります*3

f:id:ms2sato:20170227020045j:plain

参考のコード

参考に、rubyでクラスを使ったコードを書いてみました。

#######################################
# ケーブルのクラス(設計図)を作る
#######################################
class BasicUsbCable 
  def initialize(length)
    @length = length # @length というプロパティを用意しています
  end

  # 長さチェック用のメソッド。
  # 届かせたい距離を distance として与えると、そこに届くかを判断してくれます。
  def reachable?(distance)
    @length > distance # 届くかのチェックは @length が距離よりも長ければ届く
  end

  # 接続用のメソッド。
  # USBDeviceを実装している device を渡せばいい感じにつながります。
  def connect_to(device)
    # 何か動作がいろいろとあるはず
  end
end

#######################################
# 以下は実際にBasicUsbCableを使うところ
#######################################

# 長さ3のケーブルを一つ作る。cable1はインスタンスです。BasicUsbCableクラスで定義した機能を持ちます。
# [クラス名].new するとインスタンス化されます。
cable1 = BasicUsbCable.new(3) 

# cable1に対して長さチェックをするメソッドである reachable? を呼び出します
cable1.reachable?(5) # 5の長さは届かないので false
cable1.reachable?(2) # 2の長さは届くので true

device = GreatSpeaker.new # GreatSpeakerはUSBケーブルで繋げる別のクラス。deviceはインスタンスです。
cable1.connect_to(device) # connect_toで接続する。


# 同じBasicUsbCableから別のケーブルも作れます
cable2 = BasicUsbCable.new(10) # 長さ10のケーブルのインスタンスを cable1とは別に 一つ作る。BasicUsbCableクラスの機能はcable1と同様に持っています。
cable2.connect_to(device) # deviceには二本のケーブルが挿さっている

インターフェース or ダックタイピング

言語(今はその表現で許してください)によってはインターフェースという概念が提供されています。 これは持っているべきメソッド群をまとめた規格を表したものです。前回の内容でもありましたが、インターフェースが一致すると交換可能になります。

インターフェースが言語仕様に無いものの場合「持っているメソッドが(たまたまでも)同じだったら、同じ規格」と決めてしまうことがあります。 「アヒルのようなものはみんなアヒルとみなす」ということからダックタイピングと呼ばれています。

よく言われている機能や概念

道具としては上記のクラスを中心に行っていきますが、クラスの持つ機能や、よりよく作るための 概念として以下のようなものが有名です。

継承

あるクラスをもとにして、別のクラスを作ることです。 すでに完成しているものに対して新しい機能を追加したり、 途中まで作られた半完成品クラスを用意して、中身を入れて完成クラスを作るような方法で使います。 f:id:ms2sato:20170227022238j:plain

ポリモーフィズム(多態)

元々の意味合いとしては「同じ名前で機能の違うメソッドを色々なクラスに定義できる」ということなのですが、これだけだと何が嬉しいのかピンと来ないですよね。少し使いこなせると 「同じインターフェースを実装することで、差し替え可能にできる」というようなメリットを感じることができます。

このことはUSB規格を実装してさえいれば、別のケーブルを持ってきても挿し替えて使えたことと似ています。 f:id:ms2sato:20170227022244j:plain

カプセル化

「中のことをよく知らなくても使える」ように作ることです。 USB規格は「挿せば繋がる」ということを決めているので、USBケーブルの材質や、ケーブルの詳細な仕組みまでわからなくても使えることと似ています。 f:id:ms2sato:20170227022250j:plain

おしまいに

ちょっと色々な言葉が出てきていますが、よく出会う言葉でもあるので一度整理しておくと学習がはかどると思います。ちなみに、これらの基礎を私は多分「憂鬱なプログラマのためのオブジェクト指向開発講座」などで学んだと思うのですが(20年も昔の話なのでもう忘れてしまいましたが)、今の人たちはどんな方法で学ぶのでしょう。良書だったり、良WEBサイトがあったら是非知りたいです。 続き書きました

PR

TECH DRIVE協賛企業のサークルアラウンド株式会社では、プログラマーの成長を加速させるためのトレーニングを行なっています。フロントサイドからバックエンドまで各種バリエーションがございますので、ご興味がある方は是非以下のリンクより詳細をご覧ください。

JavaScript Climbing

JavaScriptに特化したトレーニング「JavaScript Climbing」を行なっています。
this、クロージャ、Class等、中〜大規模のフロントエンドの開発に臨にあたり、必須となるスキル習得を現役のWEBエンジニアが徹底してサポートします。
2週間の無料体験期間がございますので、ご興味がある方は是非以下のリンクより詳細をご覧ください。

circlearound.co.jp

Ruby Climbing

週1からはじめられる「Ruby」でWEB開発の基礎が習得できる塾です。現役のプログラミング講師&Rubyエンジニアがプログラミング入門からフレームワーク(Sinatra/Ruby on Rails)を使用した本格的なWEB開発の学習までをしっかりとサポートします。

ruby climbing

個別トレーニング

短期間でぐっと成長したい方は弊社主催の個別トレーニングがおすすめです。 トレーニング内容は、受講者の方の課題/要望をお伺いした上で、フルオーダメイドで作成させていただきます。 詳細は以下のリンクよりご確認ください。(応募者多数の場合には時間を別途ご用意する予定です)。

WEBプログラミング個別トレーニング

チーム開発トレーニング

既にある程度コーディングが可能なのでチーム開発を経験してみたいという方にはチーム開発トレーニングがおすすめです。 GitHub Flowを使用し、実践の開発フローを体験していただきながらスキルアップ可能なトレーニングとなっています。

WEBサービスチーム開発トレーニング

*1:String型やInteger型を普段使ってプログラミングしているかもしれませんが、これと同じようなものを自分で作れるということですね。

*2:クラスを「構造体に加えてメソッドも保有できるようにしたもの」という理解をする場合もあります

*3:この文章でもプロパティやメソッドの説明で「オブジェクト」と書いてしまいました

【インフラ初心者向け】Dockerで作るRuby on Rails 開発環境 第2回『 DockerfileでRailsの開発環境を作ってみよう(準備編) 』

こんにちは。TECH DRIVEの齋藤です。

前回の 「Docker概要、メリットをざっくりと」

dev.techdrive.top


に続きDockerfileを使ってRuby on Railsの開発環境を作成していきましょう。
前回の章立ての中では1エントリーで「DockerfileでRuby on Railsの開発環境を作成する」ところまで書こうかと思っていたのですが
1エントリーで書ききれなかったことと、その前にDockerfileの基本的な部分を抑えておくためにも準備編を追加しました。

まず、Dockerfileの作成に入る前にDockerの基本用語であるDocker イメージついて触れてみたいと思います。

Docker イメージ

前回の記事でDockerを使えば「コンテナ」と呼ばれる仮想的なマシンが構築できると紹介したかと思います。
「 Docker イメージ」はそのコンテナの雛形になります。Dockerではこの「イメージ」を元にコンテナを生成します。

Docker イメージ の使い方とDockerfileについて

Docker イメージを使用してコンテナを生成し、そのコンテナ内で手作業でOSやミドルウェアの設定をする方法と、
元になるDocker イメージの指定とOSやミドルウェアの設定をファイルにまとめて、それを元にイメージの作成 + コンテナの生成をする方法があります。

f:id:shoheis:20170221015948j:plain

今回ご紹介するDockerfileは後者の方法です。毎回手作業でインフラを構築するのは単純に時間がかかることもありますし、
ミスも必然的に多くなります。Dockerfileを使えば設定はコードとしてファイルにまとめることができコマンドを使って
簡単に設定情報通りのイメージを構築することができます。これでより管理がしやすくなり時間とミスを減らすことにつながるというわけです。

Dockerのインストール

Dockerを動かすためにはインストールが必要です。下記からインストールしておきましょう。

Dockerfileの書き方

ではDockerfileの書き方に簡単に触れてみようと思います。
まずDockerfileという名前のファイルを用意します。Dockerfileには元になるイメージの名前と
その設定情報をコードで書いていきます。コードは「命令 + 引数」という形です。

FROM命令

元になるイメージの指定は「FROM 元になるイメージ名」という形で書きます。
こんな感じです。

FROM centos

このイメージ名は誰が決めているの?置いてある場所は?という疑問があると思います。
イメージ名はイメージを作った人が決めています。置いてある場所はDocker Hubです*1
このFROMの感覚はGitでいうCloneに近い気がします。イメージ名はGitでいうリポジトリ名。DockerHubはGitHubのような感じです*2
ちなみに「centos」は公式のリポジトリとして公開されているイメージ名です。

RUN命令

もうひとつほとんどのDockerfileで使う命令が
「RUN 実行するコマンド」の書き方になります。
こんな感じです。

RUN yum -y install git

「yum -y install 」はよくみるコマンドですね。試しに今回はこの状態でイメージを作成してみましょう。
今のDockerfileの中身はこの状態です。

FROM centos
RUN yum -y install git

Dockerfileからイメージを生成

Dockerfileからイメージを生成するには「docker build」を使います。
Dockerfileを置いたディレクトリで

$ docker build -t sample:1.0 .

と打ってみましょう。イメージが生成されます。ここでの「sample」はイメージ名で「1.0」はタグになります。イメージを作成する時はタグをつけると管理がしやすくなります。
イメージの一覧を確認するためには「docker images」コマンドを使います。

$ docker images

元になるイメージ「centos」と今作ったイメージ「sample」が表示されるはずです。

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              1.0                 929b83ac4d62        11 seconds ago      315 MB
centos              latest              67591570dd29        2 months ago        192 MB

イメージからコンテナを生成

コンテナの生成+起動には「docker run」を使います。

$ docker run -it --name "test01" sample:1.0 git --version

git version 1.8.3.1 (こんな表示がされるはず)

「--name "test01"」はコンテナ名「test01」をつけるオプション、「sample:1.0」はイメージ名とタグ、「git --version」はコンテナで実行するコマンドです。「-it」オプションを使うと結果をコンソールに表示することができます。
コンテナの一覧は「docker ps」を使います。

$ docker ps -a

「-a」は起動していないコンテナも表示するためのオプションです。

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
f1a8f40b1113        sample:1.0          "bin/bash"          3 minutes ago       Exited (0) About a minute ago                       test01

「gitがインストールされたcentosのイメージ」のコンテナ「test01」が生成されたのが確認できるはずです。
作成したコンテナを削除してしまいましょう。
削除は「docker rm コンテナ名」です。

$ docker rm test01

今回はDockerfileを使ったRuby on Rails開発環境の構築に入る準備編を書きました。


最後に今回のコマンド一覧を書きます。

$ ls
Dockerfile

$ cat Dockerfile
FROM centos
RUN yum -y install git

$ docker build -t sample:1.0 .
(色々表示される)

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              1.0                 929b83ac4d62        11 seconds ago      315 MB
centos              latest              67591570dd29        2 months ago        192 MB

$ docker run -it --name "test01" sample:1.0 git --version
git version 1.8.3.1

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
f1a8f40b1113        sample:1.0          "bin/bash"          3 minutes ago       Exited (0) About a minute ago                       test01

$ docker rm test01
test01

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

$ docker images ( docker rm コンテナ名 でコンテナは削除されるがイメージは残る)
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              1.0                 929b83ac4d62        26 minutes ago      315 MB
centos              latest              67591570dd29        2 months ago        192 MB

次回は実際にRuby on Rails開発環境の構築とDockerfileのより細かい説明をしていきたいと思います。

*1: Docker Hubだけではないですがここではそう紹介します

*2: GitもGitHubだけではないですよね

ざっくりWebpack入門 Vol.1

こんにちは。TECH DRIVEの小笠原です。
今回は、昨今話題のWebpackについて、自分が学習時に苦労した点などを踏まえ、ご紹介したいと思います。

Vol1の本記事ではWebpackを使ってJavaScriptファイルのモジュール化と依存関係を管理する方法をご紹介します。

Webpackって何者?

モジュールバンドラーと言われるものらしいです。 モジュールをバンドルする(束ねる)ツール。
Webpackにおけるモジュールとは、Webサイトを構成するおおよそ全てのファイル(JSはもちろんHTML/CSS/画像ファイルまで)を指します。

f:id:kabaneshi:20170214155041p:plain

何やら壮大なことができそうですが、壮大すぎてよくわからない。
「全てがモジュール?」「画像ファイルもモジュールなの?」等、Webpackに出会った当初この辺りの感覚が中々掴めずに頭を悩ませました。

この辺りの詳細を含めると話が複雑になるので、本連載では少し話を小さくして、毎回Webpackで行える一部の機能をピックアップしながら、少しずつご紹介していきたいと思います。

本記事でやること

冒頭でも触れた通り、Vol1の今回はWebpackでJavaScriptファイルのモジュール化と依存関係を管理する方法について触れていきます。
環境はnpmが導入済みのMac OSを想定しておりますので、予めご了承くださいませ。

モジュール化について

Webpackの話に入る前に少しモジュールについても触れておきます。
複数の処理が無秩序に書かれたコードは可読性が悪かったり、バグの温床になりがちです。
解決策の一つとして、コードを機能単位で分割(部品化)し、名前をつけて管理する方法があります。
上記を実現するための方法の一つがモジュール化です。 (少々乱暴な言い方ですが)

モジュール化を行うメリットとしては、以下のようなことがあります。

  • どこに何が書いてあるのかが把握しやすい
  • 一度書いたコードを再利用しやすい

JSではモジュールをどう実装すべきかを定義したガイドブックのようなものが複数存在します。(CommonJSやAMDなどがこれに当たります)
しかし、現状ブラウザで動作するJSではガイドブックのルールに従い実装されたモジュールを取り扱う機能がないため、Webpack等のツールを導入しこれを実現します。

依存関係の管理について

JSファイルの依存関係についても少し触れておきます。

依存関係の考慮が必要な例として、jQuery等の外部ライブラリの利用が挙げられます。
当然ですが、jQueryの機能を使用して書かれたコードは、jQuery本体のファイルが先に読み込まれている状態でなければ動作しません。
依存関係とはこのように「あるファイルに書かれたコード」が「別のファイルのコード」に依存している状態を指します。

依存関係は、大抵以下のようにHTMLに記載するscriptタグの順番で管理を行います。

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>webpack sample</title>

   <script src="./js/common/hoge.js"></script>
   <script src="./js/common/huge.js"></script>
   <script src="./js/main.js"></script>
</head>

scriptタグはasync等の属性を指定しないかぎり、頭から順番に実行が行われ、先頭の処理が完了するまで次のファイルが実行されることはありません。
そのためjQuery等の「依存されるファイル」は頭の方に書きます。

しかし、依存関係の考慮が必要なファイルが増えてきたりHTMLファイルが多い場合等は、scriptタグでの依存関係管理は煩わしさがあります。
以下では、この煩わしさを解消する方法をご紹介します。

Webpackの導入

前置きが長くなってしまいましたが、ここからは実際のコードを用いて説明をしていきたいと思います。
今回はプロダクトが以下のディレクトリ構造であることを前提に進めます。

├── dist  // HTMLから呼び出されるJSファイル   
├── index.html  
├── src  
   └── js // モジュール化されたJSファイル群  
       ├── entry.js  
       ├── main.js  
       └── sub.js  

まずは、ディレクトリ直下で以下のコマンドを実行し、package.jsonファイルを作成しましょう。

npm init

いくつかの質問が続いた後に、package.jsonが作成されていれば成功です。 つづけてWebpackのインストールを行います。

npm install --save-dev webpack

これでWebpackを利用するための準備ができました。

必要なファイルの準備

次にモジュールファイルの準備を行っていきます。
今回は上記で少し触れたCommonJSのルールに従いモジュールの定義や呼び出しを行います。
まずはsrc/js直下に以下の2つのファイルを用意します。

  • src/js/main.js
    main.jsの中身は実行時にアラートダイアログを表示するだけのシンプルな処理です。 module.exportsに代入をしている関数がモジュールとなります。
module.exports = function() {
  alert('Hello world');
}
  • src/js/sub.js
    sub.jeの処理は実行から2秒後にアラートダイアログを表示します。
module.exports = function() {
   setTimeout(function(){ alert('Hello webpack'); }, 2000);
}

次に作成したモジュールを呼び出し、実行するためのファイルを作成します。
CommonJSではrequireという仕組みを通し、exportsに追加したモジュールにアクセスを行いますので、そのように書きます。
src/js/entry.js

// モジュールファイルの呼び出し
var main = require("./main"),
    sub = require("./sub");

// モジュールの実行
main();
sub();

先ほど、依存関係について触れましたが、ここではentry.js内のコードが依存する処理をrequireを使って呼び出しています。
呼び出し元や呼び出し方が違うだけで、これはHTMLから外部のJSファイルを呼び出すのとよく似ています。
Webpackを使用することで、このようにJSファイル内で依存関係を管理できるようになります。

Webpackで使用するファイルについて

ここで、これまで作成をしてきたファイルについて少し整理をしてみたいと思います。

f:id:kabaneshi:20170214173314p:plain

  • 1. モジュール郡
    機能単位で分割されたファイル。
  • 2. エントリーポイント
    分割したモジュールファイルの呼び出しや実行処理を記載するファイル。
    このファイルをビルドすることで、複数のJSファイルが一つに結合される。
  • 3. 実行ファイル
    2のビルド結果。HTMLから呼び出されるファイル。

JSファイルの結合と実行

最後にentry.jsをビルドし、dist直下に出力してみたいと思います。

今回のルートディレクトリ直下で以下のコマンドを実行してください。
webpackコマンドの第一引数にエントリーポイントのファイル情報、第二引数に結合されたファイルの出力情報を渡します。

webpack src/js/entry.js dist/build.js

コマンド実行後、dist直下にbuild.jsが作成されたことを確認してみましょう。

結合ファイルの実行

作成したbuild.jsをHTMLファイルから読み込んだ際に期待した結果になることを確認してみましょう。 ルート直下にindex.htmlファイルを作成します。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
</head>
<body>

<script src='./dist/build.js'></script>
</body>
</html>

index.htmlをブラウザで開いた際に、アラートダイアログとして「Hello world」が表示され、それを閉じた2秒後に「Hello webpack」が表示されれば成功です。

設定ファイルの作成

webpackコマンド実行時にいちいち引数でファイル名を渡すのは、面倒かと思います。
これは、設定ファイルを作成することで解決できます。
ルートディレクトリ直下にwebpack.config.jsというファイルを作成し、以下の内容を記載してください。

webpack.config.js

module.exports = {
     entry: './src/js/entry.js', // ビルド対象のファイル情報
     output: {
          filename: "./dist/build.js" // 出力先のファイル情報
     }
};

上記のようにentoryにエントリーポイントのファイル情報、outputに出力情報を記載することでwebpackコマンドのみでファイルの結合/出力が実行できます。

まとめ

いかがでしょうか?本記事を通して少しでもWebpackの輪郭をつかんで頂けたのなら幸いです。

Vol2ではWebpackのloaderという機能を使いES6のトランスパイルをする方法をご紹介したいと思います。

初心者向けにできるだけ噛み砕いてみるオブジェクト指向 vol.1 規格化されることの威力を知る

はじめに

vol.0 にて長い前置きがありましたが、オブジェクト指向の目的や、広く受け入れられる背景を知っていただいた上で読んでいただきたいと思ったので書いてみました。

改めて「新たな要望を短時間で実現する」をどうやったら実現しやすいかなと考えた時、一つの回答として規格化するとやりやすいということがあると思います。今回はそのイメージをお伝えすることをゴールにしてお送りします。

規格化のメリットを知る

コードをあまり書いたことが無い人にもある程度伝わるように考えると、何かにたとえることが必要になってきそうです。何かシステムっぽいものがあると話がわかりやすいと思うので、下記のようなスマホを使った簡単なステレオのシステムがあると思ってください。

f:id:ms2sato:20161203194903p:plain

これから様々な要望が出てきた場合と、その対応について一緒に考えましょう。

交換可能なので嬉しい

「本体から遠くで鳴らしたいのだけど…。」という要望があったとしましょう。

皆さんはすぐに 「今使っているのは1mの長さだから、5mのUSBケーブルを買ってきて付け替える」 のように行動すると思います。簡単ですよね。

これが実現できるのはなぜでしょうか。 「USBという規格に合わせて様々なケーブルが作られているから」 に他なりません。

また、USBケーブルのメーカーは沢山あります。規格化されているので、作る人が誰でも大丈夫です。また、ケーブルに使われる金属や太さなどもマチマチです。これができるのもUSBという規格があるお陰ですね。

f:id:ms2sato:20161203194909p:plain

もしもUSBという規格なしにこれをやろうとすると、まずコネクタの形状を調べるところから始めて、どんな風に電気を通せば良いのかを確かめてなどしてから形状に合わせた設計図を書いて発注し…となってしまい、完全オーダーメイド。とても時間がかかってしまいます。

一体型のステレオで同じことをやろうとするとまず分解するところから始めそうです。これはもっと時間がかかります(今はイヤフォンジャックで外部スピーカー繋ぐとか、オーディオ端子で...とかは忘れてくださいごめんなさい)。

f:id:ms2sato:20161203194914p:plain

使い方さえ知っていれば中の複雑さを知らなくていいので嬉しい

規格化されているので、USBケーブルの中身がどうなっていて、具体的にどんな通信を行うものかを知る必要はありません。必要なのは「両者をつなげれば動く」という性質だけです。このおかげで、たくさん勉強する必要なくシステムを完成させることができます。

f:id:ms2sato:20161203194918p:plain

再利用できて嬉しい

USBケーブルをお友達に貸してあげることができます。お友達はPCとタブレットをつなぐという全く違うシステムを作る為に使うのかもしれません。このように同じUSB規格を利用できるところに、一度作られたケーブルを使いまわせます。

貸してあげるところまでいかなくても、スマホの部分を本格的なステレオ機器に付け替えることも、逆にスピーカーをもっと携帯性の高いものに付け替えることも簡単です。

f:id:ms2sato:20161203194922p:plain

全ての完成品がなくても試験できて嬉しい

特にソフトウェアで面白いのは、作っている途中での活用です。ケーブルを作っている工場を想像しましょう。スマホは既存の製品があるけれど、作っている最中にスピーカーで音を立てると周りの人に迷惑なので「スピーカーらしきもの」で代用しています。例えば鳴っている音をビジュアル化して表現したりして「USB規格を実現したスピーカーを繋いだらきっと鳴るよ」ということをテストしているんですね。テストに合格したら、ちゃんとしたスピーカーに繋いで音を鳴らしてみなさんに聞いてもらうんです。ソフトウェアのテストでもこれと同じようなことをしています。

f:id:ms2sato:20161203194925p:plain

オブジェクト指向と規格化

前回出てきた「技術者の心の声」のうちの何点かを規格化に絡めた例にして挙げてみました。他にも考えられるかもしれませんが、概ねポイントは押さえられたと思っています。こういったことを実現できるようにソフトウェアを作る人は努力しています。ひとえに新たな要望を素早く実現するためですね。

そしてオブジェクト指向は、このような「部品化して規格化する」ということにとても近いです。そのメリットも上記のような「規格化されたUSBケーブルを差し替える仕組みにすれば扱いやすいし、要望をより短時間に実現できる」ということと、とてもよく似ています。部品化して規格化することで実際の工業製品のような作り方をしましょう、という感じかもしれません。

このたとえ話をもう少しソフトウェアの実情に合わせてみると、

  • USBのような「規格を決めること」がインターフェースを決める(もしくはダックタイピングのためのメソッド群を決める)
  • 「USBケーブルを作る」がクラスを実装する
  • スマホとスピーカーを実際に繋いだものが出来上がったシステム全体

のように当てはめることができます。

「新たな要望を短時間で実現する」という目的を達成するために、このような規格化によって対応しているのですね。USBケーブルを簡単に入れ替えていたように、ソフトウェアも入れ替えやすさを意識して作ると良いソフトウェアに近づくと思います。

次からはコード出していきますね。 と、思っていたんですけどこのネタで会話してたら別の内容を一回挟みたくなったのでもう一回イメージの話になりました

PR

TECH DRIVE協賛企業のサークルアラウンド株式会社では、プログラマーの成長を加速させるためのトレーニングを行なっています。フロントサイドからバックエンドまで各種バリエーションがございますので、ご興味がある方は是非以下のリンクより詳細をご覧ください。

JavaScript Climbing

JavaScriptに特化したトレーニング「JavaScript Climbing」を行なっています。
this、クロージャ、Class等、中〜大規模のフロントエンドの開発に臨にあたり、必須となるスキル習得を現役のWEBエンジニアが徹底してサポートします。
2週間の無料体験期間がございますので、ご興味がある方は是非以下のリンクより詳細をご覧ください。

circlearound.co.jp

Ruby Climbing

週1からはじめられる「Ruby」でWEB開発の基礎が習得できる塾です。現役のプログラミング講師&Rubyエンジニアがプログラミング入門からフレームワーク(Sinatra/Ruby on Rails)を使用した本格的なWEB開発の学習までをしっかりとサポートします。

ruby climbing

個別トレーニング

短期間でぐっと成長したい方は弊社主催の個別トレーニングがおすすめです。 トレーニング内容は、受講者の方の課題/要望をお伺いした上で、フルオーダメイドで作成させていただきます。 詳細は以下のリンクよりご確認ください。(応募者多数の場合には時間を別途ご用意する予定です)。

WEBプログラミング個別トレーニング

チーム開発トレーニング

既にある程度コーディングが可能なのでチーム開発を経験してみたいという方にはチーム開発トレーニングがおすすめです。 GitHub Flowを使用し、実践の開発フローを体験していただきながらスキルアップ可能なトレーニングとなっています。

WEBサービスチーム開発トレーニング

【インフラ初心者向け】Dockerで作るRuby on Rails 開発環境 第1回『 Docker概要、メリットをざっくりと 』

こんにちは。TECH DRIVEの齋藤です。

今回の連載では流行りのDockerを使ってRuby on Railsの開発環境を構築していきます。 この連載記事は「インフラ初級者の方」を対象にしています。

私自身アプリケーションエンジニアでインフラに関してはまだまだということもありますので、 読者の方々の目線に立ちつつも試行錯誤しながら環境作りをしていきます。 なるべく簡単な説明で書いていきたいと思っていますので、一緒に頑張っていきましょう!

連載の章立てはこちら(後々章立ては変更される可能性があります)。

  • 第1回 Docker概要、メリットをざっくりと。
  • 第2回 DockerfileでRailsの開発環境を作ってみよう(準備編)。
  • 第3回 DockerfileでRailsの開発環境を作ってみよう。
  • 第4回 Docker-ComposeでRailsの開発環境を作ってみよう。
  • 第5回 データやソースコードをVolumeで管理してみよう。
  • 第6回 Dockerの使えるコマンド編

Dockerの概要、メリットは何?

Dockerの仕組みはいろんなページに載っていると思うので 「インフラ初級者にとってのDockerのメリット」という視点で書きたいと思います。 使用した感じから、本当にざっくり言うと

「他人の作った『環境』を自分の手元でもお手軽に構築することのできるサービス(仮想化のためのソフトウェア)」です。

他人の作った『環境』を自分の手元でもお手軽に構築するって?

MAMPあるいはXAMPPはご存知ですか? 例えばMAMPは、Mac 上でApache、MySQL、PHPの環境を簡単ダウンロードして使えるサービスです*1。 よくLAMP環境と言われたりしますね*2。 PHPで開発をするときにLAMP環境をいちから構築するのって大変だと思います。

そんなときMAMPを使えばインフラをよく知らなくても簡単にLAMP環境を利用できちゃう、そんな代物なのです。 Dockerを使えば同じように簡単にLAMP環境を利用できてしまいます。

「じゃあMAMPでよくない?」

というのはもっともな疑問ですね。

ただしDockerはMAMPだけではなく、Ruby on Railsの環境や、Wordpressの環境など様々な他人が構築した環境を利用できるのです! 他人が構築した環境ということは、例えば典型的なWordpress環境だけでなく、もしアップロードされていれば「超高速で動く」Wordpress環境だって簡単に利用できてしまうのです。 もちろん、仲間が作った環境も利用できるので開発環境も共有できます。

f:id:shoheis:20170104235404j:plain

もう一つの大きな違いは、OSから構築するか、しないかということです。 MAMPはMacOSのようにすでに存在しているOS上にダウンロードして使います。 DockerはOSから丸ごと構築して使います。 つまりは他と同じOSの環境で動かすことができます。 このことにより「開発環境のOS上では動いたのに本番環境の別OS上だと動かない」なんてトラブルとはオサラバです。

仮想化のためのソフトウェアって?

Dockerを使えばPCの中に「コンテナ」と呼ばれる仮想的なマシンが構築できます。 コンテナによってPCの中にもう一つPCが作られるイメージです。 Dockerは他人が作った環境をこのコンテナ単位でダウンロードして使います*3。 このダウンロードの仕組みや他人が作った環境をアップロードする仕組み、その他一連の仮想化のための仕組みをDockerは提供しています。

f:id:shoheis:20170124183115j:plain

他人の作った「環境」はどこに集まっているの?

一般的に私たちが利用できるダウンロード元で一番有名なものはDocker社が提供する「Docker Hub 」が考えられます。 なんとすでに30万以上のアプリの環境がアップロードされています。 公式のリポジトリもありますので欲しい環境がないか探してみるのもありですね!

https://hub.docker.com/explore/

ダウンロードの仕方については、これから掲載する第2回、第3回、第4回で紹介させていただく予定です。

自分で環境を構築することはできるの?

もちろんできます。ただインフラ初心者の方にとって完全に自力でやるのはハードルが高いかもしれません。 ですので次回から説明を交えつつ数回に分けて環境の構築の仕方を説明していこうと思っています。 その中で他の仮想化のためのソフトウェア「Virtual Box」との違いも簡単に触れていけたらいいと思ってます。

では次回は、環境構築編として、DockerfileでRailsの開発環境を作ってみよう。に取り掛かろうと思います。

*1: 最近はWindowsでも使えます

*2:LAMPのLはLinuxのことです。

*3:厳密にはダウンロードするのは「イメージ」というコンテナの雛形です。ここは想像しやすいようにコンテナとしています。

TECH DRIVEについて

TECH DRIVEは「技術者の成長を加速させる」をキーワードに都内で活動をしているコミュニティです。
TwitterやFacebookにて技術ネタやイベント情報の発信を行っていますので、ご興味があれば、いいねやフォローをお願いいたします。