MORITOMOMENT

登山好きエンジニアのテックブログ

プログラミング・アウトドア関連を中心に発信

Dockerチュートリアルを日本語で説明(第3章)

f:id:moritomo7315:20190117140005p:plain

第2章はコンテナについてのチュートリアルでしたが、

moritomo7315.hatenablog.com

今回はサービスについてのチュートリアルです。

なにをするかというと、

第2章で作成したコンテナをいくつか複製して、それらで負荷分散ネットワークを構築します。

見かけ上、アプリケーションの実行結果は変わりませんが、負荷分散ネットワークを構築することで、第2章だけのものよりも、高負荷のアクセスに耐えたりすることができるようになります。

先に結論をいうと、これを実現するためにはdocker-compose.ymlを書き特定のコマンドで実行することで簡単に構築することができます。

Dockerチュートリアルが英語しかないと思っていましたが、日本語版がありました。 なので公式のチュートリアルでも問題はないと思います。 本記事では、自分の勉強アウトプットのために投稿してますが、 公式のものにはない、 節の見通しを読者に与えたり、コマンドの実行結果や負荷分散の様子を載せているなど、 理解することに特化しているので、自分なりに公式より詳しく説明しているつもりです。

公式Docker Getstarted 日本語版

docs.docker.jp

  • Docker勉強し始めたい方
  • 公式の方でやってみたけどあまり理解できなくて困っている方

第3章の位置付け

第2章でも紹介した通りDockerでのアプリケーション開発では次の3層構造を意識します。 第3章では中間層の「Service」に着目します。

Service層は何のために位置付けられているかというと、

作ったアプリケーションの負荷を計測したり、負荷分散をおこなうなどアプリケーションの中でコンテナがどのように振る舞うかを決めるためにあります。

f:id:moritomo7315:20190120132832p:plain

Serviceについて

Serviceは1つのコンテナ(image)のみを実行することができます。

そしてimageをどのように実行するかを決めることができます。

例えば、

  • どのポートを使用するか
  • あるサービスが必要なキャパシティを満たすためには、いくつコンテナを複製すべきか

など考える際有効です。

サービスのスケーリングをしたい場合は実行するコンテナインスタンスの数を変更することで対応できます。

それでは本題に入っていきます。 上で述べたことはdocker-compose.ymlにより定義することで実現することができます。

docker-compose.yml

docker-compose.ymlはDockerコンテナがproductionでどのように振る舞うべきかを定義するYAMLファイルです。

まず次のdocker-compose.ymlをどこでもいいので作成してください。

docker-compose.yml↓

version: "3"
services:
  web: # サービス名をwebとする
    # 第2章で作成したimageのリポジトリに設定
    image: <username>/get-started:part2 #pullしたいリポジトリを指定
    deploy:
      replicas: 5 #webと名付けたimageのインスタンスを5つ用意
      resources:
        limits:
          cpus: "0.1" # 1つのインスタンスにつきCPUは10%まで使用可能
          memory: 50M # 1つのインスタンスにつきメモリは50MBまで使用可能
      restart_policy:
        condition: on-failure
    ports: # ポート指定 webの80ポートをホスト(自分のマシン)の4000ポートに割り当てる
      - "4000:80"
    networks:
      - webnet # webnetと呼ばれる負荷分散ネットワークに指定
networks:
  webnet:

docker-compose.ymlのimage: <username>/get-started:part2<username>を自分の環境に合わせて書き換えてください(第2章で設定しました)。

このYAMLはソースのコメントにも補足してありますが、次のことをDockerに伝えます。

  • image:で指定したリポジトリから第2章でアップロードしたimageをpullする。
  • replicasで指定される数分(今回は5つ)、imageのインスタンス(imageのコピーみたいなもの)を実行する。それぞれのインスタンスにつき、自分のPCのCPUの10%まで、メモリの50MBまで使用可能(limits:で指定)。
  • コンテナ終了時にステータスがon-failureだった場合、コンテナを再起動(restart_policyで設定)。
  • web(imageのサービス名)の80ポートをホスト(自分のマシン)の4000ポートに割り当てる
  • webnetと呼ばる負荷分散ネットワークを通じてwebのコンテナをポート80に共有する。
  • webnetをdefaultで定義する(webnet:の欄を空欄に)。defaultだと負荷分散オーバーレイネットワークとなります。

実際にこの負荷分散アプリケーションを動かしてみる

一連の流れは、

  1. docker swarm initswarmについては第4章で詳しく勉強します)
  2. docker stack deploy -c docker-compose.yml getstartedlabで実行。そのとき、この負荷分散アプリケーションにgetstartedlabと名前付けする。

この2つで負荷分散アプリケーションを実行することができます。

実際にやっていきます。

$ docker swarm init
実行結果↓
Swarm initialized: current node (bb7teuxa2thm4viwok5656dbz) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-0mub34dni79swd1yizk96yr0wxz3k1ba3dwd6254vbbokxo137-4pxnqgbp9189gujxcd8wpqr97 192.168.65.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
$ docker stack deploy -c docker-compose.yml getstartedlab
実行結果↓
Creating network getstartedlab_webnet
Creating service getstartedlab_web

これで負荷分散アプリケーションを実行することができました。 実行したService(負荷分散アプリケーション)のIDや名前等は次のコマンドでみることができます。

$ docker service ls
実行結果↓
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
y56sievmxu2a        getstartedlab_web   replicated          5/5                 <username>/get-started:part2   *:4000->80/tcp

サービスgetstartedlab_webで実行している1つのコンテナを「タスク(task)」と呼びます。タスクはユニークなIDを与えられており、タスクはgetstartedlab_web.数字で名前づけられます。タスクは次のコマンドで確認できます。

$ docker service ps getstartedlab_web
実行結果↓
ID                  NAME                  IMAGE                          NODE                    DESIRED STATE       CURRENT STATE           ERROR               PORTS
nl2g7hvtdi8i        getstartedlab_web.1   <username>/get-started:part2   linuxkit-025000000001   Running             Running 7 minutes ago                       
m49n4b57eeak        getstartedlab_web.2   <username>/get-started:part2   linuxkit-025000000001   Running             Running 7 minutes ago                       
9uzg797m8g9y        getstartedlab_web.3   <username>/get-started:part2   linuxkit-025000000001   Running             Running 7 minutes ago                       
hzts1lw84gmr        getstartedlab_web.4   <username>/get-started:part2   linuxkit-025000000001   Running             Running 7 minutes ago                       
uqz4dwzereid        getstartedlab_web.5   <username>/get-started:part2   linuxkit-025000000001   Running             Running 7 minutes ago  

アプリケーションで実行されているコンテナをリストアップするために次のコマンドを入力します。

$ docker container ls -q
実行結果↓
9aaca126702d
dc6c04cd7d0f
3916b7b57456
86eb305ca950
4577652260b6

任意のブラウザでhttp://localhost:4000/にアクセスしてください。

第2章と同じアプリケーションを動かしているため、同様な見た目が得られると思います。

f:id:moritomo7315:20190120130944p:plain

次にブラウザを更新してみてください。

するとHostnameの欄の値が変わると思います。

Hostnameの値の変わり方は5通りです。

f:id:moritomo7315:20190120131106p:plain

f:id:moritomo7315:20190120131050p:plain

f:id:moritomo7315:20190120131018p:plain

f:id:moritomo7315:20190120130959p:plain

この結果からわかるように、同じ結果を出力しているように見えて、それを出力しているhostが異なるのは負荷分散の恩恵です。 replicasで設定した数通りのhostによって負荷分散をできています。

また負荷分散アプリケーションのスケールを変更したい場合は、docker-compose.ymlreplicasの値を任意の値に書き換えて、

再び、docker stack deploy -c docker-compose.yml getstartedlabを実行すれば可能です。

試しにreplicasの値を5から8に変更しスケールアウトしてみましょう。

$ docker stack deploy -c docker-compose.yml getstartedlab
実行結果↓
Updating service getstartedlab_web (id: y56sievmxu2a1utk7h0zn8pn1)

実行結果の通り、Serviceの設定がアップデートされましたね。

また、

$ docker container ls -q
実行結果↓
2f7d8d74eef5
f60847282801
6c9af7c20321
96a2cce21a3b
bf2968c19aa4
3d19166e560d
b8c2baf1cf51
513adc5f9d54

上記コマンドの実行結果より、8つのインスタンスが動いていることがわかります。

このようにアプリケーションのスケールアウトも簡単にできます。

アプリケーションを停止させる

アプリケーションを停止させるためにはdocker stack rm <アプリケーション名>を実行します。

今回はアプリケーション名をgetstartedlabにしていたので、

$ docker stack rm getstartedlab
実行結果↓
Removing service getstartedlab_web
Removing network getstartedlab_webne

のように停止します。

普段からLinuxやMax、Unixを使用しているのであれば、rmというコマンドを使用するのでわかりやすいのではないでしょうか。

またSwarmというものも動作しているので

$ docker swarm leave --force
実行結果↓
Node left the swarm.

でswarmに対するコマンドも実行します。

まとめ

内容をもう一度まとめておきます。

今回はService層の役割を学ぶために、

負荷分散アプリケーションを作成しました。

第2章で作成したfriendlyhelloイメージのコンテナに 複製やネットワーク構成等の振る舞いの仕方をdocker-compose.ymlで命令することで負荷分散アプリケーションを実現しました。

  • 第3章の位置付け
  • docker-compose.ymlについて
  • 負荷分散アプリケーションの実行
  • 負荷分散アプリケーションのスケールアウト
  • 負荷分散アプリケーションの停止

Dockerの勉強頑張りましょう!!

コンテナについては第2章はこちらから。

docs.docker.jp

moritomo7315.hatenablog.com

第4章は出来次第更新

Dockerチュートリアルを日本語で説明(第2章)

Docker, getstarted, 日本語, japanese

Dockerを勉強しようと思い、色々調べていたのですが、どうも自分にとって理解しやすい記事がなかったので、

公式のDockerのGetstaretedで勉強し始めました。

docs.docker.com

公式のなので英語で書かれています。 勉強しがてら、英語で困っている方向けに、Dockerチュートリアルを日本語で説明していこうと思います。

チュートリアルをまるまる翻訳したわけではなく、自分なりにわかりやすく解説しているつもりです!

  • Dockerを勉強し始めたい人
  • Dockerの勉強始めに良さそうなサイトを見つけれていない人
  • DockerのGetstatedやりたいけど英語のせいで挫折してしまった人

第1章についてはDockerの概念、インストールの方法などについてのみ記載されているので、 ググれば色々出てくると思います。

今回はGetstartedのPart2を日本語でなるべくわかりやすく説明していきます。

公式のGetstartedのままでは面白くないので、この記事の付加価値として

  • 日本語であること
  • ローカルで作成したDockerイメージを実際に仮想マシンで実行している

の2つを用意しました。

Dockerの勉強頑張りましょう!

第2章の位置付け

Dockerでアプリケーション開発をおこなうときには次の3層構造を意識します。

f:id:moritomo7315:20190120132843p:plain

第2章では最下位層のコンテナについて扱います。

アプリケーション開発するために必要な環境を

ローカルのPCに依存しない、ポータビリティ、軽量というDockerのメリットを発揮するために非常に重要なことなのでしっかりと理解しましょう。

Dockerfileでコンテナを定義する

Dokerfileは「コンテナ内の環境がどうなっているのか定義するためのファイル」です。

Dockerfile作成

チュートリアル用のディレクトリ作成

mkdir docker_tutorial

作成したディレクトリに移動

cd docker_tutorial

Dockerfileを新規作成

touch Dockerfile

(Visual Studio Codeを使用しているならば、code Dockerfileでも可)

以下のようなDockerfileを作成します。

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# ワーキングディレクトリを /app に設定
WORKDIR /app

# カレントディレクトリの中身を/appにあるコンテナにコピー
COPY . /app

# requirements.txtに記載されたパッケージをインストールする
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 外部からこのコンテナを使用できるようポート番号を80に設定する
EXPOSE 80

# 環境変数を設定
ENV NAME World

# コンテナがローンチされた時にapp.pyを実行する
CMD ["python", "app.py"]

このDockerfileは「requirements.txt」と「app.py」の2つのファイルを参照しています。 この2つのファイルを同じディレクトリ(僕の場合、docker_tutorial/)に作成しましょう。 そしてコンテナにrequrements.txtに記載されたpythonライブラリをインストールしています。 これらのファイルはまず、DockerfileのCOPYの行で使用します。 そしてHTTPを通じてapp.pyにアクセスすることが可能となっています(EXPOSEでポート番号を80に設定したから)。

requirements.txt↓

Flask
Redis

app.py↓

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

これであなたのPCにpythonやFlaskなどのライブラリがインストールされていなくても、これらのシステムを動かす準備が整いました。

アプリケーションのビルド

まずはディレクトリ内にちゃんと先ほどのファイルがあること、 そしてチュートリアルのために作成したディレクトリのルートにいることを確認しましょう。 正しいければ、次のような結果になります。

$ ls
Dockerfile     app.py    requirements.txt

次にbuildコマンドによりDocker imageを作成します。 このとき--tagオプションをつけることで名前をつけることができます(-tでも可)。

$ docker build --tag=friendlyhello .

↓実行結果
Sending build context to Docker daemon   5.12kB
Step 1/7 : FROM python:2.7-slim
2.7-slim: Pulling from library/python
177e7ef0df69: Pull complete 
f6b2167b8d5a: Pull complete 
432b044db3f9: Pull complete 
7356f8556c46: Pull complete 
Digest: sha256:df3ba9998242864e650d62d158685c3c7af8c4f3ae1545bdc38780473b0b6c55
Status: Downloaded newer image for python:2.7-slim
 ---> f090c78858fa
Step 2/7 : WORKDIR /app
 ---> Running in de96301c1534
Removing intermediate container de96301c1534
 ---> ac6bc917db3d
Step 3/7 : COPY . /app
 ---> b8dc9d8ce04a
Step 4/7 : RUN pip install --trusted-host pypi.python.org -r requirements.txt
 ---> Running in 602fa87b6cd4
Collecting Flask (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting Redis (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB)
Collecting itsdangerous>=0.24 (from Flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Jinja2>=2.10 (from Flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting Werkzeug>=0.14 (from Flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting click>=5.1 (from Flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->Flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/bc/3a/6bfd7b4b202fa33bdda8e4e3d3acc719f381fd730f9a0e7c5f34e845bd4d/MarkupSafe-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis
Successfully installed Flask-1.0.2 Jinja2-2.10 MarkupSafe-1.1.0 Redis-3.0.1 Werkzeug-0.14.1 click-7.0 itsdangerous-1.1.0
Removing intermediate container 602fa87b6cd4
 ---> 51560c42984e
Step 5/7 : EXPOSE 80
 ---> Running in 3026d65723f9
Removing intermediate container 3026d65723f9
 ---> ea78dabe5b44
Step 6/7 : ENV NAME World
 ---> Running in c9a8cdf73279
Removing intermediate container c9a8cdf73279
 ---> b304b9575853
Step 7/7 : CMD ["python", "app.py"]
 ---> Running in f67c275a5d91
Removing intermediate container f67c275a5d91
 ---> 0e961526a74d
Successfully built 0e961526a74d
Successfully tagged friendlyhello:latest

実行結果をみると、Step 1/7, Step 2/7, ..., Step 7/7 というようにDockerfileで記述した7つの命令が順に実行されている様子が伺えますね。

さきほどビルドしたimageはどこにあるかというと、 PCのローカルなDocker image レジストリにあります。 次の方法で確認しましょう。

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
friendlyhello       latest              0e961526a74d        7 minutes ago       131MB
hello-world         latest              fce289e99eb9        2 weeks ago         1.84kB
python              2.7-slim            f090c78858fa        2 weeks ago         120MB

アプリケーションの実行

アプリケーションを実行するためには、 ローカルのポート4000にコンテナのポート80を-pオプションで割り当てる必要があります。

実際に次のコマンドで実行と割り当てをおこないます。

$ docker run -p 4000:80 friendlyhello
実行結果↓
* Serving Flask app "app" (lazy loading)
* Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

実行結果をみてください。 Running on http://0.0.0.0:80/というように、Flaskサーバ(app.py)がアプリケーションをhttp://0.0.0.0:80/で実行していると書いてあります。

しかしながらアプリケーションはhttp://0.0.0.0:80/ではなく、 http://localhost:4000/で動いています。

これはアプリケーション実行時に$ docker run -p 4000:80 friendlyhelloというコマンドで実行したとき、 コンテナのポート80をローカルのポート4000に割り当てたためです。

実際に任意のブラウザでhttp://localhost:4000/にアクセスしてみましょう。

確認したらアプリケーションをCtrl+Cで停止します。

もしWindows7上でDocker Toolboxを使っている場合、先ほどの実行コマンドでは動きません。 localhostの部分をDocker MachineのIPアドレスに置き換えてください。 Docker MachineのIPアドレスの確認方法はdocker-machine ipです。

例:http://192.168.99.100:4000/

またWindowsだとCtrl+Cでコンテナを停止できないそう。 Windowにおけるコンテナの停止方法は以下のステップでおこなってください。
  1. Ctrl+C
  2. docker container lsで実行中のコンテナを確認。
  3. docker container stop で停止したいコンテナを指定する。

またdetached modeでバックグラウンドでアプリケーションを実行することもできます(-dオプションを追加)。

$ docker run -d -p 4000:80 friendlyhello

バックグラウンド実行すれば、使用しているターミナルが占有されません。しかし占有されないということはCtrl+Cでアプリケーションを停止できません。

なのでバックグラウンド実行しているコンテナを docker container stop <CONTAINER ID>で停止します。

これをおこなうには、まず停止したいコンテナID(<CONTAINER ID>)を知る必要があります。

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
e6bc47bab323        friendlyhello       "python app.py"     6 minutes ago       Up 6 minutes        0.0.0.0:4000->80/tcp   practical_meninsky

上記コマンドで「friendlyhello」というコンテナのIDはe6bc47bab323であると確認できました。

※人によってそれぞれIDは異なります。

このIDを用いてバックグラウンド実行しているコンテナを停止しましょう。

$ docker container stop e6bc47bab323

作成したimageを他のマシンから使用できるようにする

Dockerの良さの1つにポータビリティがあります。 それを実感するために、先ほど作ったイメージをアップロードし、他の場所で実行してみましょう。

そのためには、レジストリにpushする方法を知る必要があります。

レジストリというのは、リポジトリの集合です。 そしてリポジトリはimageの集合です。 コードがすでにbuildされている点を除くと、GitHubのようなものだと気づくかもしれません。

まずアップロードの流れを簡単に示しておきます。

  1. Docker IDでログインする
  2. imageにタグ付けする(オプションだけどあったほうが好ましい)
  3. imageをpushする

まずはPCからDocker public レジストリにログインします。

$ docker login
実行結果↓
Authenticating with existing credentials...
Login Succeeded

次にimageにタグ付けをします。

このタグ付けをすることで、ローカルにあるimageとレジストリ上のリポジトリを紐づけることができます。 タグ付けのためのコマンドの文法は次の通りです。

docker tag image username/repository:tag
  • image:タグ付けしたいローカルにあるimageを指定
  • username:自分の名前
  • repository:意味がわかる名前に設定(今回ならば、DockerのGet startedをやっているので、get-startedにする)
  • tag:意味がわかる名前に設定(今回ならば、DockerのGet startedのPart2をやっているので、part2にする)

実際にタグ付けします。

$ docker tag friendlyhello <username>/get-started:part2

docker imageを確認してみると、先ほどタグ付けした結果が反映されていることがわかります。

$ docker image ls
実行結果↓
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              0e961526a74d        2 hours ago         131MB
tomoyamori/get-started   part2               0e961526a74d        2 hours ago         131MB
hello-world              latest              fce289e99eb9        2 weeks ago         1.84kB
python                   2.7-slim            f090c78858fa        2 weeks ago         120MB

では実際にタグ付けしたimageをリポジトリにアップロードしてみましょう。

$ docker push <username>/get-started:part2
実行結果↓
The push refers to repository [docker.io/<username>/get-started]
911ba4e2d3cf: Pushed 
331a11021f29: Pushed 
3e1bb2e14d3e: Pushed 
af9628477752: Mounted from library/python 
f1bd403e5041: Mounted from library/python 
b7fcb2747224: Mounted from library/python 
7b4e562e58dc: Mounted from library/python 
part2: digest: sha256:a2de3c9923055f58b20767edd4d9cddb3e68e57f11a6ffcdd8c9156eac9da35c size: 1787

これで先ほど作業していたローカル環境以外からもfriendlyhelloを使用できるはずです。

試しに違うマシンからやってみましょう。

ちなみに僕は、次の環境で試してみました。 仮想マシンではなくて異なる物理マシンでもできると思います。

CentOSへのDockerインストールは下記記事を参考にしました。

qiita.com

CentOSからdocker run -p 4000:80 <username>/get-started:part2を実行すると以下のようになるはずです。

CentOSでもコンテナが使用できている様子

CentOSのマシンにはfriendlyhelloというimageはないのでpullによってダウンロードしている様子が伺えますね。

またCentOSのマシンのブラウザでhttp://localhost:4000にアクセスするとちゃんと動いていることが確認できました。

CentOS上でのlocalhost:4000の結果

まとめ

今回はDockerチュートリアルとして、 Getstarted-Part2を日本語で説明しました。

内容をもう一度まとめておきます。

  • 第2章の位置付け
  • Dockerfileでコンテナを定義する
  • アプリケーションのビルド
  • アプリケーションの実行
  • 作ったimage(アプリケーション)を他のマシンから使えるようにする

part3も勉強するので書きます。 2019/1/20更新

第3章(サービスについて)はこちらから!

moritomo7315.hatenablog.com

やってみたわかった「Railsチュートリアル」の効果的なやり方

プログラミングをしている様子

2019年4月からWeb系エンジニアとして働くため,Railsチュートリアルをやってみました。

1周やってみての感想や2周目やるときに気をつけるポイントなど紹介します。

僕の現在のプログラミング知識などはAboutページ を参照ください。

今回の記事で対象としている読者

Railsチュートリアルって何?

RailsチュートリアルはWebアプリケーション開発で使用するRailsと呼ばれるフレームワークの学習のためのチュートリアルです。

railstutorial.jp

Railsチュートリアルでは具体的に次のことを学習できます(第1章の言葉を引用します)。

Ruby on RailsチュートリアルはWeb開発者やIT起業家を目指す方向けの優れた入門書として書かれており、Rubyの基礎、HTMLとCSS、データベース、バージョン管理、開発技法などWeb開発のすべてが網羅されています。本チュートリアルは初心者のみならず、Web開発のベテランにとっても有用です。MVCやREST、ジェネレータ、マイグレーション、ルーティング、ERBなど、Railsフレームワークのコア技術を本チュートリアルでまとめて学ぶことができます。初心者・ベテランを問わず、Ruby on Railsチュートリアルを最後まで終えることができれば、Rails周辺のさらに高度な内容の書籍、ブログ、スクリーンキャストなどを読み解く力を身に付けられます。

 Rails チュートリアルをどのように一周したか

まずどのように1周したのか紹介します。

使用したPC・開発環境

やり方

チュートリアルを順番に読みながら、実際に手を動かしてアプリケーションを作りました。

ローカル環境でやっていたので、自分のPCの環境に影響するためエラーと戦うこともあります。

moritomo7315.hatenablog.com

 Rails チュートリアルで学べたこと

Railsチュートリアルで学べたことはざっくり言うと次の2つでした。

  • Webアプリケーション開発の概念(MVCモデルなど)
  • Webアプリケーション開発の一連の流れの体験

それぞれについて具体的にどんなことが学べたか説明していきます。

Webアプリケーション開発の概念(MVCモデルなど)について

僕自身Webアプリケーション開発をしたことはありませんでした。 コードを書く経験はありますが、たくさんのコードが絡み合って1つのアプリケーションとして動作するようなものを開発したことはありませんでした。

WebアプリケーションはJavascriptCSSRubySQLなど様々なプログラミング言語が相互作用することで実現されています。

情報工学系の大学在学中の方のなかでも、これらの事実は知っていても、

「実際どのように動いているの??」というような疑問を抱えている人は非常に多いのではないでしょうか。

大学では理論を学ぶところであるので実際に実用的なWebアプリケーション開発など、自分のアイデアを形にするということを教えてもらう場所ではありません。

そのため Webを支える技術などの良本を読んで勉強する方が多いと思います。


しかし、読んで理解できたって人は少ないのではないのでしょうか。専門書等は挫折する人が多いイメージです。

実際にRailsチュートリアルで手を動かしながら学ぶことでその疑問は晴れると思います。

Webアプリケーション開発の一連の流れの体験

もちろんRailsのことを学べたことは有益でしたが、 個人的にはWebアプリケーション開発の一連の流れの体験で、次の3つを学べたことが非常に有益でした。

先でも、大学の講義等でWebアプリケーション開発を学べないと言いましたが、この3つのことは実際に働いているか、自分から経験しにいかないと学べないことだと思います。

特にテスト駆動開発はその1つです。

応用情報技術者試験の勉強やソフトウェア開発の大学院の講義でテストについてはざっくり学びます。 しかしながら実際にテストのコードを書くなどはしません

僕が一番Railsチュートリアルをやってみてよかったことが、テストについて勉強できたことでした。

もっとテストについて勉強したいって思ってしまいました。

 「こうすればよかった!」と思ったこと

次にこういった方法でやればよかったなぁ〜と気づいたことをシェアします。

Railsチュートリアルをやってみて、 こういった方法でやればよかったなぁ〜と途中で思ったことがありました。

2周目やるときはこれから紹介する方法でやりますし、

もしこれからRailsチュートリアルやってみようって思う方がいましたら、ぜひこの方法でやってみてください。

僕が思う、Railsチュートリアルの学びの効果を最大化させるやり方

Railsチュートリアルは14章構成となっております。

目次はこちらのリンクからご覧ください。

まず目次をみたときに意識していただきたいのが、

  • 独立している章
  • 複数にまたがっている章

があることです。

僕が1周やってみて独立した内容を扱っている章は、

1〜5章、13, 14章

だと思います。

その他の6〜12章は関連した内容になっています。

ですので、「独立している章」と「複数にまたがっている章」で異なるやり方で取り組むと効果的だと思います。

 独立している章の取り組み方

独立している章は、チュートリアルを読みながら実際に手を動かしていくやり方で十分だと思います。

章自体が独立しているので、新出の概念等はその章でわかりますし、いろいろなメソッドなどの関連もそんなに複雑ではないので理解しやすいと思います。

 複数にまたがっている章の取り組み方

複数にまたがっている章は、独立している章と同じ取り組み方をすると、

「なんでこのパス名なんだっけ?」「このメソッドなんだっけ?」、とこれなんだっけと疑問がでて、深い理解をすることができなくなってしまいます。

先に述べたように僕は、順番に読みながら、その都度手を動かしてやっていたので、

6〜12章をやっている途中に、「これなんだっけ?」、「これとこれってどういう関係性だっけ?」と感じ、

全体像が見えず、方向性がわからないまま取り組むこととなってしまいました。

そこで色々考えてみた結果、 これいいんじゃないか?と思う、6〜12章のやり方は

  1. 一気に6〜12章を読んでしまう。
  2. 6〜12章で繋がっているものをまとめておく(名前付きパスなど)。
  3. 1と2のステップで全体像を掴むことができたら、6章から順番に手を動かしながら取り組む。

特に2のステップが重要だと思います。 名前付きパスなどは、度々登場します。

Rails命名規則の勉強にもなると思います。 命名規則やコードででてくる記述の関連性をしっかりと理解することで、RailsによるWebアプリケーション開発の理解の促進効果もグッと上がりそうです。

僕も2周目はこの方法でやってみます。

まとめ

今回は、Raisチュートリアルをやってみた感想と、僕が思うチュートリアルの効果的な取り組み方について書きました。

もう一度まとめておくと、

  • チュートリアルをやって学べたこと
    1. Webアプリケーション開発の概念
    2. Webアプリケーション開発の一連の流れ
  • チュートリアルの学びを最大化できる取り組み方
    1. 独立している章と、複数にまたがっている章でそれぞれ異なる方法で取り組む
    2. 複数にまたがっている場合は、まず全体像をしっかりと掴む

これからWebエンジニアを目指している方、Railsチュートリアルに取り組もうと考えている方、挫折しちゃった方、参考にしてください!

大学院生が教える簡単な早起きのコツ 

フリー素材(写真AC)朝

大学院生が早起きのためにやっていること

こんにちは、今日は早起きについて書きました。

所属している研究室が朝型の研究室で、学生みんなだいたい午前9時から10時には揃っています。

割と研究室にしては珍しいのかもしれません。

みなさんは早起き得意ですか? 社会人のひとは平日は毎朝早起きして出社してますよね。

学生さんはどうでしょうか。 早起きが得意な人、苦手な人がいると思います。

特に理系学生で、大学の講義がなくなると好きな時間に研究室にいけばよくなりますよね。

朝遅くに起きて、昼ご飯食べに大学に行って研究して夜遅く帰る。 そしてまた朝遅く起きて、、、の人も多いのではないでしょうか?

研究室配属から二年半早起きを続けれているので、

早起きが苦手な人に向けて早起きのコツをシェアしたいなと思います。

ただ人それぞれにあった生活リズムがあります。

早起きがしたい!って人は参考にしていただければなと思います。

メインの内容

  1. 早寝を心がける
  2. 寝る前の気持ちの整理
  3. 早起きのためにアプリを使う

早寝を心がける

早起きするために一番重要なのは、早寝だと思います。

早寝といえば、21時とか22時のイメージがありますが、人それぞれでいいと思います。

寝る時間は起きたい時間から逆算してください。

もし、朝6時に起きたくて、8時間寝たいのであれば、22時には寝る必要があります。 6時間で十分なのであれば、0時でいいと思います。

何よりも自分が起きたい時間に起きるためには、寝る時間を意識するだけでも変わると思います。

学生へ向けて

学生の場合、アルバイト等で早寝ができないってことありますよね。 睡眠時間がうまくとれなくて、アラームで時間通り起きても、無意識のうちに二度寝してしまっていたとか、、、

そんなことあるかと思います。

自力では難しいので工夫が必要です。

それについては、記事のあとのほうに、「早起きのためにアプリを使う」で説明します。

寝る前の気持ちの整理

次に「寝る前の気持ちの整理」しています。

整理といっても、悩んでいることをいい方向に考えるとかをやっているわけではなくて、非常に単純なことをやってます。

具体的にイメージを掴むために、こんなエピソードを紹介します。

あなたもこんなことありませんでしたか?

中学校1年生の頃、僕はソフトテニス部に入部していました。 1年生の練習はランニングと筋トレのみでした。 それが終われば球拾いを黙々とやる。手を抜いたらダメでした。 練習が終われば、先輩の代わりにコート整備。 たまに素振りをやらしてくれることはありましたが、なによりもボールを打ちたかったです。 朝練もありました。 朝7時20分頃に先生や先輩、そして1年生が集まり、ランニングと筋トレを8時10分くらいまでに終わらせる。 先輩たちはもちろん走るのではなく、ラリーや試合形式の練習をしていました。 でもどうしてもボールが打ちたい僕たちは、朝6時に学校に来て、先輩たちがくるまでコートでボールを打ってました。 先輩に見つかると怒られるので、7時くらいにはコート整備をして待ってました。

こんなエピソードありませんか?

「〇〇がしたい!」ってモチベーションがあったから、どんなに早くても起きられることあったと思います。

部活に限らず、男の子なら最新作のゲームを買った時もこんなことあったと思います。

「誰よりも早くストーリーを進めたい!そして友達に自慢してやる」って思って早起きをしてた記憶ありませんか?

これって早起きに対してポジティブな気持ちを持ってますよね。

寝る前に早起きに対してポジティブに考える

昔のように朝起きることが楽しみってことが減っていると感じませんか??

朝起きたあとに楽しみなことをつくってみてはいかがでしょうか。

  • 美味しい朝ご飯を食べよう。
  • コーヒーを飲もう。
  • 溜まってる録画番組を見よう。
  • やりたい勉強しよう。
  • 友達とモーニング行こう。

とか自分が楽しみに思えることをやろうと考えましょう。

そしたらきっと早起きできます!!

早起きのためにアプリを使う

どうしても睡眠時間がとれない、十分睡眠時間をとったんだけど目覚めが悪い。

特に遅くまで仕事があって、早寝できない日がありますよね。

少ない睡眠時間でもスッキリ起きるためには自分の睡眠サイクルを理解することで改善できます。

一般的に睡眠サイクルに関して以下のことが言われています。

ノンレム睡眠(90分)とレム睡眠(90分)のサイクルを4回、つまり約6時間の睡眠で十分といわれています。また、脳は眠りはじめの3時間で必要な休息のほとんどをとるので、3時間でよいという人もいます。

すっきり目覚めたい人に、ヒントです。レム睡眠のときに目覚めるようにしましょう!目覚まし時計をかけるときには、その日の体調を考えながら、3時間+90分、180分、270分...をめやすにするとよいでしょう。 日本医師会

レム睡眠の時に目覚めるようにしましょうと言われても

自分がいつレム睡眠なのか把握することは難しいですよね。

それに個人差があるので、3時間、4時間半、6時間...のように90分刻みでアラームをセットしてもスッキリ起きることは難しいです。

そんなときに助けになるのが、「Sleep Cycle」というアプリです。

Sleep Cycle: スマートアラーム目覚まし時計

Sleep Cycle: スマートアラーム目覚まし時計

  • Sleep Cycle AB
  • ヘルスケア/フィットネス
  • 無料

無料版、プレミアム版があり、機能は以下となってます。

無料版では以下の機能をご利用いただけます。

  • 独自技術による睡眠の分析と記録
  • 睡眠時間の詳細な統計データと日々の睡眠サイクルの記録
  • 厳選されたアラーム用メロディ
  • 起床時間をカスタマイズ可能(最大90分の範囲で設定可能)

プレミアム機能では、さらに以下のような機能もご利用いただけます。

  • 長期間にわたる睡眠の傾向分析
  • 世界の統計データと自分の睡眠時間データとの比較
  • いびきの分析
  • 睡眠トラックデータのオンラインバックアップ(クラウドへの保存)
  • 睡眠トラックデータのExcelなどへのエクスポート

このアプリの何がすごいのかというと、

  • 睡眠を分析してくれる(レム睡眠とノンレム睡眠の記録s)
  • 適切なタイミングで起こしてくれる
  • いびきの録音機能がある

こんな機能があるんです。

使い方は簡単で、

  1. 起きたい時間(仮に6時とする)をセットする。
  2. アプリが睡眠を分析してくれる。
  3. 分析結果から、5時30分から6時の間でスッキリ起きれる時間にアラームを鳴らしてくれる。

よくないですか?? 起きやすい時間にアラームを鳴らしてくれるのは非常にありがたいのではないでしょうか。

ちなみに睡眠の分析結果をグラフに表示してくれます.

レム睡眠とノンレム睡眠のグラフ

また、データが集まってくるとさまざまな統計データも見ることができます。

例えば、就寝時間や睡眠時間を見ることも可能です。

就寝時間と睡眠時間の可視化

このアプリを使って、自分の生活習慣を見直してみるといいでしょう。

まとめ

僕はこの3つのことを早起きのために心がけています。

もう一度まとめておきます。

  1. 早寝を心がける
  2. 寝る前の気持ちの整理
  3. 早起きのためにアプリを使う

早起きのためには、起きる時間から逆算して寝る時間を決めることが大事ですね。

でもスッキリ目覚めれないな、と感じるのであれば、朝起きた後に楽しみな予定を入れてみてはどうでしょうか。

それでもスッキリ目覚めれない!ってときはアプリを使ってみてはいかがでしょうか!

何か新しい気づきがあれば幸いです。

大学生のうちにやっておくべきだったこと

大学生のうちにやっておくべきだったこと

こんにちは、もう12月も半分過ぎましたね。 僕は現在大学院の2年生なのであと大学院生活も残り二ヶ月となりました。 残すは修士論文や研究会での発表ってところなのですが、

ふと学部生のときに

「あれやっておけばよかったな」

と思うことが何度かあります。

そのときのときにやればいいんだけど、

周りの目を気にしたり、周りがどう思うのか

を考えていたことが妨げになっていました。

本記事が伝えたいこと

  • やりたいと思ってることは、すぐやったほうがいい
  • 周りの目は気にしなくてもいい、やってみると気にならなくなる
  • 僕は岐阜県在住の地方大学院生です。地方大学生目線でやっておけばよかったことを書きました。

    結論から言ってしまうと、 人それぞれやりたいことは違いますが、

    やりたいと思ったときにすぐやるべき です。

    現在大学生、もしくは高校受験生の子の参考になれば幸いです。

    やっておけばよかったこと

    1. ブログ
    2. インターンシップ
    3. 乱読
    4. 運動

    思いついたのがざっとこんな感じでした。 それぞれなんでやっておけばよかったのか説明していきます。

    ブログ

    f:id:moritomo7315:20181217211813j:plain

    一番やっておけばよかったなと後悔しているのが、ブログです。

    今こうしてブログで自分の考えとか勉強したことをアウトプットしているわけですが、 実を言うと、学部一年生の頃からブログやってみたいなーって思ってました。

    そのときは周りの目線とかすごい気にしていて、周りがやっていないことをやっていくのに勇気が出ませんでした。

    結局最近になってブログを初めたので、5年越しとなります。 5年前にもしブログを始めていたらどうなっていたのかわかりませんが、今よりずっと文章も上手くなっていると思うし、情報収集能力もついていたんじゃないかと思います。

    いまは、ほんとにブログをやってみてよかったと思っています。 最初は僕なんかが世に情報発信していいものかと躊躇していましたが、やってみるうちにそんなことは気にならなくなります。

    むしろブログを書いたことで行動力がさらに増したような気がします。

    学部3年のときに3週間アメリカのポートランドへ短期留学にいったことがあるし、去年国際学会のために韓国にも行ったことがあるので、絶好の情報発信チャンスだったと思います。

    インターンシップ

    f:id:moritomo7315:20181217211830j:plain

    地方学生のみなさんすべてそうではありません。 ただ僕の周りにインターンシップをしている人はいませんでした。

    大学生はアルバイトをするっていうのが当たり前な風潮でした。 インターンシップなんて就活前にやるものって思ってました。

    みんな何かしらのアルバイトをやっていました。 飲食店、学習塾、アパレルなどが多かったです。というかアルバイトといえばそれくらいしか思いつかないのではないでしょうか。

    僕は元からIT企業でエンジニアとしてサービス開発に携わりたいという目標がありました。 今思えば、大学卒業後の進路が明確なのだから、アルバイトではなくインターンシップにチャレンジすればよかったです。

    東京とかはインターンシップの受け入れ先が多いイメージがありますが、東海地方は全然ないって理由でリサーチすらしていませんでした。

    だけど、去年就職活動をして、名古屋駅周辺などいくつかインターンシップができる企業があることを知りました。

    地方だからって何も行動していなかった自分に後悔しました。

    もし今、この記事を読んでくださっている地方大学生で、地方ってことを理由にしてインターンシップを諦めているのであれば、もっとリサーチしたほうがいいと思います。

    今はクラウドソーシングなども充実していて地方でも仕事がもらえる世の中だと思います。

    地方だからと理由で諦めてるあなた、きっと突破口はあるはずです。

    乱読

    f:id:moritomo7315:20181217211945j:plain

    次は乱読です。

    乱読とは特定のカテゴリの本に決めずに興味を持ったいろんな本をどんどん読んでいく、読書のことです。

    学部生自体、ときたま読書はしてたんですが、小説メインでした。 「1Q84」を読んで村上春樹さんの世界にはまって他の作品も読んでみる。そんな感じに結構偏ってました。

    1Q84 BOOK 1

    キングコング西野さんの著書、「魔法のコンパス」が2016年に発売されています。

    魔法のコンパス 道なき道の歩き方

    僕自身、今までやりたいと思っていたブログを始めてみようと思ったきっかけが、キングコング西野さんの「新世界」でした。

    新世界

    すごく背中を押してくれました。もし2016年大学4年生のとき、「魔法のコンパス」を読んでいたら残った大学院の2年間をもっと有意義に過ごしていたかもしれません。

    乱読は、偶然の出会いを与えてくれると思います。 きっと自分の背中を押してくれる素敵な本に出会えるでしょう。

    運動

    f:id:moritomo7315:20181217212237j:plain

    運動はやっておくべきでした。

    実のところ、大学4年間で高校卒業時と比べて8kgほど太ってしまいました。

    太ることは悪いと思いませんが、顔に肉がついてたり、お腹がだらしなかったりして、後悔します。

    今年は割と運動しているので、2kgほど痩せましたがまだまだ高校当時と比べたら、、、

    これからどんどん脂肪が落ちにくい身体になっていくので気をつけないといけませんが、 運動を続けていたらこうはなってなかったと思います。

    大学生になって、アルバイトするようになったり、行動範囲が広くなって遊びの選択肢も増えます。 そうすると運動をすることが一気になくなってしまいました。

    絶対運動はやったほうがいい!

    まとめ

    今回は、大学生のうちにやっておくべきだったことを紹介しました。 5年前に戻って自分に言い聞かせてやりたいくらいです。

    もう一度まとめておくと、

    1. ブログ
    2. インターンシップ
    3. 乱読
    4. 運動

    です。

    これは僕に限っての項目ですが、もっとも言いたかったことは次の2つです。

  • やりたいと思ってることは、すぐやったほうがいい
  • 周りの目は気にしなくてもいい、やってみると気にならなくなる
  • 今振り返ってみると、やってみたいことに挑戦できる時間はめちゃくちゃありました。 課題とかたくさんあったけど、スマホアプリに没頭していたこともあるし、ポケモンやってたこともあるし、、

    まあそれもいい思い出ですが、本当にやりたいと思っていることが心の中にあるんだったら、どんどん挑戦した方がいいです。

    いまくすぶっている地方学生の方がこのブログを読んで、何か行動してみようと思ってくれたらとても嬉しいです。

    読んでいただきありがとうございます。

    コミュニケーションデザインのヒントを登山から学ぶ

    概要

    コミュニケーションをデザインすることは重要ではないでしょうか? 最近オンラインサロンやオンラインコミュニティなど流行っていますね。そこではみんなが似た意思や価値をもっています。しっかりとした交流のためのプラットフォームが存在しているから、オフラインとオンラインともに議論が活発です。議論から刺激を受けて、自分の活動にコミュニティの学びを生かしていくなど個人それぞれが頑張れる場所なんじゃないかと思います。

    僕はふとコミュニティでは、「人と人が会話しやすいことが大事」だと思いました。 なにかを相談したくても、意見を言いたくても、言えなかったら自分の中にその意見は止まってしまいます。誰かに相談すれば人生が変わるかもしれません。 じゃあコミュニケーションがしやすい環境に共通することは何だろうか。 コミュニケーションをどうデザインしたらいいんだろうか? これについて僕の大好きな登山から考えてみました。

    f:id:moritomo7315:20181215121824j:plain:w500

    登山でのコミュニケーション

    登山では登山者同士で会話する場面がすごく多いです。その場面が自然発生するので不思議ですが、ここにコミュニケーションの秘訣が隠れてそうじゃないですか?

    道中でのあいさつ

    登山道というのは、急登になっていたり、気の道があったり、岩ボコなみちだったり、バランスを崩してしまったら命に関わるような道など様々です。

    そんなときに必要となるのが、登山者同士、下山者同士の気遣いです。基本的に登山者優先というルールがあるみたいですが、道によっては下山者を優先した方がいい場合もあります。 登山道では常に人を思いやる気持ちが生まれます。いっしょに登山しているメンバーを思いやり、他の登山客のことも考えて道を進んでいきます。

    下山者とすれ違う際には、「こんにちは」、「お疲れ様です」など元気よく笑顔であいさつします。不思議なのが、みんながあいさつに返事してくれます。 下山時に登山者とすれ違うときには、「もう少しです。頑張ってください!」など励ましのあいさつをします。

    写真を撮って欲しい!

    登山では写真撮影がつきものです。登頂したぞ!って写真や、かっこいい岩との記念撮影、背景には綺麗な景色。撮影する場所がたくさんあります。自分たちではどうしてもメンバー全員が写る写真は撮れないので、他の登山客にお願いをします。

    山小屋でのコミュニケーション

    一泊二日で登山にいくような山には、山小屋があります。素泊まり、朝夕食つき、などプランはいろいろあります。 山小屋はその山の頂上から標高300mしたとか割と近くに位置しています。山小屋に一泊して早朝に頂上へ向かい、頂上から日の出を拝むってのが多くの登山客の流れじゃないでしょうか。

    長い登山道を乗り越えてきた登山客たちが、山小屋でくつろいでいます。 山小屋には炊事場や外のテーブル等があります。そこで自分たちでバーナーを使っておつまみをつくってビールを飲んだりしてのんびりします。

    f:id:moritomo7315:20181215121740j:plain:w500

    近くにいる人に「どちらから来られたんですか?」と聞かれたり、こちらから会話に入ったりすごい気持ちのいいコミュニケーションが山小屋では生まれています。すごいのが、年齢関係なく、わいわいおしゃべりしていることです。どんな世代の人でも山ではみんな仲良くしています。

    どうして登山はコミュニケーションが生まれるのか

    ここからが本題です。登山ではなぜコミュニケーションしやすいのか考えてみます。読者のみなさまも考えながら読んでみてください。「全然意見が違う!」、「その意見おかしいんじゃない?」って思ったら遠慮なくコメントください!!

    道中での道のゆずりあいやあいさつ

    これは、

    • 相手のことを思っていること
    • 場の状況(雰囲気)の理解

    がすごく効いているんじゃないでしょうか。

    いまはこういう道になっているから下山者を優先させた方がいいんじゃないか、などめちゃくちゃ相手のために考えます、

    「思いやり」と「状況理解」って普段のコミュニケーションでも必要ですよね。たとえば誰かから相談を受けるときを例にしてみます。相談してくる人は、一生懸命相談したいことを話しています。

    ただ相談したいことっていうのはモヤモヤしていることも多くて、あまりまとまった説明ができないですよね。そんな場面では聞き役の働きが大事となります。相談者の状況を理解してあげること、そして何より相談者目線でまず何を相談したいのか思いやって考えてあげること。

    それができてやっと相談者が何を相談したいのかをわかってあげることができます。

    写真撮影でのコミュニケーション

    写真撮って欲しいからお願いしないといけない。でもそれってディズニーランドとかもそうじゃないかって感じだと思う方がいるかもしれません。

    山登りと、ディズニーランドとかでお願いする写真撮影の決定的な違いは、 「景色が変わるスピード」、「人の流動性」だと思います。

    景色が変わるスピード

    ディズニーランドだと綺麗な建物などを背景に写真を撮ることがありますよね。でもこの景色って一日中静止してますよね。

    けど登山はそのときの1分1秒の瞬間が大事なんですよね。雲が景色を邪魔しない瞬間を撮りたい人もいれば、雲がいい感じの配置になった時に撮りたいとか、こだわりがあると思います。

    不思議なことに1分1秒の瞬間が現れるまで粘ってくれる人が登山客にはいるのです。僕も以前そういう体験をしました。本当に優しい方が集まっています。

    ディズニーランドにいる人が優しくないと言ってるわけじゃないですよ。優しいスタッフ、笑顔であふれるお客さんがいて最高の場所だと思います。

    ただ常に同じ背景を保存できるテーマパークだと、一瞬で撮影がおわるのでコミュニケーションは生まれません。登山だとその1分1秒を取るために待っている間にコミュニケーションが生まれます。そしてその1分1秒間にしかできない景色が取れた瞬間にお互い喜びを感じます。

    そこで「共通意識」が生まれてコミュニケーションも弾みます。

    人の流動性

    「人の流動性」っていう観点では、ディズニーランドはたくさん人がいるので誰でもいいから撮ってくれそうな人を探しますよね。問題はそこではないと僕は思います。問題は写真を撮ってあげる側にあります。写真を撮ってほしそうにしている人を見かけますよね?でも、自分から撮ってあげる人は少ないと思います。人はたくさんいるので、「別に自分じゃなくても他の人がいるからいいじゃん」って通り過ぎて行きませんか?

    一方、登山では人数は限られています。そこで「人を思いやる気持ち」が生まれます。自分が撮ってあげなかったらこの人は自撮りをすることになり、山での思い出の写真に妥協してしまう。そう思って写真をとってあげましょうかと声をかける人は多いと思います。

    山小屋でのコミュニケーション

    山小屋に着く頃にはもう疲れ果てています。 けどなぜコミュニケーションが生まれるのでしょうか。

    僕は、「共感」と「安心感」だと思います。

    登山者たちはこの山小屋に何のためにやってきましたか? 縦走しにいくために泊まる人、一泊二日で日の出をみに来た人、様々な目的があると思いますが、とりあえず泊まるその日は、この山小屋を目指してやってきました。 山小屋への道のりは、過酷です。 その過酷な道を乗り越えてみんなやってきています。

    あの人もあの人もあの人も、みんな乗り越えてきたのかと思うとなんか親近感がわきますよね。それが「共感」です。 それだけでは話しにくいですよね。

    でも山に登ってきている人って「登山」っていう共通の趣味があります。つまり共通のネタをみんな持っているんですよね。

    だからコミュニケーションをとるのに「安心感」があります。

    登山からコミュニケーションのヒント

    以上の登山の話からコミュニケーションデザインのヒントをまとめます。

    思いやり

    相手のことを考えられる環境なのか

    状況理解

    コミュニケーション取れない状況を理解できるか、そしてそれを防ぐ状況にデザインできるか

    景色が変わるスピード

    その瞬間にしかない景色を共有できるか

    人の流動性

    この人だからコミュニケーションがしたいと思わせれるか。 ただコミュニティを育てていくことを考えると、人を少なくするとか、人数を固定してしまうのはいけないと思います。 やはり多様な人とコミュニケーションができるほうが個人としてもコミュニティとしても良いと思います。

    例えば、人数を固定数にグループわけしてコミュニケーションをとって、数分たったらローテーションするとか。 いろいろ工夫が考えれそうです。

    ※一般的な流動性の意味として使っておりません

    共感と安心感

    共通意識や安心感を与える場をつくり、話したいと思わせれるか

    この6つのヒントを登山から見いだしました。 コミュニケーションが大事となる場を作る人にとって、この6つのヒントから何か仮説を立てアクションを起こしてみてはどうでしょうか。

    登山はオフラインのレジャーなので、オフラインでのコミュニケーションには役立つと思いますが、 オンラインでのコミュニケーションでは工夫して取り入れる必要があります。

    みなさんのコミュニケーションデザインに役立つと嬉しいです。

    今後も趣味から何か役立つヒントを探しつづけていきます。

    【奮闘記】rails newでactivesupportのバージョンコンフリクトが起きた

    概要

    rails newで新しいプロジェクトを作ろうとしたらactivesupportのバージョンコンフリクトが起きてしまいました。 結果的にrailsのバージョンとactivesupportのバージョンを合わせないといけないようです。特に今回はrailsチュートリアルに沿っているため、v5.1.6指定です。それより新しいv5.2.2などがインストールされていたために、activesupportのバージョンコンフリクトが起きてしまったようです。 先に結論だけ述べておくと、「railsのバージョンより新しいバージョンのactivesupportがインストールされてると競合してしまいエラーが起こる」ってことがわかり、無事解決しました。以下奮闘記ですので、よかったら僕の試行錯誤ストーリーをご覧ください。

    PC環境

    OS: MacOS Mojave クラウドIDEではなくてローカル環境でやってます。

    奮闘記

    Railsチュートリアル第二章を始めようとしたら、一歩目のrails newで躓きました。 ディレクト~/environment/rails _5.1.6_ new toy_appとterminalで実行すると以下のように出力されました。

    The i18n gem is not available. Please add it to your Gemfile and run bundle install
    /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/specification.rb:2278:in `check_version_conflict': can't activate activesupport-5.2.2, already activated activesupport-5.1.6.1 (Gem::LoadError)
        from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/specification.rb:1407:in `activate'
        from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:89:in `block in require'
        from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:88:in `each'
             ・
             ・
             ・
        from
    /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:39:in `require'
        from /Library/Ruby/Gems/2.3.0/gems/railties-5.1.6.1/exe/rails:9:in `<top (required)>'
        from /usr/local/bin/rails:22:in `load'
        from /usr/local/bin/rails:22:in `<main>'

    ディレクトリでrails -vなどrailsコマンドを使用すると同様の出力となります。 ディレクト~/environment/hello_app/ではrailsコマンドが問題なく使用可能となっています。

    まずはThe i18n gem is not available. Please add it to your Gemfile and run bundle installについて考えてみました。

    「どこのGemfileのことなんだろう。そもそもi18nってなんだ。」

    i18nはアイエイティーンエヌと呼ばれるそうです。

    ソフトウェアである限られた言語でしか使えない状態から多言語が使えるように対応すること。 d.hatena.ne.jp

    調べてもそれと今回のことがどう繋がるのかよくわからなかったです。

    でも`Gem::LoadErrorとあるのでgem関連に問題があるのか。

    とりあえずgoogleで「gem loaderror」で検索。

    qiita.com

    「ほうほう。bundle updateすればいいのかな?とりあえずやってみよう。」

    実行結果は

    Could not locate Gemfile

    そりゃそうです。ディレクトリにGemfileはありませんから。

    よく出力を読むと、`check_version_conflict': can't activate activesupport-5.2.2, already activated activesupport-5.1.6.1とある。

    よく読んだら、すでにv5.1.6.1のactivesupportが動作してて、v5.2.2のactivesupportは動作できないよっていうメッセージを出してくれています。

    「もしかしたら、railsのv5.2.2として動いているのか??ンv5.1.6に指定してrails newしているのに。」

    とりあえず、現在gemでインストールしたrails関連をgem list railsで確認します。 すると、以下の出力が得られました。

    *** LOCAL GEMS ***
    
    autoprefixer-rails (9.3.1, 6.7.7)
    bootstrap3-datetimepicker-rails (4.17.47)
    coffee-rails (4.2.2)
    jquery-rails (4.3.3, 4.3.1, 4.2.2)
    momentjs-rails (2.17.1)
    rails (5.1.6.1, 5.1.6, 5.0.2)
    rails-dom-testing (2.0.3, 2.0.2)
    rails-html-sanitizer (1.0.4, 1.0.3)
    sass-rails (5.0.7, 5.0.6)
    sprockets-rails (3.2.1, 3.2.0)
    tether-rails (1.4.0)
    

    「んーv5.2.2が見当たらない。いや、activesupportのことか??」

    ということで、gem list activesupportで調べると

    *** LOCAL GEMS ***
    
    activesupport (5.2.2, 5.2.1.1, 5.1.6.1, 5.1.6, 5.0.2)

    「もしかしたらactivesupportのv5.1.6.1をアンインストールしちゃえばいいのかな??」 sudo gem uninstall -v '5.1.6.1'でアンインストール後、再びrails newをしたら、

    /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/dependency.rb:319:in `to_specs': Could not find 'activesupport' (= 5.1.6.1) - did find: [activesupport-5.2.2,activesupport-5.2.1.1,activesupport-5.1.6,activesupport-5.0.2] (Gem::LoadError)

    「あれ今度はv5.1.6がみつからない。笑 てことはもしかしたらv5.1.6.1はインストールしなおして、v5.2.2をアンインストールすればいけるんじゃないか??」

    てことで、

    sudo gem install activesupport -v '5.1.6.1'

    を実行した後、sudo gem uninstall -v '5.2.2'を実行しました。そして再びrails new。そしたら、

    /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0
    /rubygems/specification.rb:2278:in
     `check_version_conflict': can't activate activesupport-5.2.1.1, already activated activesupport-5.1.6.1 (Gem::LoadError)

    もう笑うしかないです。

    「あれ、でもちょっと待てよ。最初v5.1.6.1をuninstallしたら、v5.1.6.1が見つからないと出たからv5.1.6.1は必要だと。v5.2.2をuninstallされたら次はv5.2.1.1とコンフリクト。お、もしかして大きいバージョンを優先的に読み込む的な動きをするのか??じゃあv5.2系のactivesupportをすべてuninstallしてみよう!」

    $sudo gem uninstall activesupport -v '5.2.1.1'
    
    You have requested to uninstall the gem:
        activesupport-5.2.1.1
    
    actionpack-5.2.1.1 depends on activesupport (= 5.2.1.1)
    actionview-5.2.1.1 depends on activesupport (= 5.2.1.1)
    activejob-5.2.1.1 depends on activesupport (= 5.2.1.1)
    activemodel-5.2.1.1 depends on activesupport (= 5.2.1.1)
    activerecord-5.2.1.1 depends on activesupport (= 5.2.1.1)
    If you remove this gem, these dependencies will not be met.
    Continue with Uninstall? [yN]  
    

    これらはactivesupportのv5.2.1.1に依存するようなので一緒にuninstallしておいていいでしょう。

    で、再びrails _5.1.6_ new toy_appをやってみると、

    きました!無事rails newコマンドが成功でした!

    まとめ

    ローカル環境だとやっぱりバージョンコンフリクトがめんどくさいです。 google検索してみても今回はなかなか解決策が見つからなかったのでエラーメッセージから読み取って試行錯誤してみました。

    フレームワークはバージョンがきっちりしてて面倒ですが、エラーメッセージも的確でやはり便利なものだと感じました。 引き続き詰まったところがあったらシェアしていきます。

    とりあえず解決してよかったです。同じ問題に当たってしまった方よかったらご参考ください。