unicornがどのRubyバージョンで動作しているかを調べる

背景

以前、Railsアプリケーションが動作している環境のRubyのバージョンアップを行いました。Rubyのバージョンは正しく上がっているようでしたが、Railsアプリケーションの動作が不安定になってしまいました…その時の調査のログです。

原因

結果的にはunicornが旧Rubyバージョンで動作していることが原因でした。unicornがどのRubyバージョンで動作しているかを確認する方法を記載します。

確認方法

プロセスIDの確認

unicornのmasterプロセスを探します。

1
2
3
4
5
6
7
8
9
$ ps -ef | grep unicorn
user 1797 1 0 Jul29 ? 00:00:06 unicorn master -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1840 1797 8 Jul29 ? 02:42:10 unicorn worker[0] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1847 1797 8 Jul29 ? 02:40:24 unicorn worker[1] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1857 1797 8 Jul29 ? 02:40:50 unicorn worker[2] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1872 1797 8 Jul29 ? 02:38:32 unicorn worker[3] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1894 1797 8 Jul29 ? 02:39:10 unicorn worker[4] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
user 1909 1797 7 Jul29 ? 02:37:28 unicorn worker[5] -c /var/www/user-cms/current/config/unicorn/production.rb -E deployment -D
21235 42323 42237 0 00:47 pts/3 00:00:00 grep unicorn

masterプロセスのプロセスIDは1797とわかります。
次にrootになって、/proc/プロセスIDのディレクトリを確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ sudo su -
# ls -l /proc/1797/
合計 0
dr-xr-xr-x 2 user user 0 7月 31 00:47 2020 attr
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 autogroup
-r-------- 1 user user 0 7月 31 00:47 2020 auxv
-r--r--r-- 1 user user 0 7月 31 00:47 2020 cgroup
--w------- 1 user user 0 7月 31 00:47 2020 clear_refs
-r--r--r-- 1 user user 0 7月 31 00:46 2020 cmdline
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 comm
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 coredump_filter
-r--r--r-- 1 user user 0 7月 31 00:47 2020 cpuset
lrwxrwxrwx 1 user user 0 7月 31 00:47 2020 cwd -> /var/www/user-cms/releases/20200729065345
-r-------- 1 user user 0 7月 31 00:47 2020 environ
lrwxrwxrwx 1 user user 0 7月 31 00:47 2020 exe -> /usr/local/rbenv/versions/2.4.10/bin/ruby
dr-x------ 2 user user 0 7月 31 00:47 2020 fd
dr-x------ 2 user user 0 7月 31 00:47 2020 fdinfo
-r-------- 1 user user 0 7月 31 00:47 2020 io
-rw------- 1 user user 0 7月 31 00:47 2020 limits
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 loginuid
-r--r--r-- 1 user user 0 7月 31 00:47 2020 maps
-rw------- 1 user user 0 7月 31 00:47 2020 mem
-r--r--r-- 1 user user 0 7月 31 00:47 2020 mountinfo
-r--r--r-- 1 user user 0 7月 31 00:47 2020 mounts
-r-------- 1 user user 0 7月 31 00:47 2020 mountstats
dr-xr-xr-x 6 user user 0 7月 31 00:47 2020 net
dr-x--x--x 2 user user 0 7月 31 00:47 2020 ns
-r--r--r-- 1 user user 0 7月 31 00:47 2020 numa_maps
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 oom_adj
-r--r--r-- 1 user user 0 7月 31 00:47 2020 oom_score
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 oom_score_adj
-r--r--r-- 1 user user 0 7月 31 00:47 2020 pagemap
-r--r--r-- 1 user user 0 7月 31 00:47 2020 personality
lrwxrwxrwx 1 user user 0 7月 31 00:47 2020 root -> /
-rw-r--r-- 1 user user 0 7月 31 00:47 2020 sched
-r--r--r-- 1 user user 0 7月 31 00:47 2020 schedstat
-r--r--r-- 1 user user 0 7月 31 00:47 2020 sessionid
-r--r--r-- 1 user user 0 7月 31 00:47 2020 smaps
-r--r--r-- 1 user user 0 7月 31 00:47 2020 stack
-r--r--r-- 1 user user 0 7月 31 00:46 2020 stat
-r--r--r-- 1 user user 0 7月 31 00:47 2020 statm
-r--r--r-- 1 user user 0 7月 30 22:38 2020 status
-r--r--r-- 1 user user 0 7月 31 00:47 2020 syscall
dr-xr-xr-x 5 user user 0 7月 31 00:47 2020 task
-r--r--r-- 1 user user 0 7月 31 00:47 2020 wchan

exeファイルのリンク先を確認すると、/usr/local/rbenv/versions/2.4.10/bin/rubyとなっており、Rubyの実行ファイルになっています。この場合だとバージョンは2.4.10ですね。今回はパスでバージョンがわかりますが、パスからわからない場合は、exeのリンク先の実行ファイルで-vオプションを実行すればバージョンがわかります。

おまけ

デプロイを行うのにcapistranoを使っているのですが、通常のデプロイシーケンスでは、unicornはworkerが再起動されるだけで、masterプロセスは再起動されませんでした。Rubyのバージョン変更を行った場合はmasterプロセスの停止・起動が必要となります。

自分の環境では以下のコマンドでunicornのmasterプロセスの再起動が行えました。

1
2
3
$ bundle exec cap production deploy:stop
$ bundle exec cap production deploy:start
(productionは環境名)

最初のコマンドでunicornを停止し、次のコマンドで起動しています。Rubyのバージョンを変更した場合は、masterプロセスの再起動が必要ということを覚えておきます。

この辺りを学ぶにはなるほどUNIXプロセスという本がとても役に立ちそうです。読み始めているのですが、とても楽しく読めています。機会があれば本の内容も紹介したいと思います。

ECSでタスクが起動しない時の調査方法

背景

オンプレミス環境からAWS ECSへ移行しようというプロジェクトを行っております。環境はnginx + Railsです。

Docker Desktop for Macでdocker networkを作成しnginxとrailsでコンテナ間通信ができるところまでは確認できたので、そのコンテナイメージをECRにpushし、タスク定義まで行いました。

ECSクラスターの作成を行い、作成したタスク定義を実行したところ起動できなかったのでその時の調査方法を記載します。

ECSインスタンスにログイン

起動しない原因を調査するにあたってまずはログを確認したいのですが、ログの確認方法がわかっていません…なので、本来もっと良い方法があると思うのですがよくわかっていないので、一旦ECSインスタンスにSSHログインできるようにしました。

2020/12/9追記

ログの確認方法

ECSクラスターを選択、下のタブのタスクをクリックします。

タスクの一覧が表示されます。表示されない場合は、コンテナがすでに止まってしまっている可能性が高いです。その場合は、必要なタスクのステータスStoppedにすると表示されると思います。タスクのIDのリンクをクリックします。するとタスクの詳細ページに遷移します。

画面上部にタブがあり、Logsタブをクリックします。ログを表示するコンテナを選択しますというメッセージの横にセレクトボックスがあるので、ログを表示するコンテナを選択します。CloudWatchに出力する(logDriverがawslog)設定になっているコンテナが選択できます。

選択すると下にログが表示されます。エラーなどコンテナが起動できなかった理由がわかると思います。

ECSインスタンスにログインするための設定

ECSインスタンスにログインするためには以下の設定が必要です。

  • クラスターテンプレートの選択EC2 Linux + ネットワーキングを選択する
  • クラスターの設定 -> インスタンスの設定キーペアを指定する
  • クラスターの設定 -> ネットワーキングパブリックサブネットを指定する
  • クラスターの設定 -> ネットワーキングAuto assign public IPEnabledにする
    • サブネットの設定でパブリック IPv4 アドレスの自動はいになっていればUse subnet settingでも大丈夫です
  • クラスターの設定 -> セキュリティグループでSSHを通しているセキュリティグループを選択する
    • デフォルトのセキュリティグループではNG

以上の設定でクラスターを作成します。

ECSインスタンスの起動確認

先ほど作成したクラスターを選択して、ECS インスタンスタブをクリックすると、作成したクラスターのECSインスタンスが表示されます。ECS インスタンスのリンクをクリックすると、EC2の確認ができます。

ECSインスタンスにSSHする

確認したEC2のパブリックDNS、もしくはパブリックIPにクラスター作成時に指定したキーペアを使ってログインします。

コンテナのログを確認

早速コンテナの状況を確認します。docker ps -aをすると、なにかの原因でステータスがExitedになっていました。

コンテナのログの確認にはdocker logsコマンドを利用します。

1
2
3
4
5
6
7
8
9
$ docker logs コンテナID
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: error: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2020/07/22 07:55:16 [emerg] 1#1: host not found in upstream "rails:3000" in /etc/nginx/conf.d/rails.conf:2
nginx: [emerg] host not found in upstream "rails:3000" in /etc/nginx/conf.d/rails.conf:2

nginxの設定がDocker Desktopで動作確認した時のそのままになってしまっているのが原因のようです。(docker networkを作成して動作確認したときに、Rails用コンテナをrailsという名前で起動していたため)

今回、タスク定義のネットワークモードをawsvpcにしているので、コンテナ間通信はlocalhost指定で行えます。こちらを参考にしました。

ですので、nginxのupstreamの指定をlocalhost:3000として、コンテナをbuild、pushしたら無事タスクが起動しました。

まとめ

なにか起こった時の調査にログは欠かせません。まずはログを確認するようにしたいです。
今回のログの確認方法は本来の方法ではないと思います。Fargate使っていたらできないと思いますし…
本来はCloudWatchなど利用して行うのだと思いますが、まだその辺りを理解できていないのでこれから調べていきたいと思います。

※ Container Insightsを使ってみましたが使用しているリソース確認、マップ表示くらいの機能でした。プロダクション環境では重宝するかもしれません。

パーフェクトRuby on Rails 【増補改訂版】

前作から6年ぶりの改訂

先日いつも立ち寄る三省堂書店神保町本店の技術書コーナーにいくと、パーフェクトRuby on Railsの増補改訂版が置いてありました。まだ発売日前のようですが置いてくれていたんですね。早速購入しました。

前作が2014年7月10日に初版第1刷発行ということで、6年ぶりの改訂となります。前作も手元にありますので比較してみていきます。

対象のバージョン

前作ではRuby2.0.0、Rails4.1.1が対象でした。今見るとさすがにちょっと古い感じがしますね。
今作ではRuby2.6.6、Rails6.0.3が対象です。「はじめに」にもありますが、本書執筆時点ではRuby2.7.1が最新バージョンでしたが(2020年7月21日現在も2.7.1が最新)、Ruby2.7からRuby3.0へ向けて非互換性の警告が出るようです。そのため2.6.6を利用したようです。

内容

前作は431ページで、今作は527ページと約100ページ増えています。

内容は、前作ですとPart1〜4と付録がありました。今回はPart1〜5と付録があります。

Part1 Rails Overview

Part1は前作と同様、Railsの概要、MVCアーキテクチャ、基本機能が紹介されています。今作では秘密情報の管理方法がバージョン4.0までと4.1、5.1、5.2、6.0でどのように行うかが紹介されています。

ここまでの内容は普段Railsアプリケーションを開発されている方々であればざっと流し見する感じでしょうか。

Part2 Railsの周辺知識

Part2ではRailsの周辺知識として、フロントエンド開発周りやActive 〜、Action 〜などのコンポーネントの利用方法について紹介されています。

前作ではフロントエンド開発周りで言うと、アセットのコンパイル(assets:precompile)を行う方法、CoffeeScriptの書き方、Sassの書き方などでした。
今作では、6.0から導入されたWebpackerの紹介、JavaScripthレームワークStimulusの紹介などがあります。cssもWebpackerで管理する方法で普段開発しているのですが、本書ではcssは引き続きSprocketsで管理すると記載されています。

その他は前作と同じようにActive 〜、Action 〜の紹介がされています。

Part3 Webアプリケーション開発

Part3では前作と同様、簡単なサンプルアプリケーションを作成し、そのテストも実装するという内容になっています。

前作では上記にプラスしてRailsアプリケーションの開発、運用、CI/CDについてもPart3で言及しています。この頃はまだコンテナ技術が広まっていなかったからか、仮想マシンを用いた開発、運用について紹介されています。Chefとか懐かしいですよね。今作ではPartを分けて、Part4で紹介されています。この辺りの技術に大きな変化があったということでしょう。

Part4 Railsアプリケーションの拡張・運用

今作で切り出されたPartです。RailsでのCIやコンテナ技術について紹介されています。

最近やっと着手したGitHub ActionsやDockerコンテナでのアプリケーション設定方法について記載されています。

Part5 エキスパートRails

今作のPart5は前作のPart4の内容に少し追加されているくらいの印象です。ですが、やはりこの辺りをしっかりと理解しておくことがRailsをちゃんと使いこなせるかどうかの違いになってきそうです。わたしも(Concernやコールバックオブジェクトなど)理解できていない部分があるので、もう一度見直したいと思います。

付録

付録はWindows環境でのRailsアプリケーションの構築方法、Rubyのインストール方法など環境構築方法が紹介されています。rbenvを使っています。

まとめ

内容に関して大きく変わりはないですが、今使われている技術をざっと見直したい、Railsについて理解しているつもりだけどわかっていないところを再発見したいときに流し読みするには良さそうです。もちろんRailsにまだあまり慣れていない人にとっては最初からじっくり手を動かしながら読むのがオススメです。

Docker Desktop for Macでコンテナがマウントしてるボリュームを調べる

動機

仕事でRubyのバージョンアップを行いました。ローカルの開発環境ではDockerを使っているので、新しいバージョンのRubyをインストールするようDockerfileを書き換えてイメージをビルドしました。

イメージのビルド後、あたらしいバージョンのRubyで bundle installを実施しました。すると以下のようなメッセージが表示されました。

1
Ignoring (gem名) because its extensions are not built.

古いgemが残っているからなのだと思うのですが、ちょっと気持ち悪いので対処したいと思いググってみました。すると、どこかのサイトにgemのインストールディレクトリをまっさらにしてからもう一度 bundle installするとよい、と書かれていたのでその通りにすると、アプリケーションが全く動かなくなってしまいました。bundle installは実行できますが、すでにgemはインストール済という認識でなにも行ってくれません。

docker-compose.ymlを見ると、マウントしているボリュームにbundle installしているようです。そのボリュームを調べたいと思いました。

ボリュームの一覧表示

ボリュームの一覧表示をするにはdocker volume lsを実行します

1
2
3
4
5
6
$ docker volume ls
DRIVER VOLUME NAME
local 0d506af3b9c55280acce2e034fb7ff2b6f19c9c23192e6de91ac406702236f8d
local 2f6589f1ec9c16dd1fcdc638aa2df316c3d1e5fa9c712651e8b61997ca26d0d1
local 3c8d4c4aa95221be36b5adc472549440e7330764ad3b8bef08f37d4d59f4d4ba
...

かなりの数があります。

使っていないものもあるのだろうなと思い、フィルタオプションでボリュームが参照されているかどうかを指定して(dangling=true)使っていないボリュームの一覧を表示してみます。(参照されていない時がtrue。ドキュメントはこちらです。danglingとは宙ぶらりんという意味のようです。)

1
2
3
4
5
6
$ docker volume ls -f dangling=true
DRIVER VOLUME NAME
local 0d506af3b9c55280acce2e034fb7ff2b6f19c9c23192e6de91ac406702236f8d
local 2f6589f1ec9c16dd1fcdc638aa2df316c3d1e5fa9c712651e8b61997ca26d0d1
local 3c8d4c4aa95221be36b5adc472549440e7330764ad3b8bef08f37d4d59f4d4ba
...

ほとんどが使われていないボリュームのようです。

では利用されていないボリュームを削除します。ボリュームを削除するにはdocker volume rmコマンドを利用します。VOLUME NAMEを一つずつ指定して削除することもできますが、大変なので一気に削除します。

1
2
3
4
5
$ docker volume ls -qf dangling=true | xargs docker volume rm
2f6589f1ec9c16dd1fcdc638aa2df316c3d1e5fa9c712651e8b61997ca26d0d1
3c8d4c4aa95221be36b5adc472549440e7330764ad3b8bef08f37d4d59f4d4ba
5cb87cee19c530d3dc8e903a93501333ebdb7b191a220a24c6eec4b8cc1151f7
...

削除されたボリューム名が表示されます。

これですっきりしました、残ったボリュームは数個しかありません。ではそれらのボリュームの詳細をみていきたいと思います。

ボリュームの詳細確認

ボリュームの詳細を確認するにはdocker volume inspectコマンドを利用します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ docker volume inspect web_bundle
[
{
"CreatedAt": "2020-07-16T13:09:21Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "web",
"com.docker.compose.version": "1.25.4",
"com.docker.compose.volume": "bundle"
},
"Mountpoint": "/var/lib/docker/volumes/web_bundle/_data",
"Name": "web_bundle",
"Options": null,
"Scope": "local"
}
]

マウントポイントが記載されています。中身をみてみます。

1
2
$ ls -l /var/lib/docker/volumes/web_bundle/_data
ls: /var/lib/docker/volumes/web_bundle/_data: No such file or directory

どういうことでしょうか…

Dockerホストにログイン

少しググってみると、Docker Desktop for MacはDocker Desktop HyperKit VMが動作していて、Mac上で仮想マシンが動いているということでした。ですとMacのファイルシステムにそのパスは存在せず、Mac上で動いている仮想マシンに存在するということになります。

その仮想マシン(Dockerホスト)にログインするにはどうするのか調べてみると、screenというコマンドでログインできるようです。screenについての詳細はman screenで確認しました。

screenコマンドでDockerホストに接続します。

1
$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

パッと見、接続できたかどうかわかりづらいですが、エンターキーを押すと、docker-desktop:~#とプロンプトが表示されます。切断するときはCtrl-a Ctrl-kです。
Ctrl-dを押すとおなじみのクジラが表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
docker-desktop:~# __  __

Welcome to LinuxKit

## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""__/ ===
{ / ===-
_____ O __/
__/
_________/

docker-desktop login: root (automatic login)

Welcome to LinuxKit!

NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
System services are namespaced; to access, use `ctr -n services.linuxkit ...`
login[72826]: root login on 'ttyS0'

ボリュームの確認

ではボリュームを確認します。

1
2
3
4
5
6
7
8
9
10
11
12
docker-desktop:~# ls -l /var/lib/docker/volumes/web_bundle/_data
total 84
drwxr-xr-x 2 root root 4096 Jul 16 13:09 bin
drwxr-xr-x 2 root root 4096 Apr 3 15:49 build_info
drwxr-xr-x 3 root root 4096 Apr 3 15:49 bundler
drwxr-xr-x 3 root root 20480 Jul 16 11:59 cache
-rw-r--r-- 1 root root 60 Jul 16 13:09 config
drwxr-xr-x 4 root root 4096 Jul 14 02:21 doc
drwxr-xr-x 3 root root 4096 Apr 3 15:50 extensions
drwxr-xr-x 264 root root 16384 Jul 16 11:59 gems
drwxr-xr-x 4 root root 4096 Jul 14 01:47 ruby
drwxr-xr-x 2 root root 20480 Jul 16 11:59 specifications

このボリュームはRailsアプリケーションで利用するgemのインストールディレクトリです。Dockerコンテナでbundle installを行うとこのボリュームのファイルが更新されます。

まとめ

  • dockerで利用しているボリュームはdocker volumeコマンドで確認ができる
  • Docker Desktop for Macは仮想マシンで動作している
  • MacからDockerホストに接続するにはscreenコマンドを利用する

RailsアプリケーションでGitHub Actionsを試す

前回のまとめ

前回は空のアプリケーションでGitHub Actionsを動作させてみました。今回はもう少し実践的にRailsアプリケーションを動作させてみようと思います。

Railsアプリケーションの準備

Railsアプリケーションはこちらで準備しました。

GitHub Actionsの作成

前回GitHub Actionsを作成したように、作成したRailsアプリケーションのリポジトリを選択した状態で、Actionsタブをクリックします。

RailsアプリケーションのGitHub Action template

Rails用はないようです。とりあえずSet up this workflowをクリックして雛形を作成します。

Railsアプリケーションのworkflow

workflowの設定

今回は、workflowでRailsのテストの実行まで行いたいと思います。

トリガー

1
2
3
4
5
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

トリガーは前回と同じように、masterブランチの更新と、masterブランチへのPullRequest作成(更新)時になっています。

ジョブ

1
2
3
jobs:
test:
runs-on: ubuntu-latest

testというジョブが予め作成されています。ランナーマシンはubuntu-latestです。

Rubyのインストール

前回のRailsアプリケーションの作成ではRubyの現時点での最新版を指定しました。が、workflowでは初期値2.6を指定しており、一致しておらず、Your Ruby version is 2.6.6, but your Gemfile specified 2.7.1というエラーが出ます。ですので、workflowのRubyバージョン指定を2.7.1に変更します。

1
2
3
4
5
6
7
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
with:
ruby-version: 2.7.1
- name: Install dependencies
run: bundle install

サービスコンテナの利用

前回、RailsアプリケーションのデータベースとしてMySQLを設定しました。MySQLをランナーマシン上で動かしてもよいのですが、GitHub Actionsではサービスコンテナというものが使えるので使ってみましょう。

サービスコンテナについてはドキュメントがしっかりしていたので、参考になりました。

ランナーマシンがDockerホストのように動作し、その上にコンテナを立ち上げるイメージです。ですので、ランナーマシン上でジョブを実行するときに、サービスコンテナと通信を行うにはlocalhostのポートをマッピングするだけで可能です。ドキュメントにも以下のように記載されています。

ジョブをランナーマシン上で直接実行する場合、サービスコンテナにはlocalhost:もしくは127.0.0.1:を使ってアクセスできます。 GitHubは、サービスコンテナからDockerホストへの通信を可能にするよう、コンテナネットワークを設定します。

なるほど!簡単ですね!

サービスコンテナの設定でハマる

まず、先ほどのジョブにサービスコンテナを設定します。

1
2
3
4
5
6
7
services:
mysql:
image: mysql:5.6
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root

ランナーマシンのローカルポート3306をコンテナの3306にマッピングします。環境変数でrootのパスワードも設定します。

次に、Railsのデータベース接続設定を行います。CI用のdatabase.ymlを作成します。

1
2
3
4
5
6
7
8
9
test:
adapter: mysql2
encoding: utf8
collation: utf8_general_ci
username: root
password: root
host: localhost
database: github_actions_for_rails_test
reconnect: false

これをdatabase.yml.ciとして保存し、ジョブ内でdatabase.ymlにリネームします。

1
2
3
4
5
6
7
- name: Setup Database
env:
RAILS_ENV: test
run: |
cp config/database.yml.ci config/database.yml
./bin/rails db:create
./bin/rails db:migrate

masterへのPullRequestを作成し、workflowの動作確認を行うと、以下のようなエラーが表示されました。

1
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

MySQLへの接続に失敗しているようです。ランナーマシンのlocalhost:3306をmysqlコンテナの3306にマッピングしているので問題なさそうです…

原因がわからないので、一度サービスコンテナを使わずにランナーマシンにインストールされているMySQLを起動してみます。

サービスコンテナの記述を削除し、Setup Databaseを以下のように書き換えます。

1
2
3
4
5
6
7
8
- name: Setup Database
env:
RAILS_ENV: test
run: |
sudo systemctl start mysql
cp config/database.yml.ci config/database.yml
./bin/rails db:create
./bin/rails db:migrate

この場合は接続可能でした。
しかし、やはりサービスコンテナを利用したいです。

ドキュメントにはlocalhostでも127.0.0.1でもよいと書かれていたので、127.0.0.1を接続先として設定し試してみます。すると、先ほどのConnection Errorは出ず、マイグレーションが行われました。

Railsアプリケーション特有の問題かどうかわかりませんが、localhostではなく127.0.0.1を接続先として指定することで解決しました。

最終版のconfig/database.yml.ciは以下のようになります。

1
2
3
4
5
6
7
8
9
test:
adapter: mysql2
encoding: utf8
collation: utf8_general_ci
username: root
password: root
host: 127.0.0.1
database: github_actions_for_rails_test
reconnect: false

workflowは以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby

name: Ruby

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
test:

runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.6
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root

steps:
- uses: actions/checkout@v2
- name: Set up Ruby
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
# change this to (see https://github.com/ruby/setup-ruby#versioning):
# uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
with:
ruby-version: 2.7.1

- name: Setup Database
env:
RAILS_ENV: test
run: |
cp config/database.yml.ci config/database.yml
./bin/rails db:create
./bin/rails db:migrate
- name: Run tests
run: ./bin/rails test

まとめ

GitHub ActionsでCIの設定を行ってみました。GitHub Actionsはとても評判の良いCI/CDツールです。コード管理しているプラットフォームで行えるという点がとても良いと思います。今後も積極的に使っていきたいと思います。

次回は今回のようなまっさらなRailsアプリケーションではなく、プロダクション環境で稼働中のRailsアプリケーションでGitHub Actionsを動作させてみたいと思います。

その次くらいにAWS ECSにデプロイする処理を書いてみたいと思います。

Railsアプリケーションの作成

動機

RailsアプリケーションでGitHub Actionsを試そうと思い、その準備のために空のRailsアプリケーションを作成する必要がありました。その時のメモです。

Dockerを利用したほうがよいのでは?

publicなDocker imageを利用して誰でも作成できるようにしたほうがよいと思います。

こちらのコンテナを落としてみたんですが、Rubyのバージョンが2.3.3p222でした…他を探すにしても数が多すぎてよくわからなかったので、今回はローカル(Mac)に作成します。

Rubyのインストール

ローカルにanyenvをインストールしていました。最新バージョンのRubyをインストールするためにupdateします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ anyenv update
Updating 'anyenv'...
Updating 'anyenv/anyenv-update'...
Updating 'ndenv'...
Updating 'ndenv/ndenv-yarn-install'...
Updating 'ndenv/node-build'...
Updating 'rbenv'...
| From https://github.com/rbenv/rbenv
| c2cfbd1..c879cb0 master -> origin/master
Updating 'rbenv/ruby-build'...
| From https://github.com/rbenv/ruby-build
| 637ddf3..69ccbf4 master -> origin/master
| * [new tag] v20200518 -> v20200518
| * [new tag] v20200519 -> v20200519
| * [new tag] v20200520 -> v20200520

anyenvのupdateについてはこちら

インストールできるRubyを確認します

1
2
3
4
5
6
7
8
9
10
11
12
$ rbenv install -l
2.5.8
2.6.6
2.7.1
jruby-9.2.12.0
maglev-1.0.0
mruby-2.1.1
rbx-5.0
truffleruby-20.1.0

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all' to show all local versions.

メッセージにあるようにstableの最新しか表示されないようになったようです。

最新の2.7.1をインストールします。

1
2
3
4
5
6
7
8
9
10
11
$ rbenv install 2.7.1
Downloading openssl-1.1.1g.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
Installing openssl-1.1.1g...
Installed openssl-1.1.1g to /Users/username/.anyenv/envs/rbenv/versions/2.7.1

Downloading ruby-2.7.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2
Installing ruby-2.7.1...
ruby-build: using readline from homebrew
Installed ruby-2.7.1 to /Users/username/.anyenv/envs/rbenv/versions/2.7.1

2.7.1を利用するようにします。

1
2
3
$ rbenv local 2.7.1
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]

Railsアプリケーションの作成

Gemfileの作成

bundler initします

1
2
$ bundler init
Writing new Gemfile to ~/github/github_actions_for_rails/Gemfile

Gemfileの更新

作成したGemfileを更新します。MySQLを利用する予定なのでmysql2を追加します。

1
2
gem 'rails'
gem 'mysql2'

bundle install

bundle installします

1
2
3
4
5
6
7
8
9
10
11
Installing mysql2 0.5.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

(中略)

linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

いつものようにエラーが出ます。毎回忘れるのですが、bundle configします。

1
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"

再度bundle installして完了です。

Railsアプリケーションの作成

rails newします。

1
$ bundle exec rails new . -d mysql

conflictするファイル(.gitignore, Gemfileなど)はoverwriteするようにします。不要なgemなどはスキップをするようにしたほうがよいと思いますが、今回はGitHub Actionsを試すためなので特に指定していません。GitHub ActionsのワークフローでMySQLと接続する処理を行おうと思うのでデータベースにmysqlを指定しています。

webpacker:installでメッセージが…

1
2
3
rails  webpacker:install
Webpacker requires Node.js >= 8.16.0 and you are using 8.9.4
Please upgrade Node.js https://nodejs.org/en/download/

ということで最新版にします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ndenv install v12.18.2
Downloading node-v12.18.2-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v12.18.2/node-v12.18.2-darwin-x64.tar.gz
Installing node-v12.18.2-darwin-x64...
Installed node-v12.18.2-darwin-x64 to /Users/username/.anyenv/envs/ndenv/versions/v12.18.2

Installing Yarn...
/Users/username/.anyenv/envs/ndenv/versions/v12.18.2/bin/yarn -> /Users/username/.anyenv/envs/ndenv/versions/v12.18.2/lib/node_modules/yarn/bin/yarn.js
/Users/username/.anyenv/envs/ndenv/versions/v12.18.2/bin/yarnpkg -> /Users/username/.anyenv/envs/ndenv/versions/v12.18.2/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.22.4
added 1 package in 0.82s
Installed Yarn 1.22.4
$ ndenv local v12.18.2
$ node -v
v12.18.2

再度webpacker:installを実行します。

1
2
3
4
5
6
7
8
$ rails webpacker:install
create config/webpacker.yml
Copying webpack core config
create config/webpack

(中略)

Webpacker successfully installed 🎉 🍰

最後に動作確認します

1
2
3
4
5
6
7
8
9
10
$ ./bin/rails s -b 0.0.0.0
=> Booting Puma
=> Rails 6.0.3.2 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.5 (ruby 2.7.1-p83), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

TOPページにアクセスするとデータベースがないというエラーが発生。config/database.ymlに書かれているデータベースを作成して無事TOPページを表示することができました。

まとめと次回

今回テスト用のRailsアプリケーションを作成しました。次回はこれを用いてGitHub Actionsでワークフローを作成したいと思います。

GitHub Actionsを試す

動機

GitHub Actionsという名前は知っていましたが、今まで使うことはありませんでした。今行っているプロジェクトでオンプレミス環境からパブリッククラウド(AWS)への移行を検討しています。

AWSではコンテナで環境を作成しようと思っており、ECSを利用する予定です。今日のDevelopers.IO2020のWebinarで、GitHub Actionsはすばらしいと説明されていたので使ってみようと思いました。

GitHubのCI/CDツール GitHub Actions

今までもCircleCIなどのツールは存在していました(わたしもCircleCIは使ったことがあります)。ソースコード管理はGitHubなので、GitHubと連携する必要がありました。しかしGitHub Actionsなら連携の設定をすることなくそのまま利用可能です。便利ですね。

試してみる

一度テスト用のリポジトリでGitHub Actionsを試してみます。

リポジトリの作成

適当にリポジトリを作成します。実際のリポジトリを想定してプライベートリポジトリを作成します。

GitHub Actionsの作成

GitHubのリポジトリを選択した状態で、上のActionsというタブをクリックします。すると以下のような表示になります。

GitHub Actions作成
今回はテストで作成するので、Set up this workflowをクリックします。

workflowの内容は、リポジトリ内のコードによって変わってきます。Dockerfileが保存されているリポジトリでActionsタブをクリックすると、docker-composeコマンドを実行するworkflowになりました。今回は空のリポジトリなので、echoするだけの単純なworkflowになったのだと思います。

workflowの保存

Set up this workflowをクリックすると、設定ファイルを編集する画面に遷移します。
workflowの編集

ファイル名を適当に変更します。workflow内はそのままで、右上のStart commitをクリックします。workflowのyamlは.github/workflows/ディレクトリの下に作成します。

workflowの動作確認

どういったトリガーでworkflowが実行されるかはyamlのonを確認します。今回のyamlは

1
2
3
4
5
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

となっており、masterブランチのpushと、pull_requestになります。つまり、

  • masterブランチを更新
  • masterブランチへのPull Requestを作成

で実行されると言うことになります。試しにmasterブランチへのPullRequestを作成すると以下のようになります。

PullRequestの作成

workflowが実行された結果が表示されています。workflowの結果を確認するにはActionsタブをクリックします。左のペインですべてのworkflow(All workflows)か、特定のworkflowを選択すると、選択したものの結果が表示されます。

まとめ

今回GitHub actionsの初めの1歩として簡単に触ってみました。比較的わかりやすくスムーズに進みました。

次回はもう少しプロダクションよりな感じにしたいと思います。Ruby(Rails)でのテストの実装や、データベースなどのコンテナの立ち上げ方を理解し、workflowを試したいと思います。

Dockerのlink機能 その2 アプリケーションサーバの設定

前回までのまとめ

前回Docker実践ガイドの第5章のlink機能を用いたアプリケーションサーバ用コンテナとDB用コンテナを起動するところまで行いました。

今回はアプリケーションサーバの設定を行い、linkしているコンテナが正しく動いているかを確認します。

アプリケーションサーバの設定

まずはじめにアプリケーションサーバのIPアドレスを確認します

1
2
$ docker container inspect mw0001 --format={{'.NetworkSettings.IPAddress'}}
172.17.0.4

docker container inspect コンテナ名とすることでコンテナ名に指定したコンテナの情報をJSON形式で取得することができます

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ docker container inspect mw0001
[
{
"Id": "a4d1693a7981100b015d75f958468069c7418e11dad13e042bf26f5454246581",
"Created": "2020-06-22T11:03:55.9929367Z",
"Path": "/sbin/init",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
...
(中略)
...
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "d6a62553445bbae6f040e8972635b12995ca2b23f0328ab8736f7a2b71d541bb",
"EndpointID": "73fae0f570728362bbe4c504ef79e98df191c9352375e9d1805b73ef56613ad2",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
}
]

--formatオプションで取得する値を指定することができます。

ブラウザからのアクセス

アプリケーションサーバのIPアドレスがわかったので、ブラウザからアクセスしてみます。
URLはhttp://172.17.0.4/wiki/です。

しかし応答が返ってきません。-pオプションを利用していないのにIPアドレスがわかったところで通信できるのでしょうか?書籍ではLinuxをホストOSとして動作させているので可能なのかもしれません。わたしの手元の環境はDocker Desktopだからかもしれません。

一旦-pオプションを利用してアクセスできることを確認します。

1
2
3
$ docker stop mw0001
$ docker rm mw0001
$ docker container run -itd --tmpfs /tmp --tmpfs /run --mount type=bind,src=/sys/fs/cgroup,dst=/sys/fs/cgroup,readonly --stop-signal SIGRTMIN+3 -v /var/www/html --name mw0001 -h mw0001 --link mariadb0001:db0001 -p 8080:80 centos:mw0001 /sbin/init

今回は-p 8080:80を設定しています。よって、URLはhttp://localhost:8080/wiki/です。すると、正しく表示されました。

が、しかし、データベースの接続設定のところで、mariadb0001のIPアドレス、ユーザー名、パスワードを入力すると

1
2
Cannot access the database: MySQL server has gone away (172.17.0.3)。
以下のホスト名、ユーザー名、パスワードを確認してから再度試してください。

というエラーが出てしまった。パスワードは間違ってなさそうです。

ちょっと原因がわからないので、一旦linkオプションを用いたコンテナ間通信はここまでにしようと思います。

次回はコンテナ間通信を行うもう一つの方法、bridgeネットワークを用いたコンテナ間通信を試したいと思います。

Dockerのlink機能

前回までのまとめ

前回Docker実践ガイドの第5章のlinkオプションの説明を読んで環境構築をしようとしたところ、Dockerfileの記述方法をミスってしまい、環境構築まで到達できませんでした。

なんとかDB用コンテナが起動できたところまで進んだので、アプリケーションサーバ用コンテナの準備をしたいと思います。

DB用コンテナの確認

起動の確認

DB用コンテナが起動していることを確認します

1
2
3
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
65b5af36d7ac centos:mariadb0001 "/mariadb.sh" 4 days ago Up 4 days 3306/tcp mariadb0001

起動オプションの確認

コンテナ起動オプションを確認します。

1
$ docker run -d -e DBNAME=testdb -e MARIADBUSER=root -e MARIADBPASSWORD=mysqlPassword -v /var/lib/mysql:/var/lib/mysql:rw --name mariadb0001 centos:mariadb0001

マウントしているディレクトリの確認

-vオプションで指定しているディレクトリを確認します。

1
2
3
4
5
6
$ ls /var/lib/mysql
65b5af36d7ac.pid ib_logfile1 mysql.sock
aria_log.00000001 ibdata1 performance_schema
aria_log_control ibtmp1 test
ib_buffer_pool multi-master.info
ib_logfile0 mysql

データファイルやログファイルなどが保存されています。コンテナが/var/lib/mysqlとして利用しているのがわかります。

アプリケーションサーバ用コンテナのビルド

DB用コンテナが起動していることがわかったので、次にアプリケーションサーバ用コンテナを準備します。
書籍に倣って、Mediawikiをインストールします。

Dockerfileの作成

Dockerfileは以下のようになっています。

1
2
3
4
5
6
7
8
9
FROM centos:7.5.1804
RUN yum remove -y php* && \
yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm && \
yum install -y --enablerepo=remi,remi-php72 php php-mysqlnd php-mbstring php-xml httpd openssh-clients && \
curl -O https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.0.tar.gz && \
tar xzvf /mediawiki-1.31.0.tar.gz -C /var/www/html/

WORKDIR /var/www/html
RUN ln -sf ./mediawiki-1.31.0 wiki && systemctl enable httpd

WORKDIRについてしっかり理解していなかったので、ドキュメントを参照しました。

ざっくりの理解だと、WORKDIRを宣言した後はそのディレクトリでRUN, CMD, ENTRYPOINT, COPY, ADDが実行されるということです。その名の通りworking directoryを指定しています。WORKDIRに関するベストプラクティスも記載されていました。コマンドを実行するたびにどこかのディレクトリに移動するのではなくWORKDIRからのパスで処理を実行しましょうということです。

イメージのビルド

Dockerfileの作成が終わったのでイメージをビルドします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ docker image build -f Dockerfile -t centos:mw0001 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos:7.5.1804
---> cf49811e3cdb
Step 2/4 : RUN yum remove -y php* && yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm && yum install -y --enablerepo=remi,remi-php72 php php-mysqlnd php-mbstring php-xml httpd openssh-clients && curl -O https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.0.tar.gz && tar xzvf /mediawiki-1.31.0.tar.gz -C /var/www/html/
---> Running in c808fb96ff1d

(中略)

Removing intermediate container c808fb96ff1d
---> 90815ed52b36
Step 3/4 : WORKDIR /var/www/html
---> Running in 5b4fdf6b5b97
Removing intermediate container 5b4fdf6b5b97
---> e535a272bbf0
Step 4/4 : RUN ln -sf ./mediawiki-1.31.0 wiki && systemctl enable httpd
---> Running in 9733db996f6f
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service, pointing to /usr/lib/systemd/system/httpd.service.
Removing intermediate container 9733db996f6f
---> 67b7fb3ff7d6
Successfully built 67b7fb3ff7d6
Successfully tagged centos:mw0001

無事イメージのビルドができました。

tarコマンドにvオプションを指定してしまったため、Mediawikiのファイル一覧が出力されてログが流れてしまった。vオプションはなしにした方がよさそうです。

アプリケーションサーバ用コンテナの起動

アプリケーションサーバ用コンテナを起動します。

1
$ docker container run -itd --tmpfs /tmp --tmpfs /run --mount type=bind,src=/sys/fs/cgroup,dst=/sys/fs/cgroup,readonly --stop-signal SIGRTMIN+3 -v /var/www/html --name mw0001 -h mw0001 --link mariadb0001:db0001 centos:mw0001 /sbin/init

オプションがたくさん指定されていますので、一つずつ見ていきます。

  • -i
    標準入力を利用します
  • -t
    ttyを利用します。こちらに書かれているように、シェルなどのインタラクティブなプロセスではttyを割り当てるために-itオプションを指定します。今回の場合は-dも指定しているため、-itdとなっています。
  • –tmpfs
    tmpfsを割り当てます。
  • –mount
    srcはホストOS上のディレクトリを指定するはずですが、今利用しているMacには/sys/fs/cgroupはありませんでした。後ほど詳しく調べます。
  • –stop-signal
    こちらの内容だと、コンテナ停止のためのシグナルを指定するオプションのようです。
  • -h
    コンテナのホスト名を指定します。
  • –link
    前回にも記載しましたが、コンテナを指定し、コロンの後のエイリアス名でをprefixにして環境変数にアクセスできるようになります。

アプリケーションサーバ用コンテナとDB用コンテナの連携確認

アプリケーションサーバ用コンテナの起動確認

起動していることを確認します

1
2
3
4
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4d1693a7981 centos:mw0001 "/sbin/init" 3 hours ago Up 3 hours mw0001
65b5af36d7ac centos:mariadb0001 "/mariadb.sh" 4 days ago Up 4 days 3306/tcp mariadb0001

環境変数の確認

環境変数を確認します

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ docker container exec -it mw0001 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=mw0001
TERM=xterm
DB0001_PORT=tcp://172.17.0.3:3306
DB0001_PORT_3306_TCP=tcp://172.17.0.3:3306
DB0001_PORT_3306_TCP_ADDR=172.17.0.3
DB0001_PORT_3306_TCP_PORT=3306
DB0001_PORT_3306_TCP_PROTO=tcp
DB0001_NAME=/mw0001/db0001
DB0001_ENV_MARIADBUSER=root
DB0001_ENV_MARIADBPASSWORD=mysqlPassword
DB0001_ENV_DBNAME=testdb
HOME=/root

エイリアス名の大文字をprefixとした環境変数が取得できることがわかります。これらの環境変数を使ってDB用コンテナにアクセスすることができます。

hostsファイルの確認

次にhostsファイルを確認します

1
2
3
4
5
6
7
8
9
$ docker container exec -it mw0001 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 db0001 65b5af36d7ac mariadb0001
172.17.0.4 mw0001

DB用コンテナがhostsファイルに登録されているのがわかります。

まとめ

link機能を使うと

  • 他のコンテナの環境変数にアクセスできるようになる
  • 他のコンテナが/etc/hostsファイルに記載される

link機能は単体のホストOS上で複数のコンテナが連携する場合に有用です。Dockerにおける複数コンテナの連携の基本となっているのでしっかり理解したいです。

TypeScriptことはじめ

TypeScriptを学びたい

わたしはサーバーサイドエンジニアとして長らく働いてきました。その間何度かJavaScriptの習得にチャレンジしましたが、今のところ手にした感はありません…

そんな折、TypeScriptの話をよく聞くようになりました。TypeScriptは強い型付けが可能なJavaScriptという感じでしょうか。強い型付けが好きなわたしとしては、JavaScriptの習得にはこの言語しかないと思わせるものがあります。

また、この前のDevelopers.IO 2020でもAWS CDKでTypeScriptを利用した例が紹介されていました。今後もAltJSとして利用されることが多くなると予想されます。TypeScriptを学び始めるのにはちょうどよい時期なのでしょう。

今回はWEB+DB PRESS Vol.117の特集で取り上げられていた内容をもとに学んでいこうと思います。

TypeScript環境構築

Node.jsのインストール