kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Active Record の scope を使う必然性ってあるの?

と思って調べたら、Rails ガイドに、

スコープでのメソッドの設定は、クラスメソッドの定義と完全に同じ (というよりクラスメソッドの定義そのもの) です。どちらの形式を使用するかは好みの問題です。

と、言われたので、 特に必然性は無いらしい

ちなみに、 引数を使う場合はクラスメソッドを推奨するそうです

スコープで引数を使用するのであれば、クラスメソッドとして定義する方が推奨されます。クラスメソッドにした場合でも、関連オブジェクトからアクセス可能です。

あと、適当にぐぐったら「以前の時代は特別なものだったけど、今は別に使わなくてもよいのでは?」という話を見つけて、それもそうかという気持ちになりました

追記

こちらの記事の「追記」にあるように「 ActiveRecord::Relation を返す chainable な検索処理は scope で書く」というスタイルも、model 内でのメソッドの役割が明確になって良いのかもしれないですね

EC2の仮想化方式についてのおぼえがき

先にまとめ

  • AMI(Amazon Machine Image)の仮想化方式は、準仮想化 (PV) およびハードウェア仮想マシン (HVM) の2種類
  • 現在はHVMを推奨している
    • 公式曰く: 最適なパフォーマンスを得るために、インスタンスを起動するときには、現行世代のインスタンスタイプと HVM AMI を使用することをお勧めします
    • 特別なハードウェアサポート(拡張ネットワーキングや GPU 処理など)も受けられる
  • 旧世代のインスタンスタイプは、PVしかサポートしていない

仮想化方式とは?

  • EC2は、仮想化マシンモニタ Xen 上で動作している
  • Xenが、仮想マシンを作る方式には、HVMとPVの2種類の仮想化方式がある

PV (paravirtual。準仮想化)

実在のハードウェアを完全にエミュレートする代わりに、仮想マシン環境を実現するのに都合の良い仮想的なハードウェアを再定義する方式

メリット

  • 以前は、ハードウェア制御のオーバーヘッドが無いので、HVMとくらべて速度が早かった

デメリット

  • ハードウェアを仮想化しているので、特別なハードウェア拡張を利用できない
    • EC2だと拡張ネットワーキングや GPU 処理など

HVM (Hardware-assited VM。完全仮想化)

物理マシン用に用意されたOSをそのままXen上で動作させる方式

メリット

  • 物理マシンのハードウェアを利用できる

デメリット

  • 以前は、物理マシンのハードウェアを操作するためのオーバーヘッドにより、PVより遅かった
  • 現在は、オーバーヘッドが発生しやすい部分(IOなど)について、PVと同様のドライバを使うことで回避している(らしい)

参考

docs.aws.amazon.com

kanny.hateblo.jp

Xen (仮想化ソフトウェア) - Wikipedia

どうぶつタワーバトルを社内に普及したいのでプレゼン

この記事は feedforce Advent Calendar 2017 の 11 日目の記事です

ドーモ、社内ニンジャスレイヤー推進おじさん かせいさんです

前回は、Waka F のNY旅行の話でした。アドベントカレンダーでまさかのYouTubeでした。すごい!

www.youtube.com

さて、ニューヨーク旅行からのこちらは、みなさんご存知、どうぶつタワーバトルのお話です

アドベントカレンダーにかこつけて、どうぶつタワーバトルを社内で流行させるべく、プレゼンいたします

どうぶつタワーバトルとは!?

どうぶつタワーバトルは、12月初旬ころから爆発的に流行しているe-sportsです

f:id:kasei_san:20171211205257j:plain

どんなゲームなの

物理エンジンで構築された世界で、2人オンライン対戦でどうぶつさんを交互に積み上げて、バランスを崩して、盤の外に落としたほうが負けというゲームです。シンプル!

f:id:kasei_san:20171211112101p:plain

どうぶつタワーバトルの何がすごいか?

上で見たように、ぱっとみゆるふわな低年齢向けのパズルゲームに見えますが... 運と、技術介入要素のバランスが大変絶妙で、カードゲームやボドゲ好きな人が次々と沼に落ています

以下は沼にはまった、マジック・ザ・ギャザリングの日本人プロプレイヤーの市川佑樹さん (DTBはどうぶつタワーバトルの略称。1600-1700はレーティングで、RAGEはe-sportsのイベント名です)

運ゲーとしてのどうぶつタワーバトル

このゲーム、何も考えないでプレイすると運ゲーになります

ランダムに出るどうぶつを乗せ合うので、最終的に乗せらせられないどうぶつが出てきたプレイヤーが負けになるためですね

下の画像は、終盤に面積が広いキリンを引いた様子。これはかなり辛いです

f:id:kasei_san:20171211204304p:plain

ただ、運ゲーだからといって面白くないかというと別で、後半ギリギリの展開で何を引くか...!? というシーンではかなり手に汗を握ります...!

技術介入ゲーとしてのどうぶつタワーバトル

とはいえ、どうぶつタワーバトルは、ただの運ゲーというわけではなく、かなりの技術介入要素があります

何も考えず積むのではなく、戦略を練ることと、将棋の棋譜のようにパターンを知ることで勝率をかなり上げることができます

どんな戦略があるの

シンプルな戦略では「奇をてらったことはしない」というのがあります。対戦中やプレイ動画で見られるスーパープレイを「ようし、俺もやってやるぜ!」なんてマネすると大体死にます

しばらくは我慢して、安定する置き方を覚えましょう。レートの低いうちは、自分が死なないプレイをしていると、結構な確率で相手が自滅して勝ちになります

自分もこれに気がついてから、だいぶ勝率が上がりました

技術介入要素まとめ

そんな感じで、運ゲーに見せかけて、気付きをプレイスタイルに取り込むと、結構わかりやすく勝率が上がります

f:id:kasei_san:20171211213242p:plain

また、レーティングという形で、自分の強さが可視化されているので、数値ベースにPDCAサイクルを廻しやすいのもポイントです

運と技術介入要素のバランスの良いゲームは良ゲー

持論ですが 運と技術介入要素のバランスの良いゲームは良ゲー と思っています

なぜなら、運要素がゼロだと、強い相手には絶対に勝てないので、初心者には面白みが薄く、取っ掛かりも悪いです。また、盛り上がりにも欠けます (そっちのほうがストイックで好きという人も居ると思いますが)

また逆に、すごろくのように、運要素のみだと一時的には盛り上がりますが、すぐに飽きてしまいます

どうぶつタワーバトルや、一部のカードゲームのように運と技術介入要素のバランスが良いと、引きに一喜一憂して盛り上がりつつも、さらに、自分の工夫で勝率が上がっていくいう楽しみを得ることができます

まとめ

どうぶつタワーバトルは、ゆるふわな見た目にも関わらず、運と技術介入要素のバランスが良い

運と技術介入要素のバランスの良いゲームは良ゲー

すなわち、どうぶつタワーバトルは良ゲー

みんなもやってみよう

iPhone、アンドロイドでプレイ可能です!

どうぶつタワー

どうぶつタワー

  • Yuta Yabuzaki
  • ゲーム
  • 無料

play.google.com

明日のアドベントカレンダー

mizukmb の「新卒エンジニアの生態について」です! お楽しみに!!

週報 2017/11/27週 Dockerを勉強した週

期間

2017/11/27(月) 〜 2017/12/03(日)

インプット

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

パプリカ

パプリカ

  • 疲れて帰ってきたのにそのまま深夜までイッキ見してしまった映画
  • 夢の中の世界をアニメならではの表現で延々と見させられた
  • 今畝監督の他の作品も見たい

機動戦士ガンダム公式設定集 アナハイム・ジャーナル U.C.0083-0099

機動戦士ガンダム公式設定集 アナハイム・ジャーナル U.C.0083-0099

  • はしゃいでたら、ウソの学会誌を作る人なんだから、こういうのにハマるのだろうと指摘されて納得するなど

アウトプット

kasei-san.hatenablog.com

kasei-san.hatenablog.com

  • Dockerを理解すべく手を動かし中

note.mu

  • Evernoteに書きなぐってあったのを偶然見つけたので供養
  • このゲーム本当にゲーム開始までの設定が魅力的なので、むしろそれをゲームで体験したい...

KPT

Keep

  • 「とりあえず、12月はDockerを勉強する! ECSで動かしたり、CircleCIで、ブランチ毎に自動的に環境を立ち上げられるようにする」と決めた

t-wada さんが、弊社TDD本読書感想会に参加して頂けそう!

Problem

ややオーバーキャパシティ気味

キャリア支援やマネージメントに関する本を読めていない

Try

引き続きDockerを進める

来週末の社内LTのネタを考える

今後の予定

adventar.org

  • 12/11(月)

yumenosora.connpass.com

  • 勢いでLT申し込んでしまったので何か書かねば...

危機感にかられて今更Dockerを学び直す人の記録(Railsを動かしてみる編)

これまでのあらすじ

概要を理解して、Imageを作ってコンテナをうごかしてみました

kasei-san.hatenablog.com

kasei-san.hatenablog.com

今日やること

公式のクイックスタートガイドを元に、ローカルのDockerでRailsを動かしてみる

docs.docker.com

ワーキングディレクトリ作成

cd .
mkdir -p work/rails_docker_demo
cd work/rails_docker_demo
git init

Dockerfile について

概要編でも軽く説明したが、Imageの環境を定義するDockerfileと言うものがあり、クイックスタートガイドでは、それでRails環境を作るように書かれている

Dockerfileに以下を定義

FROM ruby:2.4.2
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

コマンド解説

リファレンスはこちらを参照

docs.docker.com

FROM

ベースとなるImageを定義。

クイックスタートでの定義がちょっと古かったので、dockerhubのrubyオフィシャルから安定最新っぽい2.4.2に変更した

RUN

/bin/sh -c でコマンドを実行する

WORKDIR

ワーキングディレクトリを定義

これ以下のコマンドでのカレントディレクトリが、ワーキングディレクトリになる

COPY

Dockerホストからファイルをコピー

DockerホストでGemfile作成

source 'https://rubygems.org'
gem 'rails', '5.1.4'

COPY Gemfile.lock のために空の Gemfile.lock を作成

touch Gemfile.lock

docker-compose.yml の作成

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

docker-compose とは?

ホスト上の複数のコンテナを一元管理する為のツール

docker-compose.yml で定義

今回は、webと、dbのコンテナの設定をそれぞれ定義している

docker-compose.yml のコマンド解説

リファレンスはこちらを参照

docs.docker.com

version

docker-compose のバージョン指定。最新なら 3

services

各コンテナをサービスとして定義する場所

image

imageのタグ、id等を定義。dockerfileの FROM と同じ?

build

dockerfileのPATH

command

コンテナに定義されているデフォルトのコマンドを上書きする

volumes

PATHをボリュームとして定義

ボリューム

コンテナを実行するときに、ホストのディレクトリをコンテナのディレクトリにマウントできる

このとき、マウントされた領域をボリュームという

ports

docer run のpublishオプションと同じもの?

depends_on

依存関係の定義

今回の場合、webを起動するには、dbの起動が必要

環境のビルド

docker-compose run は、docker-compose.yml に定義された環境を作成して、コマンドを実行。完了したら各コンテナを終了する

docker-compose run web rails new . --force --database=postgresql

docker-compose のコマンド解説

run

ワンオフなタスクの実行

特定のサービスを指定する必要がある

指定したサービス用のコンテナと、それと依存関係にあるサービス用のコンテナが起動する

実行後、コンテナは停止する

docker container build を実行していない場合、一緒に実行される

build

docker-compose.yml の内容に従って環境がビルドされる

Dockerfileを変更した場合は、今回ならば Gemfile を変更した場合、build が必要

buildではまだコンテナは作成されない??

up

コンテナを作成して起動する

start

環境の再構築

新しいgemを追加したり、Dockerfieを更新した場合

docker-compose build

DBへの接続

config/database.yml を以下のように変更する

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

環境の起動

$ docker-compose up

rake db:create の実行

docker-compose run web rake db:create

localhost:3000/ に接続

f:id:kasei_san:20171202180135p:plain

👏

環境の停止

docker-compose down

環境のステータス

docker-compose ps

起動時

        Name                       Command               State           Ports
---------------------------------------------------------------------------------------
railsdockerdemo_db_1    docker-entrypoint.sh postgres    Up      5432/tcp
railsdockerdemo_web_1   bundle exec rails s -p 300 ...   Up      0.0.0.0:3000->3000/tcp

終了時

        Name                       Command               State    Ports
-----------------------------------------------------------------------
railsdockerdemo_db_1    docker-entrypoint.sh postgres    Exit 0
railsdockerdemo_web_1   bundle exec rails s -p 300 ...   Exit 1

ここまでのコード

github.com

感想

とりあえず、動かすことができたという感じ

これで実際にどうやって、開発/本番環境の運用をしていくのかイメージは湧いていない

今後

ECSや、herokuで、docker on rails な環境を動作させてみる

参考

qiita.com

qiita.com

qiita.com

qiita.com

危機感にかられて今更Dockerを学び直す人の記録(実践編)

Dockerエンジンのインストール

OSXならばこちら → Docker Store

  • 無償のcommunity editionと、有償のenterprise edition がある
  • Dockerは、linuxカーネルの機能を使うので、macwindowsで動かす場合は、小さいLinuxVMを内部で動かしているらしい

色々動かしてみる

こちらを参考に色々やってみた

qiita.com

バージョンの確認

$ docker version

Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:40:09 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:45:38 2017
 OS/Arch:      linux/amd64
 Experimental: true

Dockerは、クライアント・サーバモデルなので、それぞれの情報が表示される

docker run

新しいコンテナを作成して、起動するコマンド

  • イメージを元に、コンテナを起動する
  • イメージが無い場合、Docker Hub から探してくる

以下は、nginx というイメージを元に webserver というコンテナを起動している

$ docker run -d -p 80:80 --name webserver nginx

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
bc95e04b23c0: Pull complete
f3186e650f4e: Pull complete
9ac7d6621708: Pull complete
Digest: sha256:b81f317384d7388708a498555c28a7cce778a8f291d90021208b3eba3fe74887
Status: Downloaded newer image for nginx:latest
8d291801fd815f6bb8112842c4c1df2d0efd96162d3a28067258502186d3b061

複数のデータレイヤをダウンロードして、イメージを作成している

コマンドの解説

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  • -d, --detach: バックグラウンドで実行
  • -p, --publish: ホストマシンとコンテナのポートを接続する。左がホスト
  • --name : コンテナの名前

詳細はこちらも参考

docs.docker.com

docker container ls でコンテナの状況を確認

$ docker container ls

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
8d291801fd81        nginx               "nginx -g 'daemon ..."   22 seconds ago      Up 21 seconds       0.0.0.0:80->80/tcp   webserver

localhost:80 にアクセスしてみる

nginxのデフォルト画面が出力される

$ curl http://localhost:80

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

コンテナ内に入る

docker attach で入れるのは、コンテナがメインのコマンドとしてシェルが起動している場合のみ

適当にぐぐると、 docker attach すると言われる

しかし、docker attach で、コンテナの中をシェルで操作できるのは、メインのコマンドでシェルが起動しているコンテナのみ

今回の nginx イメージは、docker container lsCOMMAND を見ると、メインのコマンドは、nginxをデーモンとして動かしている "nginx -g 'daemon ..."

そのため、docker attach しても、nginxデーモンの標準出力が見えるばかりで、さらにそこから ^D して脱出しようとすると、コンテナが終了してしまう...

docker exec -it 〜 /bin/bash でメインのコマンドがシェルでないコンテナにも入れる

docker exec は、対象のコンテナに任意のコマンドを実行するコマンド

$ docker exec -it webserver /bin/bash
root@7fec1ea5a77b:/# exit

コマンドの解説

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
  • -i, --interactive: デタッチされるまで標準入力を受け入れるオプション
  • -t, --tty: 仮想端末をコンテナに当てるオプション
    • ちなみに仮想でない端末とは出力を物理的にアウトプットする「テレタイプ端末」のこと

コンテナに対して、インタラクティブな状態で、 /bin/bash を実行している

コンテナの停止

$ docker container stop webserver

停止されたことを確認

$ docker container ls

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

docker container ls --all で、停止中のコンテナも確認可能

$ docker container ls --all

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                     PORTS               NAMES
8d291801fd81        nginx               "nginx -g 'daemon ..."   About a minute ago   Exited (0) 6 seconds ago                       webserver

コンテナの再開

$ docker container start webserver

コンテナの削除

$ docker container rm webserver

imageの確認

$ docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              9e7424e5dbae        4 days ago          108MB

imageの削除

$ docker image rm nginx

Untagged: nginx:latest
Untagged: nginx@sha256:b81f317384d7388708a498555c28a7cce778a8f291d90021208b3eba3fe74887
Deleted: sha256:9e7424e5dbaeb9b28fea44d8c75b41ac6104989b49b2464b7cbbed16ceeccfc3
Deleted: sha256:7fcb1f7f8194a8cd7e706d4fc8a0f864cf48bf3937384c4b0a4797af05cc54c6
Deleted: sha256:70a75f17542ef0e6d2686f6ab9f89c22a859c0fe9f9c3abaddb1a893af4f476d
Deleted: sha256:cec7521cdf36a6d4ad8f2e92e41e3ac1b6fa6e05be07fa53cc84a63503bc5700

削除されたことを確認

$ docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

参考

docker exec を使いこなす – ユニコーンリサーチ

qiita.com

危機感にかられて今更Dockerを学び直す人の記録(概要編)

そもそもDockerって何なの?

コンテナ型仮想化サービス

仮想化サービスとは?

サーバ上に仮想的なサーバを作り出す技術

ホスト型、ハイパーバイザ型、コンテナ型がある

ホスト型

汎用的なOS上に専用のアプリを入れて、仮想化を実現

ハイパーバイザ型

仮想化専用のOSを入れて、その上で仮想化を実現

コンテナ型

独立した環境をOS上に作る技術

他の仮想化技術と違って、別のOSを仮想環境で動かしたり、ハードウェアのエミュレーションをしているわけではない

  • Dockerエンジン

コンテナ型についてもう少し詳しく

コンテナ: 1つのLinuxOS上でリソースを分離、独立させた実行環境のこと

  • linuxに元々ある機能で実現している
    • namespace: プロセス毎のリソースの分離・独立(ファイルツリーなど
    • Cgruops: CPUやメモリ、DiskIOのリソース制限
  • カーネルはホストと共有
  • コンテナは、リソースへのアクセスが制限された、特殊なプロセスとディレクトリの集まり

コンテナ型の利点

  • 開発環境においては、ホスト型より軽量なため扱いが楽
    • 起動が早い、リソースを食わない、ファイルサイズが小さい
  • 最近は、Dockerをそのまま本番環境で動かす仕組みが普及してきたので、本番/開発環境の違いによる問題も解決されるようになった

Dockerとは

Dockerは、アプリケーションの開発、出荷、および実行のためのオープンなプラットフォームです。 Dockerを使用すると、アプリケーションをインフラストラクチャから分離して、迅速にソフトウェアを提供できます。 Dockerを使用すると、アプリケーションを管理するのと同じ方法でインフラストラクチャを管理できます。 Dockerのコードを迅速に出荷、テスト、デプロイするための方法論を活用することで、コードを記述して本番環境で実行するまでの遅延を大幅に短縮することができます。

Docker overview | Docker Documentation

Dockerは、元々コンテナ型仮想化サービスの名称だったが、最近ビジネスが周りだしたので、開発・デプロイ・実行までのエコシステム全体をDockerと言い出した

旧来のコンテナ型仮想化サービスは、Docker エンジン と呼んでいるらしい

Dockerのエコシステム(一部)

  • Docker Hub 等のリポジトリから Docker image(後述) を持ってくる
  • Dockerエンジンは、Docker image を元にコンテナを作成する
  • コンテナの変更を commit すると、新しい Docker image が作られる
  • 新しい Docker image が、リポジトリに push される

Docker image

  • コンテナの元。コンテナを構築するのに必要な情報が格納されている
  • 実態は tar ファイル
  • Docker エンジンはこれを元に、コンテナを起動する
  • イメージレイヤというものの集合体
  • 上記のcommit をすると、イメージレイヤが1毎重ねられる
  • 今までの変更記録が積み重ねられているというイメージっぽい

dockerfile と docker build

元々は、上記のように commit を積み重ねて環境を作る仕組みだった

しかしそれでは、変更箇所を追うことが困難だったので、単純なテキスト形式の設定ファイル(dockerfile)を元に、イメージが作られる機能(docker build)が追加された

参考