20210221のdockerに関する記事は12件です。

docker --init (Tini) が PID 1 問題を解決している様子を調べてみた

はじめに

docker --init は PID 1 として動作させることを想定してないプロセスを適切に処理するために、軽量の init を PID 1 で実行する Docker 1.13 で追加されたオプションです。内部的には Tini が使用されています。Tini の大きな役目は次の2つです。

  • デフォルトのシグナルハンドラを機能させる
  • ゾンビプロセスを刈り取る(reaping)

この記事では Tini を使用しない場合にどのような問題が発生し、Tini を使用することでそれらが解決する様子を確認します。

準備

まず動作確認を行うためのファイルを準備します。作業用のディレクトリを作り以下のファイルを作成します。

Dockerfile
FROM debian
RUN apt-get update && apt-get install -y procps tini
# ENTRYPOINT ["/usr/bin/tini", "-vvv", "--"]
COPY ./script.sh ./script.sh
CMD [ "sleep", "30" ]

--init では Tini のオプションを指定できないようなのでパッケージでインストールします。最初に Tini を使わない状態での問題を確認するため ENTRYPOINT はコメント状態にしています。

script.sh
#!/bin/bash

i=0
echo "parent pid: $BASHPID"
(
  echo "child pid: $BASHPID"
  while [ $i -lt 100000 ]; do i=$((i+1)); done # 長いsleepの代わり
  exit 0
) &

while [ $i -lt 1000 ]; do i=$((i+1)); done # 短いsleepの代わり
exit 0

sleep を使用すると新たにプロセスが作成されて混乱のもとになるので while を使用しています。

Tini を使わない場合の問題を確認

以下のコマンドを実行し Docker コンテナを起動します。(Docker コンテナは 30 秒後に停止します。)

docker build -t tini-test . && docker run --name tini-test --rm -it tini-test

デフォルトのシグナルハンドラが機能しないことの確認

確認用の Docker コンテナは sleep コマンドを PID 1 として起動しています。sleep(明示的にシグナルをハンドルしてないプロセス)は INT シグナルや TERM シグナルを受け取ったときにデフォルトの処理としてプロセス停止を行いますが PID が 1 の場合はプロセス停止を行いません。(PID 1 はプロセスのルートにあたる存在なので通常は終了する必要はないし終了されたら困るからでしょう。)

Docker コンテナを起動したら CTRL-C を押してみてください。コンテナを停止することができません。これは PID 1 のプロセスである sleep が INT シグナルに反応していないためです。

$ docker build -t tini-test . && docker run --name tini-test --rm -it tini-test
Sending build context to Docker daemon  8.192kB
Step 1/5 : FROM debian
 ---> 6d6b00c22231
Step 2/5 : RUN apt-get update && apt-get install -y procps tini busybox bash ksh mksh posh yash zsh ruby
 ---> Using cache
 ---> 9e8992a067c9
Step 3/5 : COPY ./script.sh ./script.sh
 ---> Using cache
 ---> 6b89b83578b8
Step 4/5 : COPY ./sleep.sh ./sleep.sh
 ---> Using cache
 ---> 1e51be59d454
Step 5/5 : CMD [ "sleep", "30" ]
 ---> Using cache
 ---> 29964877f137
Successfully built 29964877f137
Successfully tagged tini-test:latest
^C^C^C^C

Docker コンテナを起動したら以下のように docker stop を実行してみてください。停止するのに 10 秒ほど時間がかかります。これは docker stop で TERM シグナルを sleep に送信したものの反応しないために 10 秒後にタイムアウトして代わりに KILL シグナルでコンテナが強制的に停止しているためです。(※ docker stop で送信するシグナルは Dockerfile の STOPSIGNAL または docker run --stop-signal で変更することができます。)

$ docker stop tini-test
# (10秒後)
tini-test

ゾンビプロセスが刈り取られないことの確認

Docker コンテナを起動したら、別の端末から以下のように docker exec でコンテナに入り ./script.sh スクリプトを実行してみてください。バックグラウンドプロセスとして起動したサブシェル( (...) & 部分)は、プロセスが終了したにも関わらず誰も wait していない(= PID 1 で起動している sleep が回収していない)ためゾンビプロセス(STAT: Z, <defunct>)として残っていることがわかります。

このゾンビプロセスは親プロセス (PPID) が 1 に変更されてる点にも注目してください。PID 15 の[script.sh] は 親プロセスである PID 14 から起動しているので、本来の PPID は 14 ですが親プロセスが先に停止し、孤児プロセスとなった PID 15 の PPID は 1 に振り返られています(リペアレンティング)。そのため新たに親プロセスとなった PID 1 が PID 15 を wait してプロセスを刈り取らなければいけません。これが PID 1 が行わなければいけない特殊な処理です。しかしsleep コマンドや多くのプログラムは(そもそもPID 1 として動かすことを想定してないので)そのような処理を行いません。

$ docker exec -it tini-test /bin/bash
root@3561d6cf51de:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     7     7     7 pts/1       13 Ss       0   0:00 /bin/bash
    7    13    13     7 pts/1       13 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        1 Ss+      0   0:00 sleep 30

root@3561d6cf51de:/# ./script.sh
parent pid: 14
child pid: 15

root@3561d6cf51de:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     7     7     7 pts/1       16 Ss       0   0:00 /bin/bash
    7    16    16     7 pts/1       16 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        1 Ss+      0   0:00 sleep 30
    1    15    15     7 pts/1       16 Z        0   0:00 [script.sh] <defunct>

Tini を使って問題が解決することを確認

では次に Tini を使用することで、これらの問題が解決することを確認します。Dockerfile の ENTRYPOINT のコメントを外して有効化してください。(もしくは docker run--init オプションを指定することでも解決します。)

デフォルトのシグナルハンドラが機能することの確認

確認手順は同じですので詳細は省きます。CTRL-C を押すとすぐにコンテナが停止し docker stop を実行するとすぐにコンテナが停止することが確認できるはずです。

ゾンビプロセスが刈り取られていることの確認

Docker コンテナを起動したら、別の端末から以下のように実行してみてください。先程と違ってゾンビプロセスは残りません。

$ docker exec -it tini-test /bin/bash
root@8734c3957af5:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     9     9     9 pts/1       15 Ss       0   0:00 /bin/bash
    9    15    15     9 pts/1       15 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        8 Ss       0   0:00 /usr/bin/tini -vvv -- sleep 30
    1     8     8     1 pts/0        8 S+       0   0:00 sleep 30

root@8734c3957af5:/# ./script.sh
parent pid: 16
child pid: 17

root@8734c3957af5:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     9     9     9 pts/1       18 Ss       0   0:00 /bin/bash
    9    18    18     9 pts/1       18 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        8 Ss       0   0:00 /usr/bin/tini -vvv -- sleep 30
    1     8     8     1 pts/0        8 S+       0   0:00 sleep 30
root@8734c3957af5:/# exit
exit

Tini を使用した場合は /usr/bin/tini が PID 1 として起動しており sleep は子プロセスとして実行されています。そして script.sh を実行すると先程の例でゾンビプロセスとなっていた [script.sh] は PID 1 である Tini によって刈り取られます。

このとき、Docker コンテナを起動した端末では次のような Tini のログが出力されているはずです。(※ 起動するプロセスが増えているため PID 番号は変わっています。)

$ docker build -t tini-test . && docker run --name tini-test --rm -it tini-test
[INFO  tini (1)] Spawned child process 'sleep' with pid '8'
[TRACE tini (1)] No child to reap
[TRACE tini (1)] No child to reap
[DEBUG tini (1)] Received SIGCHLD
[DEBUG tini (1)] Reaped child with pid: '17'
[TRACE tini (1)] No child to reap
[TRACE tini (1)] No child to reap
[DEBUG tini (1)] Received SIGCHLD
[DEBUG tini (1)] Reaped child with pid: '8'
[INFO  tini (1)] Main child exited normally (with status '0')
[TRACE tini (1)] No child to wait
[TRACE tini (1)] Exiting: child has exited

Tini は一定間隔(0.5 秒?)で刈り取るべきプロセスがないかを確認し、対象となるプロセスがあれば刈り取ります。(-vvv オプションを指定している場合は上記の Reaped child with pid: '17' のようなログを出力を出力します。)

補足

さて Tini の動作確認としてはここまでなのですが、検証中に気づいた点について補足します。

シェルもゾンビプロセスを刈り取ります

Dockerfile を次のように書き換えて Docker コンテナを起動してください。(Tini は使用しません)

Dockerfile
FROM debian
RUN apt-get update && apt-get install -y procps tini
# ENTRYPOINT ["/usr/bin/tini", "-vvv", "--"]
COPY ./script.sh ./script.sh
COPY ./sleep.sh ./sleep.sh
CMD [ "sh", "./sleep.sh" ]
sleep.sh
#!/bin/sh
sleep 30

そしてゾンビプロセスが残るかどうかを確認してみましょう。結果は以下の通り残りません。

$ docker exec -it tini-test /bin/bash
root@69f6fc6d0e4c:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     8     8     8 pts/1       15 Ss       0   0:00 /bin/bash
    8    15    15     8 pts/1       15 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        1 Ss+      0   0:00 sh ./sleep.sh
    1     7     1     1 pts/0        1 S+       0   0:00 sleep 30

root@69f6fc6d0e4c:/# ./script.sh
parent pid: 16
child pid: 17

root@69f6fc6d0e4c:/# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     8     8     8 pts/1       18 Ss       0   0:00 /bin/bash
    8    18    18     8 pts/1       18 R+       0   0:00  \_ ps axjf
    0     1     1     1 pts/0        1 Ss+      0   0:00 sh ./sleep.sh
    1     7     1     1 pts/0        1 S+       0   0:00 sleep 30

これは Tini と同じように PID 1 で動作しているシェル(sh)がゾンビプロセスの刈り取りを行っているからです。シェルがゾンビプロセスの刈り取りを行うのは POSIX シェル の要件ではない(間違っていたら教えて下さい)と思いますが、少なくとも dash、bash、ksh、posh、yash、zsh、busybox ash はゾンビプロセスの刈り取りを行っているようです。そして mksh はゾンビプロセスの刈り取りを行いませんでした。

この事実から PID 1 のプロセスとして dash や bash を使っている場合はゾンビプロセスの刈り取りについては Tini に頼る必要はありません。しかしデフォルトのシグナルハンドラが機能しない問題が残っており、シェルスクリプトは明示的に処理を書かない限り TERM シグナルに反応しません。(CTRL-C には反応します。)trap コマンドで明示的に TERM シグナルのシグナルハンドラを書くことで対応できますが docker stop は PID 1 のプロセスにしか TERM シグナルを送信しないので、子プロセスがいる場合はプロセスグループに対して kill する等の対応が必要になることがあります。場合によっては先に子プロセスを終了してから自分自身を終了するなど面倒な処理となる場合もあるでしょう。

Tini を使うべきかどうか

プログラムが正しく INT や TERM シグナルに対応しており終了処理をきちんと行っていれば Tini を使う必要はありません。それが理想だと思いますがプログラムの修正が困難な場合もあります。例えば少し複雑なシェルスクリプトを TERM シグナルに正しく対応するのは意外と大変です。Tini は本来存在しているはず init の代替に過ぎないので Tini を使用したとしてもプログラムに悪い影響を与えることはなくデメリットは殆ど無いでしょう。Docker イメージのサイズが多少増える程度です。なので可能ならプログラムを修正し、それが難しいなら躊躇せず Tini を使うという流れで良いと思います。

Docker compose の FAQ 「Why do my services take 10 seconds to recreate or stop?」([日本語]サービスの再作成や停止に10秒かかるのはどうして?)でも同様のことが述べられています。

To fix this problem, try the following:

  • Make sure you’re using the exec form of CMD and ENTRYPOINT in your Dockerfile.
  • If you are able, modify the application that you’re running to add an explicit signal handler for SIGTERM.
  • Set the stop_signal to a signal which the application knows how to handle:
  • If you can’t modify the application, wrap the application in a lightweight init system (like s6) or a signal proxy (like dumb-init or tini). Either of these wrappers takes care of handling SIGTERM properly.

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

複数の形態素解析器と辞書を入れた Docker コンテナを作って Python で使う

はじめに

いくつかの形態素解析器(と辞書)を比較する機会があったので、まとめて動かせる環境を Docker コンテナにして Python で使えるようにしました。

やったこと

今回使ったのは、MeCabspaCyGiNZA の3つ、辞書は以下の通り MeCab 用の6つと spaCy 用の3つです。

Docker コンテナを作る

これらをまとめて動かせる環境を Docker コンテナにできたら便利、というわけで、ネット上の情報1を参考にしながら、Ubuntu 20.04 の Docker イメージ をベースに必要なものをインストールする形で Dockerfile を書きました。

Dockerfile
FROM ubuntu:20.04

# basic libs
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y sudo vim wget curl git file unzip xz-utils
RUN apt-get install -y build-essential zlib1g-dev gcc make

# locale
RUN apt-get install -y locales
RUN locale-gen ja_JP.UTF-8

# python
RUN apt-get install -y python3 python3-pip
ENV PYTHONIOENCODING "utf-8"
WORKDIR /usr/local/bin/
RUN ln -s `which python3` python
RUN ln -s `which pip3` pip

# mecab
RUN apt-get install -y mecab libmecab-dev
RUN apt-get install -y mecab-ipadic-utf8 unidic-mecab

# mecab-ipadic-NEologd
WORKDIR /usr/local/src
RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
RUN cd mecab-ipadic-neologd && ./bin/install-mecab-ipadic-neologd -n -y

# mecab-unidic-NEologd
WORKDIR /usr/local/src
RUN git clone --depth 1 https://github.com/neologd/mecab-unidic-neologd.git
RUN cd mecab-unidic-neologd && ./bin/install-mecab-unidic-neologd -n -y

# mecab-naist-jdic
WORKDIR /usr/local/src
RUN wget https://ja.osdn.net/projects/naist-jdic/downloads/53500/mecab-naist-jdic-0.6.3b-20111013.tar.gz
RUN tar xzvf mecab-naist-jdic-0.6.3b-20111013.tar.gz
RUN cd mecab-naist-jdic-0.6.3b-20111013 && \
    ./configure --with-charset=utf8 --with-mecab-config=/usr/bin/mecab-config && \
    make && make install

# mecabrc
WORKDIR /etc
RUN sed -i -e 's/dicdir = .*/dicdir = \/usr\/lib\/x86_64-linux-gnu\/mecab\/dic\/mecab-ipadic-neologd/g' mecabrc
RUN cp mecabrc /usr/local/etc/mecabrc

# python libs
RUN pip install --upgrade pip
RUN pip install mecab-python3

# python libs (spaCy & GiNZA)
RUN pip install spacy ginza
RUN python -m spacy download ja_core_news_sm
RUN python -m spacy download ja_core_news_md
RUN python -m spacy download ja_core_news_lg

辞書のサイズが大きく(特に unidic 系)、イメージを作るのに結構な時間がかかります2

Python で使う

立ち上げたコンテナに入れば、以下のような Python コードが動きます。

test.py
# MeCab (辞書6パターン)
import MeCab
m_juman  = MeCab.Tagger('-d /var/lib/mecab/dic/juman-utf8')
m_ipadic = MeCab.Tagger('-d /var/lib/mecab/dic/ipadic-utf8')
m_unidic = MeCab.Tagger('-d /var/lib/mecab/dic/unidic')
m_naist_jdic = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/naist-jdic')
m_ipadic_neologd = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
m_unidic_neologd = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-unidic-neologd')

# spaCy & GiNZA
import spacy
s_sm = spacy.load('ja_core_news_sm')
s_md = spacy.load('ja_core_news_md')
s_lg = spacy.load('ja_core_news_lg')
s_ginza = spacy.load('ja_ginza')

def parse_mecab(m, text):
    arr = []
    node = m.parseToNode(text)
    while node:
        if len(node.surface) > 0:
            arr.append(node.surface)
        node = node.next
    return ' '.join(arr)

def parse_spacy(s, text):
    arr = []
    for token in s(text):
        arr.append(token.orth_)
    return ' '.join(arr)

def parse(text):
    print('mecab-juman         : {}'.format(parse_mecab(m_juman, text)))
    print('mecab-ipadic        : {}'.format(parse_mecab(m_ipadic, text)))
    print('mecab-unidic        : {}'.format(parse_mecab(m_unidic, text)))
    print('mecab-naist-jdic    : {}'.format(parse_mecab(m_naist_jdic, text)))
    print('mecab-ipadic-NEologd: {}'.format(parse_mecab(m_ipadic_neologd, text)))
    print('mecab-unidic-NEologd: {}'.format(parse_mecab(m_unidic_neologd, text)))
    print('spaCy(news_sm)      : {}'.format(parse_spacy(s_sm, text)))
    print('spaCy(news_md)      : {}'.format(parse_spacy(s_md, text)))
    print('spaCy(news_lg)      : {}'.format(parse_spacy(s_lg, text)))
    print('GiNZA               : {}'.format(parse_spacy(s_ginza, text)))

parse('複数の形態素解析エンジンを切り替えて使えるコンテナが便利です')

出力は以下の通り。

mecab-juman         : 複数 の 形態 素 解析 エンジン を 切り替えて 使える コンテナ が 便利です
mecab-ipadic        : 複数 の 形態素 解析 エンジン を 切り替え て 使える コンテナ が 便利 です
mecab-unidic        : 複数 の 形態 素 解析 エンジン を 切り替え て 使える コンテナ が 便利 です
mecab-naist-jdic    : 複数 の 形態素 解析 エンジン を 切り替え て 使える コンテナ が 便利 です
mecab-ipadic-NEologd: 複数 の 形態素解析 エンジン を 切り替え て 使える コンテナ が 便利 です
mecab-unidic-NEologd: 複数 の 形態素解析 エンジン を 切り替え て 使える コンテナ が 便利 です
spaCy(news_sm)      : 複数 の 形態 素 解析 エンジン を 切り 替え て 使える コンテナ が 便利 です
spaCy(news_md)      : 複数 の 形態 素 解析 エンジン を 切り 替え て 使える コンテナ が 便利 です
spaCy(news_lg)      : 複数 の 形態 素 解析 エンジン を 切り 替え て 使える コンテナ が 便利 です
GiNZA               : 複数 の 形態素 解析 エンジン を 切り替え て 使える コンテナ が 便利 です

おわりに

また形態素解析したくなったときには、即コンテナ化して使い始められます。


  1. dockerで動く mecab + python3 の環境を作る - Qiita」や「dockerでubuntu16+python3.6+mecab(neolog-ipadic)を構築する - メモ帳」などを参考にさせていただきました。ありがとうございます。 

  2. ネットワークなどの環境次第ですが、イメージの生成に数十分以上かかる場合もあると思います。また、生成されるイメージのサイズは 17GB ほどになります。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2/21~docker~

why~なぜdocker~

従来の仮想化技術はOS丸ごとイントールしていたが

how

コンテナ型で仮想化することで

what

素早く動作させることができる


dockerはコンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンソースソフトウェアあるいはオープンプラットフォームである。
OSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。
Dockerはコンテナ仮想化を核としたアプリケーションのためのオープンプラットフォームである。DockerエンジンによりDockerコンテナとして配備、実行できる。
Linux、Windows、Mac全て対応したDockerエンジンは開発・テスト・本番・デバッグなど様々な状況で用意かつ高速なアプリケーション配備、実行を可能にする。


メリット
一台のサーバー上に複数のOSを走らせる仮想技術は従来から存在していたがこれらはOSを丸ごとインストール必要があり、アプリケーションに必要のないサービスやファイルまで伴っていた。
アプリケーションとは関係のないライブラリやデータは仮想環境内で共有することが望ましく、これを実現するのがコンテナ型の仮想化である。
Dockerはアプリケーションとライブラリを同一のコンテナ内に固めてしまうので一度固めたコンテナは軽量であり移動が容易であり、比較的どの環境でも素早くアプリケーションを動作させることが可能である。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

deviceを入れているときに、rails db:migrateできなくて詰まった話

今回起こったことを話すと、railsにいれていたgemであるdeviceを使ってログイン機能を実装しようと思ったら、rails db:migrateできなくなってしまいました

解決策

1つ目

docker-compose run --rm web rails d devise User

を実行してから、

docker-compose run web rails d devise:views

を打ち込んで実行して、

docker-compose run --rm web rails g controller Pages index show

を実行、ただし、このときにcontrollerを作成していなければ、この限りではない
この工程をスキップした場合は、これは行わなくていい

docker-compose run --rm web rails d devise:uninstall

を実行して、deviceをアンイストールした後に、gemfileの、

gem 'device'

を削除

そして、

完了

ってなるはずだったんですけど、ここで致命的なミスをやらかしてました。
それは何かって言うと、最初の工程である、

docker-compose run --rm web rails d devise User

これをしないで、完了したぜイェイとか思ってたんですけどこれが間違いでしたね、、、

これをしないで、deviceを再インストールしたら、

db/migrate/20210221123320_add_devise_to_users.rb
# frozen_string_literal: true

class AddDeviseToUsers < ActiveRecord::Migration[6.0]
  def self.up
    change_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

#省略

五行目の

def self.up
    change_table :users do |t|

change_tableになってるのでこれは間違いですね。

def self.up
    create_table :users do |t|

になおして

docker-compose run web rails db:migrate

をしたら無事migrationできました。

ふぅ

参考記事

https://teratail.com/questions/214948

https://qiita.com/cigalecigales/items/16ce0a9a7e79b9c3974e

ご指摘などありましたらコメント欄によろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初学者がDocker composeでPostgreSQLとpdAdmin4の環境を構築する

概要

初学者がDocker composeを使って、PostgreSQLとpgAdmin4の環境を構築しました。とりあえず作成した環境なので、ボリュームのマウントなどは行っていません。

※Dockerのインストール等は既に完了しています。

docker-compose.ymlを作成

docker-compose.yml

version: '3'

services:
  db:
    image: postgres
    container_name: pg-docker
    ports:
      -  '5432:5432'
    environment:
        - 'POSTGRES_USER=postgres'
        - 'POSTGRES_PASSWORD=postgres'
        - 'POSTGRES_DB=pg_db'

  pgadmin4:
    image: dpage/pgadmin4
    container_name: pgadmin4
    ports:
      - '80:80'
    environment:
      - 'PGADMIN_DEFAULT_EMAIL=xxx@yyy.com'
      - 'PGADMIN_DEFAULT_PASSWORD=pga4_pw'

docker-compose.ymlを実行

デタッチモード: -dでdocker-composeを実行します。docker-compose upでbuildとrunが同時にできるので便利です。

$ docker-compose.yml up -d

コンテナの状態を確認

StateがUpになっていることを確認します。

$ docker-compose ps
  Name                Command              State              Ports
------------------------------------------------------------------------------
postgres   docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
pgadmin4   /entrypoint.sh                  Up      443/tcp, 0.0.0.0:80->80/tcp

自分のIPアドレスを確認

色々な方法があると思いますが、とりあえず私はシステム環境設定からネットワークを開き、IPアドレスを確認しました。

ブラウザからpdAdmin4にアクセス

ブラウザを開き、IPアドレス:80にアクセスします(80番ポートは、docker-compose.ymlで設定)。タイプミスなどが無ければ、pdAdmin4のトップページが表示されると思います。

スクリーンショット 2021-02-21 21.14.20.png

ログインの情報はdocker-compose.ymlのpgadmin4のenvironmentに記述した内容を入力します。

サーバー(postgre)に接続

ログインが完了したら、右側のメニューからServersを右クリックし、Createにマウスポインターを合わせ、Server...を選択します。
スクリーンショット 2021-02-21 21.36.01.png

Create-Serverウィンドウが表示されるので、GeneralタブのNameにpd-dockerと入力します。一応、docker-compose.ymlで記述したcontainer-nameと合わせていますが、必要ないかもしれません。
スクリーンショット 2021-02-21 21.38.43.png

Connectionタブをクリックし、HostはPCのIPアドレス、Portは5432を入力します。Maintenance databaseとUsernameとPasswordは、docker-compose.ymlのenvironmentで設定した値を入力します。
スクリーンショット 2021-02-21 21.43.41.png

Saveボタンをクリックし、問題がなければ接続が完了します。
スクリーンショット 2021-02-21 21.46.07.png

注意点

冒頭にも書きましたが、ボリュームをマウントしていないのでコンテナがUpでなくなると(消すと?)、データベースも消えてしまうので運用する際は注意が必要です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Buildkitを「docker-compose build」で使う方法

皆さんこんにちは!

まだまだ毎日投稿しているのですがネタ尽きないっす。

なんならもっと書きたいぐらい。

色々記事書いてるので、ぜひ時間のある方はほかの記事もご覧ください!

さて、今回はDockerの記事です。

Dockerで作ったイメージをAWSのECRにプッシュしようとしたら以下のような警告が表示されました。

[+] Building 0.1s (2/2) FINISHED
 => [internal] load build definition from Dockerfile                                     0.0s
 => => transferring dockerfile: 2B                                                       0.0s
 => CANCELED [internal] load .dockerignore                                               0.0s
 => => transferring context:                                                             0.0s
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount119702719/Dockerfile: no such file or directory

明らかにビルドできてない気がする。

実際にECSでこのイメージを使ってもエラーが表示される。

ってことで半日くらいかかった末にようやく答えが出た。

僕自身WindowsでDockerの開発を行っているのですが、Windowsだとこの現象が起きるらしいです。

悲し。。。

なので、docker-composeでビルドしちゃえばいいんじゃねって思って半日近くの時間を費やしようやく答えを見つけた!

どうやらdocker-composeはデフォルトではBuildkitに対応していないらしい。

なので、docker-composeでBuildkitを有効にする魔法のコマンドを打つ!!!

Mac

COMPOSE_DOCKER_CLI_BUILD=1 docker-compose build

Windows

set "COMPOSE_DOCKER_CLI_BUILD=1" & set "DOCKER_BUILDKIT=1" & docker-compose build

COMPOSE_DOCKER_CLI_BUILD=1という環境変数を追加してあげることでBuildkitを使用してコンテナをビルドできるそうです。

Dockerは習い始めて約2週間、AWSは約1週間くらいなのですが、なれるまでに時間がかかりそうですね。

以上、「[Docker]Buildkitを「docker-compose build」で使う方法」でした!

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい!!

Thank you for reading

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Horizonインストール時のエラー require ext-pcntl *....への対処法

Laravel8 + PHP 7.4.7のdocker環境でHorizonをインストールしようとしたら、以下のようなエラーが出ました。

$ composer require laravel/horizon
Using version ^5.7 for laravel/horizon
./composer.json has been updated
Running composer update laravel/horizon
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/horizon[v5.7.0, ..., 5.x-dev] require ext-pcntl * -> it is missing from your system. Install or enable PHP's pcntl extension.
    - Root composer.json requires laravel/horizon ^5.7 -> satisfiable by laravel/horizon[v5.7.0, 5.x-dev].

PHPの拡張pcntl(Process Controll)がないらしいです。

解決策 Dockerfileに拡張機能インストール処理を追記

私の場合、dockerで環境構築していたので、
webサーバー(PHPの処理を書くコンテナ)のDockerfileにpcntlをインストールしました。

Before

FROM php:7.4-apache

# pcntl is requirement of horizon
RUN apt-get update \
    && apt-get install -y zip unzip vim libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql

After
docker-php-ext-installコマンドの後ろにpcntlを追加

docker-php-ext-installコマンドがない人は、PHPコンテナ内をfindで探し、あるなら下記のように追記、なければ別のPHP拡張インストーラーが入っているはずなので、そのインストーラーの処理に追記しましょう。

FROM php:7.4-apache

# pcntl is requirement of horizon
RUN apt-get update \
    && apt-get install -y zip unzip vim libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql pcntl

後はコンテナを立て直してcomposer require laravel/horizonすればOK!

$ composer require laravel/horizon

Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/horizon (v5.7.0): Downloading (100%)         
laravel/horizon suggests installing ext-redis (Required to use the Redis PHP driver.)
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating optimized autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

代替案 CLIで今すぐインストール

代わりというのもアレですが、既にコンテナが立っている状態であれば、Dockerfileを編集せずにインストールすることも可能です。

// コンテナ内で実行
docker-php-ext-install pcntl


// もしパスが通ってなかったら、コンテナ内でphpなどのパスにないか確認・移動(大抵同じ箇所にある)
which php
# -> /usr/local/bin/php

cd /usr/local/bin
docker-php-ext-install pcntl

以上で完了です!

こんな対応もあるらしい

私自身は「解決策」の方法を取り、導入・動作まで確認できましたが、調べる過程では別の方法も提案されていました。

Laracasts laravel horizon install error
composer require laravel/horizon --ignore-platform-reqsコマンドでインストールする。
オプション(--ignore-platform-reqs)で環境(PHP側の拡張がないこと)を無視してインストールできるらしい。
=> packagistでHorizonのrequiresを見る限り、pcntlがないとヤバそうなので、不採用。

Laracasts Install pcntl ext
PHPをダウンロードして、コマンドを打って設定できるみたい。
既にdockerで環境を作った場合、ここに示されているようなファイルが見つからなかったので見送り。
MAMP環境での導入方法が書かれているので、同じ環境の人は試してもいいかも

資料

Docker上でPHP拡張モジュール『GD』を有効化する
https://laracasts.com/discuss/channels/laravel/install-pcntl-ext
https://github.com/mlocati/docker-php-extension-installer

まとめ

今回の対応は、資料①の記事を多いに参考にさせてもらいました(入れる拡張が違うだけで、やってることは変わらない)。
普段は追加機能の開発でcomposerを使ってライブラリを入れるくらいで、
PHPの拡張を入れる必要に迫られることは少なかった(ぶっちゃけ海外でもこういう人が多いっぽい)ので勉強になりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerとはなにか

本記事の概要

この記事はDocker初学者の私が、Dockerの概要についてまとめた記事です。
学習に当たっては以下の書籍を参考にしました。

Docker/Kubernetes 実践コンテナ開発入門

コンテナ技術の概念から簡易的なWebアプリの構築等、実践的な内容まで含まれております。
また、DockerやKubernetesの設計や運用における勘所についても記載があり、勉強になる書籍でした。

本記事で分かること

  • コンテナ技術の概要
  • Dockerとはなにか

コンテナ技術の概要

Dockerの説明に入る前に、そもそもコンテナとは何かについて説明します。

コンテナとは仮想化技術のうちの1つです。
コンテナ以外の仮想化技術には、ホストOS型(Virtual Box等)、ハイパーバイザー型(ESXi等)があります。

図で表すとこうです。

コンテナ型

Container.jpg

ホストOS型

Host.jpg

ハイパーバイザー型

Hypervisor.jpg

コンテナ型では仮想化ソフトウェアなしにOSのリソースを隔離し仮想OSにします。この仮想OSをコンテナと呼びます。
コンテナを作り出すためのオーバヘッドは、他の仮想化ソフトウェアと比較して少ないため、高速に起動・終了ができ、必要なマシンリソースも少なくて済むことが特徴です。

コンテナ技術の歴史

コンテナ技術自体はDockerが台頭する前から存在しています。Dockerが登場する前はLXC(Linux Container)が有名でした。
DockerにはLXCと比較して以下の特徴があります。

  • ホストに左右されない実行環境(Docker Enginによる実行環境の標準化)
  • DSL(Dockerfile)によるコンテナの構成やアプリケーションの配置定義
  • イメージのバージョン管理
  • 差分ビルドが可能
  • Dockerレジストリ(イメージ保管サーバのようなもの)

DockerではDockerfileによりコンテナ情報をコードで管理できます。そのため環境の再現性を保ちやすいことが特徴です。また、Docker以前はアプリケーションをホストOSもしくはゲストOS上へデプロイしていたため、デプロイ先の実行環境(OS)への依存度が高かったです。
しかしDockerでは、実行環境を同梱してデプロイするため依存問題を解消しています。

Dockerとはなにか

アプリケーションを開発、移動、実行するためのプラットフォームです。
アプリケーションをインフラから分離し、アプリケーションを扱うようにインフラを扱えます。
具体的にはDockerfileと呼ばれるファイルで、コンテナの環境設定をコードで記述、管理します。

Docker Enginとは

Docker Enginとは、ざっくりいうとコンテナを管理するための仕組みです。
もう少し詳しく言うと、3つのコンポーネントで構成されるクライアント / サーバー型アプリケーションであり、dockerクライアント、dockerデーモン、REST APIで構成されます。

DockerEngin.jpg
dockerクライアントにて、コンテナの構築などを実行するためにはdockerデーモンと通信します。その通信をREST APIを通じて行います。

Dockerが動く仕組み

dockerクライアントとdockerデーモンが通信することで動くわけなのですが、もう少し詳しく見てみます。
コンテナを構築するためにはイメージと呼ばれるテンプレートが必要です。例えば、Ubuntuの上にApacheをインストールしてWebサーバーを構築するとします。その際必要なUbuntuとApacheのイメージをレジストリと呼ばれるイメージの保管サーバからダウンロードし、コンテナを構築します。

Docker_Architecture.jpg

パブリックなレジストリとしてはDocker Hubがあり、多種多様なイメージが存在します。
プライベート環境にレジストリが必要な場合は、Docker Registryを使うといいでしょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【未経験PF / Rails / React / AWS / Docker / CircleCI】独学+メンターでここまで出来た!Web知識ゼロからモダンな技術アプリ開発までに利用した5つのサービス

0. はじめに

こんにちは!辻野(@ddpmtcpbr)と申します。

当記事は、「Webエンジニアへのキャリアチェンジを目指している開発未経験者が、モダンな技術を備えたアプリを開発するまでの学習過程」についてまとめたものです。

現在筆者は非IT系企業の社員として働いており、Web開発エンジニアとしての実務経験はありません

そんな筆者がWebエンジニアとしてのキャリアチェンジをするためのポートフォリオとして、本アプリを開発しました。

学習開始から現時点までにおいて、プログラミングスクール等には通っておらず、学習はほぼ全て独学&一部メンターサービス利用の布陣で進めてきました。

独学中心でアプリ開発に挑戦したい、ポートフォリオを作成してWebエンジニアへのキャリアチェンジを進めていきたい、と考えている方々にとって、参考になればと思います。

最初に、今回私が開発したアプリの概要を紹介します。

アプリ名: 積読解消アプリ 「Yomukatsu!」

image.png

あなたの積読解消をサポートします」をスローガンに掲げたSPA風Webアプリです(”風”の詳細は後述)。

読書メンタルマップという手法を用いて、ユーザーの書籍完読に向けたモチベーション維持をサポートします。

Web URL: https://yomukatsu.com/

【3分動画】Yomukatsu 字幕解説

アプリの使い方を3分でまとめています。

使用技術

  • Backend: Rails ( API mode / Rspec / rubocop) + Nginx ( upstream puma-socket )
  • Frontend: React ( create-react-app / Redux / Material-UI / eslint&prettier)
  • Infra: AWS ( ECS Fargate/ ECR / RDS / ALB / Route53 ), Netlify, Docker&docker-compose, CircleCI

各項目の詳細は後述しています。

インフラ構成

yomukatsu_cloud_architecture.png

モダンな技術を採用したWeb系企業が提供している、中・大規模なアプリケーションを想定したインフラ構成にしています(そのため、個人開発アプリとしてみるとちょっと仰々しいかもです(;’∀’))

詳細は後述しています。

機能一覧

ユーザー利用機能

  • Twitterアカウントを利用したユーザー登録(OAuthによるSNS認証)
  • ゲストログイン機能
  • Google Books APIを用いた書籍検索機能
  • Google Books、Amazon、楽天ブックスへのリンクボタン配置
  • Twitterシェア機能
    • ハッシュタグ「#yomukatsu」付きTweet
    • Twitter card 表示
  • Twitter card用にリサイズした書籍画像をAWS S3へ保存・管理
  • Redux による state 管理を活用したローディング画面
  • Slack Incomming Webhookを利用したお問い合わせ機能
  • Route53 による独自ドメイン + SSL化

非ユーザー利用機能

  • Netlify の Pre-reidering 機能活用による動的なOGP情報の保持( Twitter card 表示用)
  • Docker による開発環境の完全コンテナ化
  • CircleCI による自動 CI/CD パイプライン構築
    • CI: Rspec, rubocop, eslint&prettier
    • CD: AWS ECR
  • その他セキュリティ対策(XXS, CSPF等)

まず触ってみてもらうのが一番良いかと思います!今回はフロントエンドに React を採用しているため、メニューモーダルの開閉や通知バー表示など、アニメーション的な表現も実装できているのが伝わるかと思います。

ゲストユーザー機能もありますので、気軽に利用してみてほしいです!レスポンシブにも対応しています。(推奨ブラウザはChrome、Safariになります)

アプリURL: https://yomukatsu.com/

※現在α版としてのリリースのため、配信内容が予告無く変更される可能性がございます

あわせて、 Githubも公開していますので、よかったら参考にしてください。

Github URL: https://github.com/ddpmntcpbr/rails_react_docker

この記事について

当記事は3章構成になっております。

まず、「1.自己紹介」で、簡単に自己紹介をさせていただきます。

次に、「2.開発アプリ解説」で、今回の開発アプリ開発について、コンセプト決定の流れから、実装機能/技術スタックについて詳しく紹介します。「転職用PF作りたいけど、どんなアプリを作ればいいか分からない」という方にとって、参考になることがあれば幸いです。

最後に、「3. 学習ロードマップ」で、Web知識ゼロだった筆者が、当アプリの開発にまでに利用した5つの教材およびサービスについて、時系列に沿って紹介したいと思います。特に独学では、「まず何を学べば良いのか」「どんな教材を選べば良いのか」というところから自身で考える必要があります。そういった方々にとって参考になり得る情報と思います。

1. 自己紹介

1.1 筆者スペック

  • 20代後半 男
  • 工学部機械系 修士卒 → 非IT系 日系製造業 技術開発職(現職)
  • 大学から現職において、データ分析ツールとしてプログラミングを経験(matlab / python)
  • Webエンジニアへのキャリアチェンジを目指し、社会人になってから独学を開始

大学入学以降、授業や研究データの分析ツールとしてプログラミングに触れる機会はありました。もともと自動化や効率化に興味があったことからプログラミングにだんだんとのめり込み、研究室ではプログラミングに多く触れられそうな研究テーマ(データ分析系)を選びました。

したがって、「プログラミング自体が完全に未経験」というわけではありませんでした。しかし、いわゆる”Web系”の知識は社会人以降の独学を開始するまではゼロ、という状態で、最初は HTML すら知らないところからのスタートでした( ̄▽ ̄;)。そのため当記事では「Web知識ゼロ」という表現をしています。

キャリアチェンジ志望の理由は、ざっくりと言えば、

1. もっとプログラミングがしたい
2. モノづくりで誰かの役に立ちたい
3. 非効率・非生産的な仕事を無くしたい

ここについては当記事の趣旨ではないので、詳細については省略します。

2. 開発アプリ解説

2.1 コンセプト方針

転職用PFアプリのコンセプトを決めるにあたり、満たすべき用件としては、下記3点を考えました。

(a) 実際の企業が採用しているようなモダンな技術を盛り込む
(b) 具体的な解決課題を明確にする
(c) サービスの利用が個人で完結する

(a) 実際の企業が採用しているようなモダンな技術を採用する

未経験からエンジニア転職において、高品質なポートフォリオは必須と考えました。

「モダンな技術をポートフォリオに組み込むことで、技術力の高さをアピールする」というのが基本的な考え方になるとは思いますが、個人的な解釈としては、ポートフォリオで証明すべきは「技術力」ではなく「自走力」だと考えています。

ぶっちゃけた話、実際の現場を経験したエンジニアと比べれば、未経験者間での能力差というものはどんぐりの背比べのようなものだと思います。多くの企業が「実務経験1年以上」をエンジニアの採用項目にあげていることからも、実務経験というのはそれだけ重い価値があり、未経験者とは大きな隔たりがあるのだと思います。

したがって、ポートフォリオの技術レベルの高さそのものはあまり重要ではなく、そこに到達するまでの過程の方が大事であり、「自走力=必要な情報は自らキャッチアップして吸収する能力」があることを示す方が、企業人事側としては採用しやすいのではないか?と考えました。

「スクールの制作アプリをそのまま提出する未経験者が足切りされてしまう」という話は多く聞きますが、これはそのアプリの技術力が低いからではなく、そのアプリから当人の「自走力」が主張できないから、だと私は考えています。私が独学ベースにこだわったのは、単純にお金の問題だけではなく、独学ベースでアプリを開発することができれば、自然とそれが「自走力の証明」につながると考えたからです。

今回のアプリにおいては、「独学:メンター=8:2」 くらいの割合で、上記技術を採用できるラインまで行くことができています。「メンター利用は独学からは外れるのでは?」という指摘もあるかもしれませんが、

  • プログラミングでは、個人ではどうにもならないようなエラーに遭遇してしまうことが多々ある
  • 実際に企業に入ってからは、先輩エンジニアの方々に分からないことを質問しながら業務を進めることになるため、「質問力」も重要な能力である
  • 完全独学オンリーだと、誤った癖が身についてしまっているリスクが高くなる

といった観点から、独学者が適宜メンターサービスを利用することは、かえって採用人事側にとって安心感を与える材料になるのでは、と考えたので、自信を持って「メンターサービスを使いました」と主張しています。

※ 具体的なモダンな技術リスト

  • Rails API + JSフレームワーク(React.js)の構成
  • Dockerで実行環境を完全コンテナ化
  • Herokuではなく、AWS でアプリをデプロイ(ECS Fargate & ECR)
  • Circle CIによるCI/CDパイプラインの構築

(b) 具体的な解決課題を明確にする

さて、前章とは一見真逆のことを言いますが、アプリ開発において、モダンな技術を採用することそのものには本来何の価値もない、と考えています。

なぜなら、アプリの目的はあくまでも「ユーザーにとって価値を提供できるか」であり、技術はそれを実現するための手段でしかないはずだからです。(保守・運用面でのメリットも考えられますが、保守・運用の最終目的もユーザーへの価値提供であることから、この点も包含した解釈になります)

これは、技術というものを下に見ているというわけでは決してありません。むしろ「新しい技術をどんどん使ってみたい!」という技術に対する好奇心、探究心は人一倍強い自負があります。現職はIT系ではありませんが、技術開発職という立場で業務に取り組んでおり、知的好奇心を満たせるという意味では、今の仕事に面白みを感じています。

しかしながら、かつては行き過ぎた技術先行思想によって「手段の目的化」が発生し、「最新技術を駆使した誰にとっても役に立たない技術」を開発してしまったという苦い過去の経験があったりもします。結果として「やっぱり技術は人の役に立ってなんぼ」というのが、約3年間技術職として働いてきて培った、技術者としての小さな矜持だったりします(この辺の話は直接お会いした方にはお話できるかと思います)

転職用PFであれば、技術ありきな考え方になることはある程度は仕方がないことでしょう。しかし「せっかく作るのであれば、誰かにとって役に立ち得るものを目指そう」くらいのことは転職用PF作成においても考えていいんじゃないかな?と思いました。あるいは、もう少し目線を下げて「自分が欲しいものを作ろう」という程度でも十分でしょう。大事なのは、まず課題があり、それを解決する手段として技術があるという順番だと思いました。

もちろん今回の開発アプリは転職用PFが趣旨である以上、中には「技術力を証明したいから」という理由で選定した技術もあり、全てに対して課題が明確だったわけではありません。また、初心者の個人開発アプリがいきなりバズることは現実的には厳しいとは思います。しかし、そこを目指す姿勢があるかというのは、エンジニアとして本格的にキャリアを進めていく上では、長期的には大きな差異になると考えています。

また、

  • 課題が明確な方が採用した技術や実装した機能の根拠も明確にできるため、開発の方針を立てやすい
  • 自身がユーザー目線に立てることで、改善点を見つけやすい
  • 純粋にモチベーションを維持しやすい

といった点でもメリットもあると感じましたので、この方針は間違っていなかったと思います。

(c) サービスの利用が個人で完結する

「せっかく作るのであれば、誰かにとって役に立ち得るものを目指そう」を、もう一歩深く考えた方針です。

例えば Rails を対象として考えたとき、一般的な転職用PFとしては、TwitterライクなSNS系アプリや、メルカリライクなEC系アプリが多いかと思います。

理由は、ユーザー認証、CRUD操作、DB間のリレーションなど、基本的なサーバーサイド技術を一通り抑えられるものであるから、だと思います。「Railsの一般的な知識を持っていることを証明する」手段と考えれば、妥当な方針でしょう。

しかしながら、未経験者が転職用に開発した上記アプリが実際にユーザーに継続して使われるということは、まず無いでしょう。SNS系アプリは「ユーザー数が多ければ多いほどサービスとして質が高まる」性質があるため、アプリとして軌道に載せること自体が非常に難しいです。EC系アプリは BtoC であれば出品企業がいないとサービスが成り立たない、CtoCであればより SNS として要素が強まる & いよいよメルカリで十分、という壁があります。

これらアプリの難しさは、ユーザーどうしがつながることを前提としている点にあります。裏を返せば「個人で完結するアプリであれば、活路はある」とも言えると考え、この方針でコンセプトを詰めていくことにしました。

2.2 コンセプト内容

上記3点を念頭に置きながら、自分自身の生活の中で"課題"を探し、最終的にたどり着いたものが「読書メンタルマップ術の電子化」というコンセプトでした。

そもそも皆様は、読書メンタルマップ術というものをご存知でしょうか?

読書メンタルマップ術とは、ハーバード大学の先生が提唱している積読解消術です。読破したい書籍に対して、

1. 完読したい本について、それを読む“理由”や“目的”を3つ、紙に書きだす
2. 飽きてきたら、それを見返す

を繰り返すことで、完読までモチベーションを維持するというシンプルな読書手法です。

積読というものは、だいたい「最初は読む気があったけど、次第に読む気がなくなってしまった」書籍です。この「最初の読む気」を事前に明文化・保存しておくことで、いつでも最初の頃に新鮮な気持ちを取り戻せるようにしておこう、というイメージになります。

自分自身、実際に活用している技術ではあるのですが、少し困ったことがあります。それは、電子書籍との相性が悪いことです。

通常であれば紙とペンを用いるものですが、例えば出先でスマホやタブレットで電子書籍を読んでいるような状況では、必ずしもこれらの道具があるとは限りません。特に私は、外に出る時はあまりものを多く持ちたく無い性分なので、外ではスマホと財布くらいしか持っていないことが多いです。

仮に持っていたとしても、例えば電車の中で紙とペンを出して色々と書き始めるのは、少し億劫だったりします。

これを全部ペーパーレスで完結できるようなアプリがあったら便利だな」と思ったのが、このコンセプトを思いついたきっかけになっています。

もちろん、これだけであればスマホのメモ帳だけでもできてしまうものですが、このアプリには、

  • Google Books APIを活用した書籍検索・保存機能
  • メンタルマップ作成のヒント機能
  • Google Books, Amazon, 楽天ブックスへのリンクボタン配置(特に書籍レビューはメンタルマップ作成の大きなヒントになる)
  • Twitterでの読書仲間への気軽なシェア機能

といった機能が備わっており、より読書メンタルマップ術を使用しやすい環境を整えています。

先ほどの「2. 具体的な解決課題を明確にする」に照らし合わせて考えると、このアプリの解決課題は、ユーザーの積読を解消すること、もっと言えば、読書メンタルマップ術をペーパーレスで実行できるすることで電子書籍で読書するユーザーにとっても扱いやすくすること、になります。

また、「3. サービスの利用が個人で完結する」も満たしています。当アプリには、ユーザー同士がつながる機能は一切実装されていません

代わりとして、Twitterとの連携にはかなり重きを置いて実装機能を決めました。具体的には、

  • Twitterアカウントを利用したユーザー登録
  • ワンタップでハッシュタグ付きツイート
  • 充実した Twitter カード表示

を機能として実装しています。原則的には個人でサービスが完結しつつも、ユーザーどうしの繋がりはTwitter内の既存のネットワークに乗っかる、ことを狙ったコンセプトになっています。

2.3 技術スタック

再度、インフラ構成を載せます。

yomukatsu_cloud_architecture.png

この内容について、ひとつひとつ解説します。

Back-end

Rails API + Nginx の組み合わせにしています。

サーバーサイドフレームワークとしては他にも Laravel, Django, Node.js などもあります。恐らく大体のことは、どれを選んでも実装・実現できる、と思うのですが、その中で今回 Rails を選んだ理由は、

  1. 採用している企業数が多い
  2. 日本語の教材が豊富なため学習のハードルが低い
  3. 国内コミュニティが発達しているため、インターネット上での日本語ドキュメントが豊富

最初の学習言語として Rails を選択する初学者の方は多くいるかと思います。その一方で、「Railsはオワコン」という説が各所で言われていることについて、不安に感じる初学者の方もいると思います。

この点に関して、あくまで個人的な見解を述べますと、初学者であった自分が、少なくとも最初に学ぶ言語/FW として Rails は間違いではなかった、と考えています。

正直、初学者である私には、「なぜ Rails がオワコンであるのか」について技術ベースで語ることはできません。しかし、

  • 現時点で Rails を採用している企業の絶対数は多く存在すること
  • 日本国内において、Rails に替わるサーバーサイドのデファクトスタンダードな技術が、まだ定まっていないこと

は事実と言ってよいかと思います。

もしかしたら、長期的に見れば日本国内でも Rails を採用する企業が減っていく流れにはあるのかもしれません。しかし、微分値と絶対値はセットで捉えないと判断を誤ることになります。初心者が目指すべきは「今すぐに仕事を得られる技術を身に着けること」であり「将来必要になってくる技術」ではない、自分が今学ぶべきはやはり Rails である、と判断をしました。

また、オワコンというのは裏を返せば、技術的に枯れていて、初心者にとっては学びやすい言語/FWである、とも言えます。

特に日本国内での(過去含めた)使用者が多いため、日本語のドキュメントが多く存在します。事実、Rails開発で遭遇するエラーは、Google検索すれば何かしらの日本語記事がヒットします。

最先端の技術は過去の技術の欠点を補う要素を持って生まれてきているのは事実ですが、検索しても欲しい情報が見つからなかったり、あったとしても英語ドキュメントだけだったりします。私自身は、このアプリの開発を通じてWebフレームワークに基本的な概念が身についてきているため英語でも大丈夫になってきましたが、ベースラインすら乏しい状態の初学者がいきなり英語のドキュメントを読み解いていくのは、二重にしんどいです。

以上が、私が最初の言語/FWとして Rails を選んだ根拠になります。

主要gem
  • devise_token_auth: APIモードでの devise。トークン認証を簡単に実装
  • twitter_omniauth:Twitter認証を簡単に実装
  • active_model_serializer: Rails APIからのレスポンスJSONを制御
  • imageMagic: 画像のリサイズを実行。特に、Twitter card用に書籍画像をリサイズする際に使用
  • aws-fog/carrierwave: リサイズした書籍画像を AWS S3 に保存
  • rspec: デファクトスタンダードになっているRubyテスト用フレームワーク
  • rubocop: Rubyの静的コード解析

TwitterアカウントでのOAuth認証は、過去の実装例が少なく、非常に苦労したところでもありました。しかし、「Twitterとの連携を重視」という今回のコンセプト上では絶対に欲しい機能と考え、頑張って実装しました。

AWS S3については元々採用予定はなかった(Google Books APIの画像リンクをそのまま引っ張ってくる予定だった)のですが、Twitter card で書籍画像を表示させる時にどうしても画像サイズを適切に制御する必要が出てきたので、imageMagic と合わせて Rails で画像リサイズ & S3保存、を実装することにしました。

Front-end

今回フロントエンドとしては、JSフレームワークであるReact.jsを採用しました(細かいこと言えば React はフレームワークではなくライブラリですが、ここではフレームワークとして扱います)。モダンな技術採用を謳う以上、Rails + jQuery/bootstrap の構成では心許ないと考えました。

JSフレームワークとしては、国内企業での採用状況から考えるに、React.jsVue.jsか、の二択になると思います。その中でもReact.jsを選んだ理由は、

  1. 自分が調べた範囲では、バックエンドに Rails を採用している企業群のうち、フロントに React を採用している企業の割合が高かった
  2. Vue.js よりも規約が厳格であり、初学者の自分であっても自然と可読性の高いコードを書くことができそう
  3. たまたま、React を効率的に学べる良い教材を見つけた

特に最後については、第3章で後述しています。

アプリ開発を通じて React.js が割と気に入ってきたので良い選択だったとは思いますが、この点に関してはどちらを選んでも間違いではなかったかな、とは思います。

主要ライブラリ等
  • create-react-app: Facebookが提供するオープンソースのReact開発パッケージ
  • Redux: Stateの一元管理するフレームワーク。Redux関連ファイルは、reducksパターン則って管理
  • Redux-thunk: Redux state の非同期処理を制御
  • react-helmet: 動的なmetaタグの挿入によるOGP情報の保持(Twitter card用)
  • react-share: Twitter含めたSNSシェア用ボタンを簡単に配置
  • Material-UI : Google が提供する UI コンポーネントライブラリ。簡単におしゃれな UI コンポーネントをアプリ内に配置できる
  • eslint & prettier: javascriptに対する静的コード解析。eslint は create-react-appに標準搭載されているものをベースに少しプラグインを追加 & prettier はイチから導入

今回はユーザーの利用シーンを考えると、Web上でもネイティブアプリのようにサクサク動く、JSリッチなアプリケーションにしたいと考えました。この点からも、jQuery+bootstrap ではなく React.js を採用してよかったと思います。

React の実装には、特にMaterial-UIが強力で、開閉モーダルや通知バー表示などのアニメーション演出や、ページ全体のレスポンシブ対応などがかなり簡単に実装できました。このライブラリを使えたというだけでも、React を採用した価値があったと思えるほどでした。

Infra

Docker/docker-compose

開発環境は、全てDockerコンテナ内で完結させています。docker-compose.ymlのサービス構成としては、

  • db: MySQL
  • api: Rails
  • web: Nginx
  • front: Node.js (React)

としています。

後述しますが、AWS ECS(Fargate)へのコンテナデプロイを利用することで、開発環境と本番環境の差異を小さくすることができています。

AWS(Amazon Web Service)

バックエンド( Rails + Nginx )のデプロイに使用。Railsチュートリアルなどではアプリの本番環境へのデプロイにはHerokuを用いることが一般的ですが「モダンな技術を採用したい」という観点から、AWSに挑戦しました。

稼働させるまでめちゃくちゃ苦労しました。ここを完全独学で完結させるのは相当しんどいと思います。第3章で触れていますが、AWSの学習については、メンターさんをかなり頼らせてもらいました。

※ 利用サービス

  • ECS (Fargate): コンテナ向けサーバーレスコンピューティングエンジン。この中に Rails と Nginx の Docker イメージを入れて稼働させる
  • ECR: Rails と Nginx の Docker イメージを保存しておくリポジトリ
  • RDS (MySQL): AWS が用意しているスケーラブルなデータベースエンジン
  • ALB: 負荷分散を担うロードバランシングサービス
  • Route53: サイトの独自ドメイン化に使用
  • ACM: サイトの https 化に使用
  • S3: 静的ホスティングサービス。書籍画像も保存・管理に使用
Netlify

フロントエンド(create-react-app)のホスティングで利用。

最初はバックエンドに合わせてフロントも AWS ( Amplify Console ) でホスティングしていたのですが、create-react-appはSPAとしてのアプリ開発となることから、metaタグ無いにOGP情報を保持できない = Twitterでページをシェアした時のカード表示を動的に制御できない、という問題が出てきました。

おそらくは AWS でも解決する手段はあると思うのですが、今回は Netlify の Pre-rendering機能を使うことで解決することにしました。この機能を使うことで、 create-react-app であっても、サーバー側で javascript をレンダリングしてからブラウザが解釈できるようになります ( あと単純に、無料で利用できるのもメリット )

この問題にあたってから、最近ホットな React フレームワークの Next.js の有り難みが自然と分かるようになってきた( Next.js は SPA/SSG/SSRを選択可能 )のですが、今回はすでに開発を始めていたこともあり、create-react-app + Netlify の構成で最後まで開発しました。

CircleCI

国内ではデファクトスタンダードとされている、Saas型のCI/CDサービスです。今回CircleCIで自動化した処理は、

  • Rspec
  • rubocop
  • eslint&prettier
  • AWS ECR への Image push
  • AWS ECS のタスク&サービスの更新

Netlifyにはもともと自動デプロイ機能がついていることから、CircleCIを導入することで、Github上の master ブランチに merge しただけで、本番環境への再デプロイが完了する、という状態に持っていくことができました。

一度ありがたみが分かると、もう手放せないですね( ´ ▽ ` )

3. 学習ロードマップ

さて、いよいよ本題です。ここまでで開発したアプリについて解説をしてきましたが、ここからは、このアプリ開発に至るまでの学習過程をたどっていきます。

第1章でもお伝えした通り、筆者はプログラミング経験自体はあっても、いわゆる「Web系」の知識はゼロからのスタートでした。繰り返しますが、HTMLすら知らなかった状態から、独学ベースで上記技術スタックをアプリに盛り込めるレベルまで到達することができました

独学ベースでの学習になると、「どの学習教材を選ぶべきか」というところから自分で考える必要があります。いろいろと紆余曲折ありましたが「これは役に立った!」と思うものを厳選し、時系列に沿ってお伝えします。

※下記サービスのWebリンクや、ロゴ画像、ホームページのスクリーンショットについては、事前に各運営者様に使用許可をいただいております。改めまして運営者皆様、利用快諾していただきありがとうございました。

3.1 Progate

image.png

皆大好きProgate。今からエンジニアを目指す方は、全員ここから入門して間違い無いでしょう。

URL: https://prog-8.com/

自分は手当たり次第に色々な講座をやってみていましたが、

  • HTML&CSS
  • Javascript(ES6)
  • jQuery
  • Ruby
  • Ruby on Rails

次いで

  • Command line
  • Git
  • SQL

辺りを押さえておけば十分だったかと思います。

各講座の序盤のレッスンは無料会員でも受けることができますが、本気でエンジニアを目指すのであれば、有料会員限定のコースも含めて取り組んでいきましょう。

これだけでもそれなりにボリュームはありますが、挫折しにくいよう学習ステップがかなり細かく設定されているので、初心者にとっても易しいつくりになっています。

ただ、Rails講座だけはさすがに難易度が高かったです。。。これは、Progateさんの講座の作り云々ではなく、Webフレームワークという概念が初学者にとって「始めまして」になるので、多少仕方がない部分ではあると思います。

1周目で全体像の把握、2週目以降で詳細理解に努める、というスタンスでよいかと思います。

3.2 Ruby on Railsチュートリアル

image.png

皆大好き(?) Rails チュートリアル。

URL: https://railstutorial.jp/

色々賛否ある教材ですが、無料かつ、ここまで体系的に「RailsのWebアプリ開発」を学べる教材は他にないと思います。

本教材の謳っているところでもありますが、「単にRuby, Railsの学習に終始せず、Webアプリ開発の全体像を俯瞰する」ものですので、本教材での知識は、他言語・他フレームワークで開発をする場合でも大いに活きると思います。

確かに、当教材に対する否定的な意見はいくつか見受けられ、

  • テストフレームワークとして、国内企業でデファクトスタンダードになっているRspecではなく、Railsに標準搭載されているminitestを使用している
  • 採用技術が古くなってきてしまっている

という点がよく指摘されています。

ただ、前者については、株式会社YassLab代表のコチラのYoutube動画の動画でも説明がある通り、「かつて(第2版まで)は Rspec を Rails チュートリアルでも採用していたが、Rspec 自体の学習コストが高いこともあり、それによる脱落者を多く出していた」という背景を受けてのものになります。

また後者については、例えば現在の Rails企業の多くは、Rails単体のアプリケーション(フロントはjQery/bootstrap)ではなく、APIとしてRailsを利用し、フロントはJSフレームワーク(Vue.jsやReact.js)を使うのが一般的になってきています。しかし、Rails初学者が、いきなりAPI開発から始めるのは、理解の階段を飛ばしすぎている、というのも事実でしょう(これについては、同者のコチラのYoutube動画も参考になるかもしれません)

つまり、Rails チュートリアルは「Railsを初めて触る人がなるべく挫折しにくい難易度設定を目指す」ということを念頭に置いた教材であり、最前線の現場で使用されているような本格的なRailsの習得の橋渡しをするようは役割である、と考えることができるかと思います。逆に、これ以上現場に近づけた本格的な内容にしてしまうと、それこそ多くの初学者が挫折してしまうと思います。

したがって、Rails初学者は、今この時代であっても、自信を持って当教材取り組んでよいと思います。少なくとも自分は、この後にも続くRails学習において、ベースとなるような知識をつけることができた、と感じています。

ただ、いくら難易度を落としているとはいってもRails初学者に取ってはかなり難しく、かつ量も膨大であるのは事実です。そのため、Railsチュートリアル完走を一つのマイルストーンとして設定し、内容につまづいたら「ひたすらググる」あるいは「適宜Progateに戻る」という進め方が効率的かと思います。

私も、一度はあまりの量と難易度に挫折してしまったのですが、社会人としてすでに働いており、ある程度お金に余裕があったので、動画版を購入して最後までやり切りました。個人的には、人が解説してくれている形式の方が理解がスムーズで、モチベーションの維持もしやすかったで、お金に余裕のある方にはオススメです。

Railsチュートリアルで身につく知識を整理すると、

  • バックエンド: Rails(シングルアプリケーション)
  • フロントエンド: jQuey+bootstrap (Railsの一部として内包)
  • テスト: minitest
  • 開発環境: AWS cloud9
  • デプロイ: Heroku

全くの初心者からWebアプリとして求められる一通りの機能を実装し、本番環境へデプロイするところまでできるのは、やはり教材として素晴らしいと思います。

しかし先ほども述べた通り、当教材はあくまでも橋渡しの位置付けです。未経験からの転職という自分自身の立場を鑑みると、Web系企業への転職用PF作成の準備としては、技術面でまだ心許ない、と考えました。

改めて複数企業の採用ページから実際に企業で使用されている技術を確認し、上記の学習知識と比較して整理をすると、

  • フロントは、Vue.jsReact.jsといったJavaScriptフレームワークを使用するのが一般的。それに伴い、Railsは単独アプリとしてではなく、APIモードで開発する
  • テストフレームワークは、minitestではなく、Rspecがデファクトスタンダード
  • 開発環境はPCローカルに構築する(Vagrantで仮想マシンを構築するか、Dockerでコンテナ化するか)
  • アプリケーションのデプロイは、小規模であれば Heroku を使うこともあるが、企業が提供するような中・大規模なアプリケーションであれば、AWSGCPなどをよく用いられる

次に習得すべきは、ここの技術領域であることが分かりました(個人的な話ですが、この辺りの時期からエンジニア採用ページに書かれている各技術がスタックが、どういった内容であるかが理解できるようになってきており、成長を実感していました)。

Railsチュートリアルを完走した方は、完走者向けのロードマップ紹介ページもありますので、まずはここを見てみるものよいかと思います。しかし私は、洗い出した上記項目をより体系的に学ぶことができるものがないかと考え、自分なりに色々と教材を探してみた結果、以下のサービスに辿りつきました。

3.3 Take off Rails

image.png

URL: https://freelance.cat-algorithm.com/lp/take-off-rails

『あなたを「初心者エンジニア」から「現場で活躍できるエンジニア」まで引き上げます。』というスローガンを掲げた教材とメンターがセットになったサービスで、Rails チュートリアルと実際の企業の間の穴埋めを狙った内容になっています。

基本的にはすでに作成された教材に則っとりながら自分のペースでアプリを開発していくのですが、都度 Slack でメンターさんに質問を投げることができるというのが大きな特徴です。。

最終的な教材のゴールとしてはQiitaのクローンサイトを開発することになります。これの技術スタックは下記の通りです。

  • バックエンド: Rails APIモード
  • フロントエンド: Vue.js (ソースコードは作成済みのものを使用。あくまで Rails との繋ぎ込みまでを扱う)
  • テスト: Rspec(+Factory_bot)
  • 開発環境: ローカル + DB(MySQL) は Docker コンテナを利用
  • アプリのデプロイ: Heroku
  • その他: CircleCI による rspec, rubocop の自動化

※ 私の当サイト用のリポジトリ: https://github.com/ddpmntcpbr/qiita_clone

Railsチュートリアル時点での技術スタックと比べると、かなり実務に近い技術が盛り込まれていることが分かるかと思います。

こちら、決して安い金額ではないサービスだと思います(スクール等に比べれば全然安いですが)。ただ、当時欲しいと思っていた知識が一気に身に着けられると考えて、購入を決意しました。

結果、良い買い物だったと思います。自分が学びたい内容がきれいに体系化されていたこともそうですが、何より、教材内容についてメンターさんへ質問ができるのも有意義だと感じました。遅くとも24時間以内にはレスポンスが返ってくるのもありがたく、「料金分を回収してやるぞ!」という気持ちで、たくさん質問させてもらいました笑

本教材では、上記技術の学習だけでなく、

  • Git commit の適切な粒度や、コミットメッセージの書き方
  • Github での PR の出し方や、コードレビューの流れ
  • Slack でのやり取り(意図が伝わりやすい質問の仕方など)

といった、「独学ではなかなか身につかない」けど「チーム開発では必須になる」ような周辺知識について学べた点も、非常に有用だったと思います。Railsチュートリアルの内容がおおよそ理解できていれば前提知識としては十分な難易度で、大きく挫折をすることがなかった点もプラスです。

さて、ここまでで、Railsに関しては、比較的モダンな開発手法に触れることができました。

しかし、当教材ではあくまでも Rails の開発に的を絞ったものであり、フロントエンドは既存のソースコードを流用する形での学習でした。この教材の内容を自身の転職用PFに組み込むためには、フロントエンド側についても自身で開発する知識が必要と考えました。

フロントエンドフレームワークの選定について、第2章でもお伝えしたとおり、「Reactの方がなんとなくよさそうかなー」と考えていたところ、次の教材を見つけたことをきっかけに、正式に React の学習を始めることにしました。

3.4 【とらゼミ】トラハックのエンジニア学習講座

image.png

現役の React エンジニアである トラハックさん ( @torahack_ )が、Youtube上で公開している講座で、Reactについて基礎の基礎から学ぶことができます。

動画チャンネルURL: https://www.youtube.com/user/1492tiger

こちらの教材の特長は、

  • Reactの基礎の基礎から体系的に学べる( Progate の JavaScript 講座完了が受講目安)
  • 動画によるハンズオン形式
  • 教材範囲にモダンなフロントエンドの開発手法を含む( Redux 等)
  • 動画のほぼ全てがYoutube上でなぜか無料公開されている

特に最後については完全にバグとしか思えない点で、Udemyなどで有料販売されていても動画講座と比べても遜色ないクオリティだと思います。

動画教材にありがちな「準備した原稿丸読み」のような堅い口調ではなく、フランクな若手予備校教師の授業(?)のような語り口のため、硬い喋りが苦手な人にもお勧めできます。私は復習のために、一度見た動画を耳だけで聞き返したりして、記憶の定着を図りました。

講座はいくつかのシリーズに分かれており、私が視聴をしたのは、

1.『日本一わかりやすいReact入門』シリーズ
2. 『日本一わかりやすいReact入門【実践編】』シリーズ
3. 『日本一わかりやすいReact-Redux入門』シリーズ

の3シリーズです。

最終的な成果物の技術スタックは、

  • create-react-app
  • Redux & redux-thunk
  • Material-UI
  • Firebase: Google が提供する mBaaS。バックエンド+インフラを手軽にセットアップできる

です。

※ 私のGithubリポジトリ: https://github.com/ddpmntcpbr/react-ec-app

こちらの動画については、学習備忘録記事をQiitaに投稿しております。よろしければこちらもご参考下さい。

参考ページ: 『日本一わかりやすいReact入門【実践編】#1~5 学習備忘録

本学習講座を全て受講するためには、有料コミュニティ『とらゼミ』への加入が必要になりますが、筆者は無料公開範囲の動画で必要な知識は十分に身に付いたと感じたため、加入はしておりません。(代わりの記事として書くことで、宣伝として少しでもお役に立てればと思っています笑)

さて、ここまででフロント側も自力で開発ができる基礎が身に付きました。これくらいの時期に並行してアプリのコンセプトが決定していましたので、いよいよポートフォリオ作成に取り掛かり始めました。

しかし、開発を始めるといくつも壁が出てきます。基本的にはググりながらの解決をしていきましたが、どうしても解決できないエラーにもぶち当たりました。特に、

  • ReactとRailsの繋ぎ合わせ
  • AWSでのアプリの公開方法
  • その他インフラ知識全般

あたりが、個人的な難所でした。その過程で頼らせてもらったのが、次のメンターサービスです。

3.5 TechTrain

image.png

有名企業のエンジニアから実務を学べるオンラインコミュニティ です。

URL: https://techbowl.co.jp/techtrain

特長を列挙すると、

  • 現役エンジニアであるメンターさんと、1 on 1でのオンライン面談が可能
  • メンターの方々の技術領域は多種多様
  • 全てのメンターと面談が可能で、技術トピックに応じて切り替えることが可能
  • 面談はこちらからのタイミングで入れることができる
  • なぜか全て無料で利用できる

はっきり言います。これだけのことができて完全無料なのは完全にバグです。これからエンジニア就職を目指しているU30の学生・社会人は、全員登録した方がいいレベルです

TechTrain の中ではいくつかの Mission が設けられており、それをメンターと一緒に取り組んでいくことで知識を習得していく、ということが可能です。 Mission は実際のIT企業とのコラボで作成されており、中には「Missionをクリアできた人は一次面接をスキップできる」のような特典もついていたりします。

ただ私は Misson には取り組まず、あくまでの個人開発のサポートとして利用させてもらっていました。基本的には自身の既存知識とググり力でPF作成を進めつつ、どうしても解決できない課題が出てきたときにピンポイントで面談予約を入れる、というイメージで、個々人の利用したい形式/ペースで利用できる点も大変ありがたかったです。

異なる技術領域を持ったエンジニアの方々全員と面談をするが可能なため、Rails, React, AWSそれぞれで、別のメンターの方に質問をさせてもらっていました。

特に自力での解決が難しかったのがAWS周りの本番環境構築で、本サービス無しでは乗り越えられなかったと思います。

AWSのことをAWS現役社員に無料で聞けるサービスと表現すれば、このサービスのやばさが伝わるかと思います。

最終的には、自身のググり力 + TechTrain で都度メンターを利用、を繰り返すことで、無事アプリを完成させることができました!

3.6 番外編

上記以外で役に立ったものについて、ざっくばらんに紹介します。

Udemy 『Git:はじめてのGitとGitHub』

無料で Git の基礎を学べる講座です。「Gitよう分からん!」って人は、まずこれから触れてみましょう

『キタミ式イラストIT塾 基本情報技術者』

基本情報処理の定番本です。コンピューターサイエンス領域の基礎知識が体系的に学べます。イラストが豊富であり、文章表現も柔らかいので初心者にも優しいです。資格自体の取る/取らないに関わらず一読をオススメします。

『米国AI開発者がゼロから教えるDocker講座』

Dockerについて一から学べる動画教材です。作者様はデータサイエンス領域の方ですが、Webアプリ開発を目的とした人であっても問題ありません(実際に、講座後半では、docker-composeを利用したRailsコンテナの構築まで扱っています)

非常にボリューミーな内容にも関わらず、Udemy講座の中ではかなり良心的な価格設定です。

『【AWS 入門】EC2とDockerでHello Worldしよう』

AWSについて何にも分からない状態から、「nginxだけのシンプルなコンテナアプリを動かす」ところまで、ハンズオン形式で学習ができます。

AWSのとっつきにくさは、「①インフラの概念が分からない」「②専門用語が分からない」に集約されると思います。まずは手を動かしながら、AWSでアプリをデプロイ流れを全体像で掴むことができます。

3.7 アプリの改善点

一通りアプリを完成させてみて、初めて見えてくる改善点が多くありましたので、合わせて列挙します。

AWSサーバー代高すぎ!!!

スケーラビリティの高い中・大規模向けインフラ構成になっているため、サーバー代がめっちゃ高い笑

長く公開するためには、どこかのタイミングで無料サーバーへ移管する必要があるかなと思います。Heroku の無料枠で上手にやりくりできれば、解決できるかもしれないです。

フロントエンド は Next.js + Typescriptで実装したい

Next.js はレンダリングのタイミングを制御できるので、OGP情報の保持が簡単に実現できます。

また、それ以外でも、

  • ルーティング設定が簡単
  • パフォーマンスをよくするような機能も豊富
  • Typescriptの導入が用意

というメリットもあり、とても気になっているフレームワークです。次、全く同じアプリを開発するとするのであれば、絶対に採用したい技術です。

デザインがあやしい気がする・・・?

アプリを開発して気づいたのは、アプリにおけるデザインの重要性です。

これを思った理由は単純で、開発途中で「なんか自分のアプリ、イケてなくない?」と感じたからです笑

Webアプリにおけるデザインは、単なるお洒落さに関するものだけでは決してありません。デザインは、ユーザーにとって必要な情報を適切に配置することであり、ユーザーの価値提供のための最前線領域です

ユーザー側から価値提供の流れ(バリューチェーンと表現するのでしょうか)をざっっっくり並べると、

ユーザー -> UI/UXデザイン -> フロントエンド -> バックエンド -> インフラ

のようになっていると思っています。

「エンジニアになろう!」と意気込んでから、後ろ3つについてはそこそこ勉強してきました。しかしデザイン領域については、開発初期は完全素人の状態で、途中までは勘でやっていました。。。

一応、付け焼き刃程度ではありますが、デザインの名著である『ノンデザイナーズ・デザインブック』に目を通し、途中からは意識できる範囲ではデザインのことを意識して、フロントを実装しました。

うまく取り込めているかは分かりませんが、少なくとも「デザインはセンスではなく論理」であることが学べただけでも、よい勉強になりました。こちらの書籍も、転職用PF作成者にオススメしておきます。

4. さいごに

以上、大変長い記事でしたが、最後まで読んでいただきありがとうございました。タイトルでは「学習ロードマップ」と銘打っておきながら、私自身の思考プロセスや価値観についても多く書かせてもらいました。

「エンジニアになりたい!」と思い立ってから、学習自体はほぼ一人で淡々と進めてきました。しかし、ほぼ独学でここまで学習を進めることができたのは、多くの先輩エンジニアの方々が様々な情報をインターネットに投稿し、それをオープンに取得できる環境にあったからだと思っております。

それであれば、次は自分自信が、他の駆け出しエンジニアの方々の助けになるような情報を発信できれば、と思い、この記事を書くこととしました。参考になったという方がいらっしゃったら幸いです。

是非LGTM、ストック、twitterでのシェアお願いします!また、私自身もtwitterをやっておりますので、気軽にフォローしてもらえるとうれしいです(^^)

よろしくお願いします!

Twitter: https://twitter.com/ddpmntcpbr
Github: https://github.com/ddpmntcpbr/rails_react_docker

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【未経験】独学+メンターでここまで出来た!Web知識ゼロからモダンな技術アプリ開発までに利用した5つのサービス【Rails / React / AWS / Docker / CircleCI】

0. はじめに

こんにちは!辻野(@ddpmtcpbr)と申します。

当記事は、「Webエンジニアへのキャリアチェンジを目指している開発未経験者が、モダンな技術を備えたアプリを開発するまでの学習過程」についてまとめたものです。

現在筆者は非IT系企業の社員として働いており、Web開発エンジニアとしての実務経験はありません

そんな筆者がWebエンジニアとしてのキャリアチェンジをするためのポートフォリオとして、本アプリを開発しました。

学習開始から現時点までにおいて、プログラミングスクール等には通っておらず、学習はほぼ全て独学&一部メンターサービス利用の布陣で進めてきました。

独学中心でアプリ開発に挑戦したい、ポートフォリオを作成してWebエンジニアへのキャリアチェンジを進めていきたい、と考えている方々にとって、参考になればと思います。

最初に、今回私が開発したアプリの概要を紹介します。

アプリ名: 積読解消アプリ 「Yomukatsu!」

image.png

あなたの積読解消をサポートします」をスローガンに掲げたSPA風Webアプリです(”風”の詳細は後述)。

読書メンタルマップという手法を用いて、ユーザーの書籍完読に向けたモチベーション維持をサポートします。

Web URL: https://yomukatsu.com/

【3分動画】Yomukatsu 字幕解説

アプリの使い方を3分でまとめています。

使用技術

  • Backend: Rails ( API mode / Rspec / rubocop) + Nginx ( upstream puma-socket )
  • Frontend: React ( create-react-app / Redux / Material-UI / eslint&prettier)
  • Infra: AWS ( ECS Fargate/ ECR / RDS / ALB / Route53 ), Netlify, Docker&docker-compose, CircleCI

各項目の詳細は後述しています。

インフラ構成

yomukatsu_cloud_architecture.png

モダンな技術を採用したWeb系企業が提供している、中・大規模なアプリケーションを想定したインフラ構成にしています(そのため、個人開発アプリとしてみるとちょっと仰々しいかもです(;’∀’))

詳細は後述しています。

機能一覧

ユーザー利用機能

  • Twitterアカウントを利用したユーザー登録(OAuthによるSNS認証)
  • ゲストログイン機能
  • Google Books APIを用いた書籍検索機能
  • Google Books、Amazon、楽天ブックスへのリンクボタン配置
  • Twitterシェア機能
    • ハッシュタグ「#yomukatsu」付きTweet
    • Twitter card 表示
  • Twitter card用にリサイズした書籍画像をAWS S3へ保存・管理
  • Redux による state 管理を活用したローディング画面
  • Slack Incomming Webhookを利用したお問い合わせ機能
  • Route53 による独自ドメイン + SSL化

非ユーザー利用機能

  • Netlify の Pre-reidering 機能活用による動的なOGP情報の保持( Twitter card 表示用)
  • Docker による開発環境の完全コンテナ化
  • CircleCI による自動 CI/CD パイプライン構築
    • CI: Rspec, rubocop, eslint&prettier
    • CD: AWS ECR
  • その他セキュリティ対策(XXS, CSPF等)

まず触ってみてもらうのが一番良いかと思います!今回はフロントエンドに React を採用しているため、メニューモーダルの開閉や通知バー表示など、アニメーション的な表現も実装できているのが伝わるかと思います。

ゲストユーザー機能もありますので、気軽に利用してみてほしいです!レスポンシブにも対応しています。(推奨ブラウザはChrome、Safariになります)

アプリURL: https://yomukatsu.com/

※現在α版としてのリリースのため、配信内容が予告無く変更される可能性がございます

あわせて、 Githubも公開していますので、よかったら参考にしてください。

Github URL: https://github.com/ddpmntcpbr/rails_react_docker

この記事について

当記事は3章構成になっております。

まず、「1.自己紹介」で、簡単に自己紹介をさせていただきます。

次に、「2.開発アプリ解説」で、今回の開発アプリ開発について、コンセプト決定の流れから、実装機能/技術スタックについて詳しく紹介します。「転職用PF作りたいけど、どんなアプリを作ればいいか分からない」という方にとって、参考になることがあれば幸いです。

最後に、「3. 学習ロードマップ」で、Web知識ゼロだった筆者が、当アプリの開発にまでに利用した5つの教材およびサービスについて、時系列に沿って紹介したいと思います。特に独学では、「まず何を学べば良いのか」「どんな教材を選べば良いのか」というところから自身で考える必要があります。そういった方々にとって参考になり得る情報と思います。

1. 自己紹介

1.1 筆者スペック

  • 20代後半 男
  • 工学部機械系 修士卒 → 非IT系 日系製造業 技術開発職(現職)
  • 大学から現職において、データ分析ツールとしてプログラミングを経験(matlab / python)
  • Webエンジニアへのキャリアチェンジを目指し、社会人になってから独学を開始

大学入学以降、授業や研究データの分析ツールとしてプログラミングに触れる機会はありました。もともと自動化や効率化に興味があったことからプログラミングにだんだんとのめり込み、研究室ではプログラミングに多く触れられそうな研究テーマ(データ分析系)を選びました。

したがって、「プログラミング自体が完全に未経験」というわけではありませんでした。しかし、いわゆる”Web系”の知識は社会人以降の独学を開始するまではゼロ、という状態で、最初は HTML すら知らないところからのスタートでした( ̄▽ ̄;)。そのため当記事では「Web知識ゼロ」という表現をしています。

キャリアチェンジ志望の理由は、ざっくりと言えば、

1. もっとプログラミングがしたい
2. モノづくりで誰かの役に立ちたい
3. 非効率・非生産的な仕事を無くしたい

ここについては当記事の趣旨ではないので、詳細については省略します。

2. 開発アプリ解説

2.1 コンセプト方針

転職用PFアプリのコンセプトを決めるにあたり、満たすべき用件としては、下記3点を考えました。

(a) 実際の企業が採用しているようなモダンな技術を盛り込む
(b) 具体的な解決課題を明確にする
(c) サービスの利用が個人で完結する

(a) 実際の企業が採用しているようなモダンな技術を採用する

未経験からエンジニア転職において、高品質なポートフォリオは必須と考えました。

「モダンな技術をポートフォリオに組み込むことで、技術力の高さをアピールする」というのが基本的な考え方になるとは思いますが、個人的な解釈としては、ポートフォリオで証明すべきは「技術力」ではなく「自走力」だと考えています。

ぶっちゃけた話、実際の現場を経験したエンジニアと比べれば、未経験者間での能力差というものはどんぐりの背比べのようなものだと思います。多くの企業が「実務経験1年以上」をエンジニアの採用項目にあげていることからも、実務経験というのはそれだけ重い価値があり、未経験者とは大きな隔たりがあるのだと思います。

したがって、ポートフォリオの技術レベルの高さそのものはあまり重要ではなく、そこに到達するまでの過程の方が大事であり、「自走力=必要な情報は自らキャッチアップして吸収する能力」があることを示す方が、企業人事側としては採用しやすいのではないか?と考えました。

「スクールの制作アプリをそのまま提出する未経験者が足切りされてしまう」という話は多く聞きますが、これはそのアプリの技術力が低いからではなく、そのアプリから当人の「自走力」が主張できないから、だと私は考えています。私が独学ベースにこだわったのは、単純にお金の問題だけではなく、独学ベースでアプリを開発することができれば、自然とそれが「自走力の証明」につながると考えたからです。

今回のアプリにおいては、「独学:メンター=8:2」 くらいの割合で、上記技術を採用できるラインまで行くことができています。「メンター利用は独学からは外れるのでは?」という指摘もあるかもしれませんが、

  • プログラミングでは、個人ではどうにもならないようなエラーに遭遇してしまうことが多々ある
  • 実際に企業に入ってからは、先輩エンジニアの方々に分からないことを質問しながら業務を進めることになるため、「質問力」も重要な能力である
  • 完全独学オンリーだと、誤った癖が身についてしまっているリスクが高くなる

といった観点から、独学者が適宜メンターサービスを利用することは、かえって採用人事側にとって安心感を与える材料になるのでは、と考えたので、自信を持って「メンターサービスを使いました」と主張しています。

※ 具体的なモダンな技術リスト

  • Rails API + JSフレームワーク(React.js)の構成
  • Dockerで実行環境を完全コンテナ化
  • Herokuではなく、AWS でアプリをデプロイ(ECS Fargate & ECR)
  • Circle CIによるCI/CDパイプラインの構築

(b) 具体的な解決課題を明確にする

さて、前章とは一見真逆のことを言いますが、アプリ開発において、モダンな技術を採用することそのものには本来何の価値もない、と考えています。

なぜなら、アプリの目的はあくまでも「ユーザーにとって価値を提供できるか」であり、技術はそれを実現するための手段でしかないはずだからです。(保守・運用面でのメリットも考えられますが、保守・運用の最終目的もユーザーへの価値提供であることから、この点も包含した解釈になります)

これは、技術というものを下に見ているというわけでは決してありません。むしろ「新しい技術をどんどん使ってみたい!」という技術に対する好奇心、探究心は人一倍強い自負があります。現職はIT系ではありませんが、技術開発職という立場で業務に取り組んでおり、知的好奇心を満たせるという意味では、今の仕事に面白みを感じています。

しかしながら、かつては行き過ぎた技術先行思想によって「手段の目的化」が発生し、「最新技術を駆使した誰にとっても役に立たない技術」を開発してしまったという苦い過去の経験があったりもします。結果として「やっぱり技術は人の役に立ってなんぼ」というのが、約3年間技術職として働いてきて培った、技術者としての小さな矜持だったりします(この辺の話は直接お会いした方にはお話できるかと思います)

転職用PFであれば、技術ありきな考え方になることはある程度は仕方がないことでしょう。しかし「せっかく作るのであれば、誰かにとって役に立ち得るものを目指そう」くらいのことは転職用PF作成においても考えていいんじゃないかな?と思いました。あるいは、もう少し目線を下げて「自分が欲しいものを作ろう」という程度でも十分でしょう。大事なのは、まず課題があり、それを解決する手段として技術があるという順番だと思いました。

もちろん今回の開発アプリは転職用PFが趣旨である以上、中には「技術力を証明したいから」という理由で選定した技術もあり、全てに対して課題が明確だったわけではありません。また、初心者の個人開発アプリがいきなりバズることは現実的には厳しいとは思います。しかし、そこを目指す姿勢があるかというのは、エンジニアとして本格的にキャリアを進めていく上では、長期的には大きな差異になると考えています。

また、

  • 課題が明確な方が採用した技術や実装した機能の根拠も明確にできるため、開発の方針を立てやすい
  • 自身がユーザー目線に立てることで、改善点を見つけやすい
  • 純粋にモチベーションを維持しやすい

といった点でもメリットもあると感じましたので、この方針は間違っていなかったと思います。

(c) サービスの利用が個人で完結する

「せっかく作るのであれば、誰かにとって役に立ち得るものを目指そう」を、もう一歩深く考えた方針です。

例えば Rails を対象として考えたとき、一般的な転職用PFとしては、TwitterライクなSNS系アプリや、メルカリライクなEC系アプリが多いかと思います。

理由は、ユーザー認証、CRUD操作、DB間のリレーションなど、基本的なサーバーサイド技術を一通り抑えられるものであるから、だと思います。「Railsの一般的な知識を持っていることを証明する」手段と考えれば、妥当な方針でしょう。

しかしながら、未経験者が転職用に開発した上記アプリが実際にユーザーに継続して使われるということは、まず無いでしょう。SNS系アプリは「ユーザー数が多ければ多いほどサービスとして質が高まる」性質があるため、アプリとして軌道に載せること自体が非常に難しいです。EC系アプリは BtoC であれば出品企業がいないとサービスが成り立たない、CtoCであればより SNS として要素が強まる & いよいよメルカリで十分、という壁があります。

これらアプリの難しさは、ユーザーどうしがつながることを前提としている点にあります。裏を返せば「個人で完結するアプリであれば、活路はある」とも言えると考え、この方針でコンセプトを詰めていくことにしました。

2.2 コンセプト内容

上記3点を念頭に置きながら、自分自身の生活の中で"課題"を探し、最終的にたどり着いたものが「読書メンタルマップ術の電子化」というコンセプトでした。

そもそも皆様は、読書メンタルマップ術というものをご存知でしょうか?

読書メンタルマップ術とは、ハーバード大学の先生が提唱している積読解消術です。読破したい書籍に対して、

1. 完読したい本について、それを読む“理由”や“目的”を3つ、紙に書きだす
2. 飽きてきたら、それを見返す

を繰り返すことで、完読までモチベーションを維持するというシンプルな読書手法です。

積読というものは、だいたい「最初は読む気があったけど、次第に読む気がなくなってしまった」書籍です。この「最初の読む気」を事前に明文化・保存しておくことで、いつでも最初の頃に新鮮な気持ちを取り戻せるようにしておこう、というイメージになります。

自分自身、実際に活用している技術ではあるのですが、少し困ったことがあります。それは、電子書籍との相性が悪いことです。

通常であれば紙とペンを用いるものですが、例えば出先でスマホやタブレットで電子書籍を読んでいるような状況では、必ずしもこれらの道具があるとは限りません。特に私は、外に出る時はあまりものを多く持ちたく無い性分なので、外ではスマホと財布くらいしか持っていないことが多いです。

仮に持っていたとしても、例えば電車の中で紙とペンを出して色々と書き始めるのは、少し億劫だったりします。

これを全部ペーパーレスで完結できるようなアプリがあったら便利だな」と思ったのが、このコンセプトを思いついたきっかけになっています。

もちろん、これだけであればスマホのメモ帳だけでもできてしまうものですが、このアプリには、

  • Google Books APIを活用した書籍検索・保存機能
  • メンタルマップ作成のヒント機能
  • Google Books, Amazon, 楽天ブックスへのリンクボタン配置(特に書籍レビューはメンタルマップ作成の大きなヒントになる)
  • Twitterでの読書仲間への気軽なシェア機能

といった機能が備わっており、より読書メンタルマップ術を使用しやすい環境を整えています。

先ほどの「2. 具体的な解決課題を明確にする」に照らし合わせて考えると、このアプリの解決課題は、ユーザーの積読を解消すること、もっと言えば、読書メンタルマップ術をペーパーレスで実行できるすることで電子書籍で読書するユーザーにとっても扱いやすくすること、になります。

また、「3. サービスの利用が個人で完結する」も満たしています。当アプリには、ユーザー同士がつながる機能は一切実装されていません

代わりとして、Twitterとの連携にはかなり重きを置いて実装機能を決めました。具体的には、

  • Twitterアカウントを利用したユーザー登録
  • ワンタップでハッシュタグ付きツイート
  • 充実した Twitter カード表示

を機能として実装しています。原則的には個人でサービスが完結しつつも、ユーザーどうしの繋がりはTwitter内の既存のネットワークに乗っかる、ことを狙ったコンセプトになっています。

2.3 技術スタック

再度、インフラ構成を載せます。

yomukatsu_cloud_architecture.png

この内容について、ひとつひとつ解説します。

Back-end

Rails API + Nginx の組み合わせにしています。

サーバーサイドフレームワークとしては他にも Laravel, Django, Node.js などもあります。恐らく大体のことは、どれを選んでも実装・実現できる、と思うのですが、その中で今回 Rails を選んだ理由は、

  1. 採用している企業数が多い
  2. 日本語の教材が豊富なため学習のハードルが低い
  3. 国内コミュニティが発達しているため、インターネット上での日本語ドキュメントが豊富

最初の学習言語として Rails を選択する初学者の方は多くいるかと思います。その一方で、「Railsはオワコン」という説が各所で言われていることについて、不安に感じる初学者の方もいると思います。

この点に関して、あくまで個人的な見解を述べますと、初学者であった自分が、少なくとも最初に学ぶ言語/FW として Rails は間違いではなかった、と考えています。

正直、初学者である私には、「なぜ Rails がオワコンであるのか」について技術ベースで語ることはできません。しかし、

  • 現時点で Rails を採用している企業の絶対数は多く存在すること
  • 日本国内において、Rails に替わるサーバーサイドのデファクトスタンダードな技術が、まだ定まっていないこと

は事実と言ってよいかと思います。

もしかしたら、長期的に見れば日本国内でも Rails を採用する企業が減っていく流れにはあるのかもしれません。しかし、微分値と絶対値はセットで捉えないと判断を誤ることになります。初心者が目指すべきは「今すぐに仕事を得られる技術を身に着けること」であり「将来必要になってくる技術」ではない、自分が今学ぶべきはやはり Rails である、と判断をしました。

また、オワコンというのは裏を返せば、技術的に枯れていて、初心者にとっては学びやすい言語/FWである、とも言えます。

特に日本国内での(過去含めた)使用者が多いため、日本語のドキュメントが多く存在します。事実、Rails開発で遭遇するエラーは、Google検索すれば何かしらの日本語記事がヒットします。

最先端の技術は過去の技術の欠点を補う要素を持って生まれてきているのは事実ですが、検索しても欲しい情報が見つからなかったり、あったとしても英語ドキュメントだけだったりします。私自身は、このアプリの開発を通じてWebフレームワークに基本的な概念が身についてきているため英語でも大丈夫になってきましたが、ベースラインすら乏しい状態の初学者がいきなり英語のドキュメントを読み解いていくのは、二重にしんどいです。

以上が、私が最初の言語/FWとして Rails を選んだ根拠になります。

主要gem
  • devise_token_auth: APIモードでの devise。トークン認証を簡単に実装
  • twitter_omniauth:Twitter認証を簡単に実装
  • active_model_serializer: Rails APIからのレスポンスJSONを制御
  • imageMagic: 画像のリサイズを実行。特に、Twitter card用に書籍画像をリサイズする際に使用
  • aws-fog/carrierwave: リサイズした書籍画像を AWS S3 に保存
  • rspec: デファクトスタンダードになっているRubyテスト用フレームワーク
  • rubocop: Rubyの静的コード解析

TwitterアカウントでのOAuth認証は、過去の実装例が少なく、非常に苦労したところでもありました。しかし、「Twitterとの連携を重視」という今回のコンセプト上では絶対に欲しい機能と考え、頑張って実装しました。

AWS S3については元々採用予定はなかった(Google Books APIの画像リンクをそのまま引っ張ってくる予定だった)のですが、Twitter card で書籍画像を表示させる時にどうしても画像サイズを適切に制御する必要が出てきたので、imageMagic と合わせて Rails で画像リサイズ & S3保存、を実装することにしました。

Front-end

今回フロントエンドとしては、JSフレームワークであるReact.jsを採用しました(細かいこと言えば React はフレームワークではなくライブラリですが、ここではフレームワークとして扱います)。モダンな技術採用を謳う以上、Rails + jQuery/bootstrap の構成では心許ないと考えました。

JSフレームワークとしては、国内企業での採用状況から考えるに、React.jsVue.jsか、の二択になると思います。その中でもReact.jsを選んだ理由は、

  1. 自分が調べた範囲では、バックエンドに Rails を採用している企業群のうち、フロントに React を採用している企業の割合が高かった
  2. Vue.js よりも規約が厳格であり、初学者の自分であっても自然と可読性の高いコードを書くことができそう
  3. たまたま、React を効率的に学べる良い教材を見つけた

特に最後については、第3章で後述しています。

アプリ開発を通じて React.js が割と気に入ってきたので良い選択だったとは思いますが、この点に関してはどちらを選んでも間違いではなかったかな、とは思います。

主要ライブラリ等
  • create-react-app: Facebookが提供するオープンソースのReact開発パッケージ
  • Redux: Stateの一元管理するフレームワーク。Redux関連ファイルは、reducksパターン則って管理
  • Redux-thunk: Redux state の非同期処理を制御
  • react-helmet: 動的なmetaタグの挿入によるOGP情報の保持(Twitter card用)
  • react-share: Twitter含めたSNSシェア用ボタンを簡単に配置
  • Material-UI : Google が提供する UI コンポーネントライブラリ。簡単におしゃれな UI コンポーネントをアプリ内に配置できる
  • eslint & prettier: javascriptに対する静的コード解析。eslint は create-react-appに標準搭載されているものをベースに少しプラグインを追加 & prettier はイチから導入

今回はユーザーの利用シーンを考えると、Web上でもネイティブアプリのようにサクサク動く、JSリッチなアプリケーションにしたいと考えました。この点からも、jQuery+bootstrap ではなく React.js を採用してよかったと思います。

React の実装には、特にMaterial-UIが強力で、開閉モーダルや通知バー表示などのアニメーション演出や、ページ全体のレスポンシブ対応などがかなり簡単に実装できました。このライブラリを使えたというだけでも、React を採用した価値があったと思えるほどでした。

Infra

Docker/docker-compose

開発環境は、全てDockerコンテナ内で完結させています。docker-compose.ymlのサービス構成としては、

  • db: MySQL
  • api: Rails
  • web: Nginx
  • front: Node.js (React)

としています。

後述しますが、AWS ECS(Fargate)へのコンテナデプロイを利用することで、開発環境と本番環境の差異を小さくすることができています。

AWS(Amazon Web Service)

バックエンド( Rails + Nginx )のデプロイに使用。Railsチュートリアルなどではアプリの本番環境へのデプロイにはHerokuを用いることが一般的ですが「モダンな技術を採用したい」という観点から、AWSに挑戦しました。

稼働させるまでめちゃくちゃ苦労しました。ここを完全独学で完結させるのは相当しんどいと思います。第3章で触れていますが、AWSの学習については、メンターさんをかなり頼らせてもらいました。

※ 利用サービス

  • ECS (Fargate): コンテナ向けサーバーレスコンピューティングエンジン。この中に Rails と Nginx の Docker イメージを入れて稼働させる
  • ECR: Rails と Nginx の Docker イメージを保存しておくリポジトリ
  • RDS (MySQL): AWS が用意しているスケーラブルなデータベースエンジン
  • ALB: 負荷分散を担うロードバランシングサービス
  • Route53: サイトの独自ドメイン化に使用
  • ACM: サイトの https 化に使用
  • S3: 静的ホスティングサービス。書籍画像も保存・管理に使用
Netlify

フロントエンド(create-react-app)のホスティングで利用。

最初はバックエンドに合わせてフロントも AWS ( Amplify Console ) でホスティングしていたのですが、create-react-appはSPAとしてのアプリ開発となることから、metaタグ無いにOGP情報を保持できない = Twitterでページをシェアした時のカード表示を動的に制御できない、という問題が出てきました。

おそらくは AWS でも解決する手段はあると思うのですが、今回は Netlify の Pre-rendering機能を使うことで解決することにしました。この機能を使うことで、 create-react-app であっても、サーバー側で javascript をレンダリングしてからブラウザが解釈できるようになります ( あと単純に、無料で利用できるのもメリット )

この問題にあたってから、最近ホットな React フレームワークの Next.js の有り難みが自然と分かるようになってきた( Next.js は SPA/SSG/SSRを選択可能 )のですが、今回はすでに開発を始めていたこともあり、create-react-app + Netlify の構成で最後まで開発しました。

CircleCI

国内ではデファクトスタンダードとされている、Saas型のCI/CDサービスです。今回CircleCIで自動化した処理は、

  • Rspec
  • rubocop
  • eslint&prettier
  • AWS ECR への Image push
  • AWS ECS のタスク&サービスの更新

Netlifyにはもともと自動デプロイ機能がついていることから、CircleCIを導入することで、Github上の master ブランチに merge しただけで、本番環境への再デプロイが完了する、という状態に持っていくことができました。

一度ありがたみが分かると、もう手放せないですね( ´ ▽ ` )

3. 学習ロードマップ

さて、いよいよ本題です。ここまでで開発したアプリについて解説をしてきましたが、ここからは、このアプリ開発に至るまでの学習過程をたどっていきます。

第1章でもお伝えした通り、筆者はプログラミング経験自体はあっても、いわゆる「Web系」の知識はゼロからのスタートでした。繰り返しますが、HTMLすら知らなかった状態から、独学ベースで上記技術スタックをアプリに盛り込めるレベルまで到達することができました

独学ベースでの学習になると、「どの学習教材を選ぶべきか」というところから自分で考える必要があります。いろいろと紆余曲折ありましたが「これは役に立った!」と思うものを厳選し、時系列に沿ってお伝えします。

※下記サービスのWebリンクや、ロゴ画像、ホームページのスクリーンショットについては、事前に各運営者様に使用許可をいただいております。改めまして運営者皆様、利用快諾していただきありがとうございました。

3.1 Progate

image.png

皆大好きProgate。今からエンジニアを目指す方は、全員ここから入門して間違い無いでしょう。

URL: https://prog-8.com/

自分は手当たり次第に色々な講座をやってみていましたが、

  • HTML&CSS
  • Javascript(ES6)
  • jQuery
  • Ruby
  • Ruby on Rails

次いで

  • Command line
  • Git
  • SQL

辺りを押さえておけば十分だったかと思います。

各講座の序盤のレッスンは無料会員でも受けることができますが、本気でエンジニアを目指すのであれば、有料会員限定のコースも含めて取り組んでいきましょう。

これだけでもそれなりにボリュームはありますが、挫折しにくいよう学習ステップがかなり細かく設定されているので、初心者にとっても易しいつくりになっています。

ただ、Rails講座だけはさすがに難易度が高かったです。。。これは、Progateさんの講座の作り云々ではなく、Webフレームワークという概念が初学者にとって「始めまして」になるので、多少仕方がない部分ではあると思います。

1周目で全体像の把握、2週目以降で詳細理解に努める、というスタンスでよいかと思います。

3.2 Ruby on Railsチュートリアル

image.png

皆大好き(?) Rails チュートリアル。

URL: https://railstutorial.jp/

色々賛否ある教材ですが、無料かつ、ここまで体系的に「RailsのWebアプリ開発」を学べる教材は他にないと思います。

本教材の謳っているところでもありますが、「単にRuby, Railsの学習に終始せず、Webアプリ開発の全体像を俯瞰する」ものですので、本教材での知識は、他言語・他フレームワークで開発をする場合でも大いに活きると思います。

確かに、当教材に対する否定的な意見はいくつか見受けられ、

  • テストフレームワークとして、国内企業でデファクトスタンダードになっているRspecではなく、Railsに標準搭載されているminitestを使用している
  • 採用技術が古くなってきてしまっている

という点がよく指摘されています。

ただ、前者については、株式会社YassLab代表のコチラのYoutube動画の動画でも説明がある通り、「かつて(第2版まで)は Rspec を Rails チュートリアルでも採用していたが、Rspec 自体の学習コストが高いこともあり、それによる脱落者を多く出していた」という背景を受けてのものになります。

また後者については、例えば現在の Rails企業の多くは、Rails単体のアプリケーション(フロントはjQery/bootstrap)ではなく、APIとしてRailsを利用し、フロントはJSフレームワーク(Vue.jsやReact.js)を使うのが一般的になってきています。しかし、Rails初学者が、いきなりAPI開発から始めるのは、理解の階段を飛ばしすぎている、というのも事実でしょう(これについては、同者のコチラのYoutube動画も参考になるかもしれません)

つまり、Rails チュートリアルは「Railsを初めて触る人がなるべく挫折しにくい難易度設定を目指す」ということを念頭に置いた教材であり、最前線の現場で使用されているような本格的なRailsの習得の橋渡しをするようは役割である、と考えることができるかと思います。逆に、これ以上現場に近づけた本格的な内容にしてしまうと、それこそ多くの初学者が挫折してしまうと思います。

したがって、Rails初学者は、今この時代であっても、自信を持って当教材取り組んでよいと思います。少なくとも自分は、この後にも続くRails学習において、ベースとなるような知識をつけることができた、と感じています。

ただ、いくら難易度を落としているとはいってもRails初学者に取ってはかなり難しく、かつ量も膨大であるのは事実です。そのため、Railsチュートリアル完走を一つのマイルストーンとして設定し、内容につまづいたら「ひたすらググる」あるいは「適宜Progateに戻る」という進め方が効率的かと思います。

私も、一度はあまりの量と難易度に挫折してしまったのですが、社会人としてすでに働いており、ある程度お金に余裕があったので、動画版を購入して最後までやり切りました。個人的には、人が解説してくれている形式の方が理解がスムーズで、モチベーションの維持もしやすかったで、お金に余裕のある方にはオススメです。

Railsチュートリアルで身につく知識を整理すると、

  • バックエンド: Rails(シングルアプリケーション)
  • フロントエンド: jQuey+bootstrap (Railsの一部として内包)
  • テスト: minitest
  • 開発環境: AWS cloud9
  • デプロイ: Heroku

全くの初心者からWebアプリとして求められる一通りの機能を実装し、本番環境へデプロイするところまでできるのは、やはり教材として素晴らしいと思います。

しかし先ほども述べた通り、当教材はあくまでも橋渡しの位置付けです。未経験からの転職という自分自身の立場を鑑みると、Web系企業への転職用PF作成の準備としては、技術面でまだ心許ない、と考えました。

改めて複数企業の採用ページから実際に企業で使用されている技術を確認し、上記の学習知識と比較して整理をすると、

  • フロントは、Vue.jsReact.jsといったJavaScriptフレームワークを使用するのが一般的。それに伴い、Railsは単独アプリとしてではなく、APIモードで開発する
  • テストフレームワークは、minitestではなく、Rspecがデファクトスタンダード
  • 開発環境はPCローカルに構築する(Vagrantで仮想マシンを構築するか、Dockerでコンテナ化するか)
  • アプリケーションのデプロイは、小規模であれば Heroku を使うこともあるが、企業が提供するような中・大規模なアプリケーションであれば、AWSGCPなどをよく用いられる

次に習得すべきは、ここの技術領域であることが分かりました(個人的な話ですが、この辺りの時期からエンジニア採用ページに書かれている各技術がスタックが、どういった内容であるかが理解できるようになってきており、成長を実感していました)。

Railsチュートリアルを完走した方は、完走者向けのロードマップ紹介ページもありますので、まずはここを見てみるものよいかと思います。しかし私は、洗い出した上記項目をより体系的に学ぶことができるものがないかと考え、自分なりに色々と教材を探してみた結果、以下のサービスに辿りつきました。

3.3 Take off Rails

image.png

URL: https://freelance.cat-algorithm.com/lp/take-off-rails

『あなたを「初心者エンジニア」から「現場で活躍できるエンジニア」まで引き上げます。』というスローガンを掲げた教材とメンターがセットになったサービスで、Rails チュートリアルと実際の企業の間の穴埋めを狙った内容になっています。

基本的にはすでに作成された教材に則っとりながら自分のペースでアプリを開発していくのですが、都度 Slack でメンターさんに質問を投げることができるというのが大きな特徴です。。

最終的な教材のゴールとしてはQiitaのクローンサイトを開発することになります。これの技術スタックは下記の通りです。

  • バックエンド: Rails APIモード
  • フロントエンド: Vue.js (ソースコードは作成済みのものを使用。あくまで Rails との繋ぎ込みまでを扱う)
  • テスト: Rspec(+Factory_bot)
  • 開発環境: ローカル + DB(MySQL) は Docker コンテナを利用
  • アプリのデプロイ: Heroku
  • その他: CircleCI による rspec, rubocop の自動化

※ 私の当サイト用のリポジトリ: https://github.com/ddpmntcpbr/qiita_clone

Railsチュートリアル時点での技術スタックと比べると、かなり実務に近い技術が盛り込まれていることが分かるかと思います。

こちら、決して安い金額ではないサービスだと思います(スクール等に比べれば全然安いですが)。ただ、当時欲しいと思っていた知識が一気に身に着けられると考えて、購入を決意しました。

結果、良い買い物だったと思います。自分が学びたい内容がきれいに体系化されていたこともそうですが、何より、教材内容についてメンターさんへ質問ができるのも有意義だと感じました。遅くとも24時間以内にはレスポンスが返ってくるのもありがたく、「料金分を回収してやるぞ!」という気持ちで、たくさん質問させてもらいました笑

本教材では、上記技術の学習だけでなく、

  • Git commit の適切な粒度や、コミットメッセージの書き方
  • Github での PR の出し方や、コードレビューの流れ
  • Slack でのやり取り(意図が伝わりやすい質問の仕方など)

といった、「独学ではなかなか身につかない」けど「チーム開発では必須になる」ような周辺知識について学べた点も、非常に有用だったと思います。Railsチュートリアルの内容がおおよそ理解できていれば前提知識としては十分な難易度で、大きく挫折をすることがなかった点もプラスです。

さて、ここまでで、Railsに関しては、比較的モダンな開発手法に触れることができました。

しかし、当教材ではあくまでも Rails の開発に的を絞ったものであり、フロントエンドは既存のソースコードを流用する形での学習でした。この教材の内容を自身の転職用PFに組み込むためには、フロントエンド側についても自身で開発する知識が必要と考えました。

フロントエンドフレームワークの選定について、第2章でもお伝えしたとおり、「Reactの方がなんとなくよさそうかなー」と考えていたところ、次の教材を見つけたことをきっかけに、正式に React の学習を始めることにしました。

3.4 【とらゼミ】トラハックのエンジニア学習講座

image.png

現役の React エンジニアである トラハックさん ( @torahack_ )が、Youtube上で公開している講座で、Reactについて基礎の基礎から学ぶことができます。

動画チャンネルURL: https://www.youtube.com/user/1492tiger

こちらの教材の特長は、

  • Reactの基礎の基礎から体系的に学べる( Progate の JavaScript 講座完了が受講目安)
  • 動画によるハンズオン形式
  • 教材範囲にモダンなフロントエンドの開発手法を含む( Redux 等)
  • 動画のほぼ全てがYoutube上でなぜか無料公開されている

特に最後については完全にバグとしか思えない点で、Udemyなどで有料販売されていても動画講座と比べても遜色ないクオリティだと思います。

動画教材にありがちな「準備した原稿丸読み」のような堅い口調ではなく、フランクな若手予備校教師の授業(?)のような語り口のため、硬い喋りが苦手な人にもお勧めできます。私は復習のために、一度見た動画を耳だけで聞き返したりして、記憶の定着を図りました。

講座はいくつかのシリーズに分かれており、私が視聴をしたのは、

1.『日本一わかりやすいReact入門』シリーズ
2. 『日本一わかりやすいReact入門【実践編】』シリーズ
3. 『日本一わかりやすいReact-Redux入門』シリーズ

の3シリーズです。

最終的な成果物の技術スタックは、

  • create-react-app
  • Redux & redux-thunk
  • Material-UI
  • Firebase: Google が提供する mBaaS。バックエンド+インフラを手軽にセットアップできる

です。

※ 私のGithubリポジトリ: https://github.com/ddpmntcpbr/react-ec-app

こちらの動画については、学習備忘録記事をQiitaに投稿しております。よろしければこちらもご参考下さい。

参考ページ: 『日本一わかりやすいReact入門【実践編】#1~5 学習備忘録

本学習講座を全て受講するためには、有料コミュニティ『とらゼミ』への加入が必要になりますが、筆者は無料公開範囲の動画で必要な知識は十分に身に付いたと感じたため、加入はしておりません。(代わりの記事として書くことで、宣伝として少しでもお役に立てればと思っています笑)

さて、ここまででフロント側も自力で開発ができる基礎が身に付きました。これくらいの時期に並行してアプリのコンセプトが決定していましたので、いよいよポートフォリオ作成に取り掛かり始めました。

しかし、開発を始めるといくつも壁が出てきます。基本的にはググりながらの解決をしていきましたが、どうしても解決できないエラーにもぶち当たりました。特に、

  • ReactとRailsの繋ぎ合わせ
  • AWSでのアプリの公開方法
  • その他インフラ知識全般

あたりが、個人的な難所でした。その過程で頼らせてもらったのが、次のメンターサービスです。

3.5 TechTrain

image.png

有名企業のエンジニアから実務を学べるオンラインコミュニティ です。

URL: https://techbowl.co.jp/techtrain

特長を列挙すると、

  • 現役エンジニアであるメンターさんと、1 on 1でのオンライン面談が可能
  • メンターの方々の技術領域は多種多様
  • 全てのメンターと面談が可能で、技術トピックに応じて切り替えることが可能
  • 面談はこちらからのタイミングで入れることができる
  • なぜか全て無料で利用できる

はっきり言います。これだけのことができて完全無料なのは完全にバグです。これからエンジニア就職を目指しているU30の学生・社会人は、全員登録した方がいいレベルです

TechTrain の中ではいくつかの Mission が設けられており、それをメンターと一緒に取り組んでいくことで知識を習得していく、ということが可能です。 Mission は実際のIT企業とのコラボで作成されており、中には「Missionをクリアできた人は一次面接をスキップできる」のような特典もついていたりします。

ただ私は Misson には取り組まず、あくまでの個人開発のサポートとして利用させてもらっていました。基本的には自身の既存知識とググり力でPF作成を進めつつ、どうしても解決できない課題が出てきたときにピンポイントで面談予約を入れる、というイメージで、個々人の利用したい形式/ペースで利用できる点も大変ありがたかったです。

異なる技術領域を持ったエンジニアの方々全員と面談をするが可能なため、Rails, React, AWSそれぞれで、別のメンターの方に質問をさせてもらっていました。

特に自力での解決が難しかったのがAWS周りの本番環境構築で、本サービス無しでは乗り越えられなかったと思います。

AWSのことをAWS現役社員に無料で聞けるサービスと表現すれば、このサービスのやばさが伝わるかと思います。

最終的には、自身のググり力 + TechTrain で都度メンターを利用、を繰り返すことで、無事アプリを完成させることができました!

3.6 番外編

上記以外で役に立ったものについて、ざっくばらんに紹介します。

Udemy 『Git:はじめてのGitとGitHub』

無料で Git の基礎を学べる講座です。「Gitよう分からん!」って人は、まずこれから触れてみましょう

『キタミ式イラストIT塾 基本情報技術者』

基本情報処理の定番本です。コンピューターサイエンス領域の基礎知識が体系的に学べます。イラストが豊富であり、文章表現も柔らかいので初心者にも優しいです。資格自体の取る/取らないに関わらず一読をオススメします。

『米国AI開発者がゼロから教えるDocker講座』

Dockerについて一から学べる動画教材です。作者様はデータサイエンス領域の方ですが、Webアプリ開発を目的とした人であっても問題ありません(実際に、講座後半では、docker-composeを利用したRailsコンテナの構築まで扱っています)

非常にボリューミーな内容にも関わらず、Udemy講座の中ではかなり良心的な価格設定です。

『【AWS 入門】EC2とDockerでHello Worldしよう』

AWSについて何にも分からない状態から、「nginxだけのシンプルなコンテナアプリを動かす」ところまで、ハンズオン形式で学習ができます。

AWSのとっつきにくさは、「①インフラの概念が分からない」「②専門用語が分からない」に集約されると思います。まずは手を動かしながら、AWSでアプリをデプロイ流れを全体像で掴むことができます。

3.7 アプリの改善点

一通りアプリを完成させてみて、初めて見えてくる改善点が多くありましたので、合わせて列挙します。

AWSサーバー代高すぎ!!!

スケーラビリティの高い中・大規模向けインフラ構成になっているため、サーバー代がめっちゃ高い笑

長く公開するためには、どこかのタイミングで無料サーバーへ移管する必要があるかなと思います。Heroku の無料枠で上手にやりくりできれば、解決できるかもしれないです。

フロントエンド は Next.js + Typescriptで実装したい

Next.js はレンダリングのタイミングを制御できるので、OGP情報の保持が簡単に実現できます。

また、それ以外でも、

  • ルーティング設定が簡単
  • パフォーマンスをよくするような機能も豊富
  • Typescriptの導入が用意

というメリットもあり、とても気になっているフレームワークです。次、全く同じアプリを開発するとするのであれば、絶対に採用したい技術です。

デザインがあやしい気がする・・・?

アプリを開発して気づいたのは、アプリにおけるデザインの重要です。

これを思った理由は単純で、開発途中で「なんか自分のアプリ、イケてなくない?」と感じたからです笑

Webアプリにおけるデザインは、単なるお洒落さに関するものだけでは決してありません。デザインは、ユーザーにとって必要な情報を適切に配置することであり、ユーザーの価値提供のための最前線領域です

ユーザー側から価値提供の流れ(バリューチェーンと表現するのでしょうか)をざっっっくり並べると、

ユーザー -> UI/UXデザイン -> フロントエンド -> バックエンド -> インフラ

のようになっていると思っています。「エンジニアになろう!」と意気込んで後ろ3つについてはそこそこ勉強してきましたが、デザイン領域については開発初期は完全素人の状態で、途中までは勘でやっていました。。。

一応、付け焼き刃程度ではありますが、デザインの名著である『ノンデザイナーズ・デザインブック』に目を通し、途中からは意識できる範囲ではデザインのことを意識して、フロントを実装しました。

うまく取り込めているかは分かりませんが、少なくとも「デザインはセンスではなく論理」であることが学べただけでも、よい勉強になりました。こちらの書籍も、転職用PF作成者にオススメしておきます。

4. さいごに

以上、大変長い記事でしたが、最後まで読んでいただきありがとうございました。タイトルでは「学習ロードマップ」と銘打っておきながら、私自身の思考プロセスや価値観についても多く書かせてもらいました。

「エンジニアになりたい!」と思い立ってから、学習自体はほぼ一人で淡々と進めてきました。しかし、ほぼ独学でここまで学習を進めることができたのは、多くの先輩エンジニアの方々が様々な情報をインターネットに投稿し、それをオープンに取得できる環境にあったからだと思っております。

それであれば、次は自分自身も。他の駆け出しエンジニアの方々の助けになるような情報を発信できれば、と思い、この記事を書くこととしました。

もし、参考になったという方がいましたら、せひLGTM、ストック、twitterでのシェアお願いします!

また、私自身もtwitterをやっておりますので、気軽にフォローしてもらえるとうれしいです(^^)

よろしくお願いします!

Twitter: https://twitter.com/ddpmntcpbr
Github: https://github.com/ddpmntcpbr/rails_react_docker

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

忙しい人のためのDocker入門

とりあえずDockerって何?と思った人のためのまとめ

Dockerとは

一言でまとめると

ざっくりというと「仮想環境構築のためのツール」。

Dockerのメリット

1、要するに開発環境の構築&破棄が簡単になる。
2、環境による違いをなくせる。
3、クラスタ構成を作るのも楽。

こちらが詳しかった(https://knowledge.sakura.ad.jp/13265/

コード化されたファイルを共有することで、どこでも誰でも同じ環境が作れる。
作成した環境を配布しやすい。
スクラップ&ビルドが容易にできる。
例えば、開発環境(Windows上)では動いていたけどLinuxで動かなかった、といったケースも、開発工程からDockerを活用していくことで防ぎやすくなります。そして、開発工程の中で使っていた環境をそのまま本番環境に持っていくことも可能なため、環境差分が少なく、環境による問題を減らすことができます。作成したDockerイメージを他の人にも渡して使ってもらうことで、各自の環境のバージョンずれ防止や、開発環境準備の短縮化にもつながります。開発環境の準備で、説明不足や手順ミスで、丸一日かかったとなってしまうのはもったいないですよね。私自身も、開発環境からDockerを使っていて、新規メンバ参画時のコスト削減や、環境依存問題を減らせて、役立っています。また、クラスタ構成を構築する場合も、Dockerイメージがあれば、それを起動する名前(コンテナ名)などを変えるだけで、
複数の環境(コンテナ)を起動できるので、一から手順に沿って環境を作る作業もなくなり、クラスタ構成を構築するのも容易になります。これは、コンテナを管理するオーケストレーションツールを使うことで、より運用が楽になります。

Dockerを導入する基準は? Dockerのデメリットは?

こちらが詳しい。https://qiita.com/taishin/items/e1e7153cecb3ffd44a54
要するにインフラや開発サイクルや運用のことまで考えて導入すべきと思われる。
大規模チームで常にリリースする事業会社なら必須だろうが、少人数で小規模な受託開発するならメリットは無さそう。
(ちなみに前々職では意味なかった

Dockerで環境を作る流れ

1,Dockerレジストリ(DockerHub)からDockerイメージ(環境に必要なソフトウェアのことPHP,Apache、MySQLなど)を取得。
2,DockerイメージをDockerコンテナ(仮想環境のこと)として動かす。

DockerでPHPを環境を動かす

こちらが詳しい。https://qiita.com/nemui_/items/f911be7ffa4f29293fd5

DockerでLaravelの開発環境を作る

Laravelの場合はLaradockを使用するらしい。
https://qiita.com/J_Shell/items/695a30fd38444d065ae5

Dockerのトラブルシューティング

コンテナ間での通信やイメージに関するトラブルが多い模様。

https://qiita.com/ft0220/items/2522e2d056eb2b289dc1

https://qiita.com/hatai/items/6375c930488f34d15776

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JetPackでDockerコンテナが立ち上がらない際の対処法

問題

JetsonでJetPackを使ってTegraのコンテナを立ち上げる際に以下のようなエラーが出ることがある.

$ docker run --runtime nvidia -it nvcr.io/nvidia/l4t-base:r32.4.4
...
OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"process_linux.go:432: running prestart hook 1 caused \\\"error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: initialization error: driver error: failed to process request\\\\n\\\"\"": unknown

大抵は,以下が原因のことが多い.

  • NVIDIAが用意しているTegraのコンテナを使っていない
    nvidia/cuda:10.1-base-ubuntu18.04を使ってたり
  • インストールされているJetPackと一致しないTegraのコンテナを使用している
    ここからTegraのコンテナの一覧は確認できる
    以下でJetPackのバージョンは確認できる
    $ cat /etc/nv_tegra_release

これで解決しなかったケースがあったので,備忘録的に記載.

解決

JetPackのバージョンとTegraのコンテナのバージョンが一致しているが,エラーが出た.
原因としては,JetPackにはnvidia-docker2が元から入っているが,誤って更新してしまったことにある.
(Ubuntuと同じようにnvidia-docker2をインストールした)

ので,以下のコマンドで再インストール.

$ sudo apt remove nvidia-docker2
$ sudo apt autoremove
$ sudo apt install nvidia-docker2

これで無事Tegraの機能をもったコンテナを立ち上げることができた.

まとめ

このエラーに関しては,NVIDIAのフォーラムでも議題にあがっていることが多い印象.
最終的にはJetPackを再インストールした,という解決方法が多い.
が,それをできないケースも存在する.
(NXやAGXのチップが組み込まれているベンダーのボードを使っている際など)

このケースにはまる人はあまりいないかと思いましたが,同じことをしてしまった人のためにも情報を残しておきます.
ご参考までに.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む