- 投稿日:2021-02-21T23:28:02+09:00
docker --init (Tini) が PID 1 問題を解決している様子を調べてみた
はじめに
docker --initは PID 1 として動作させることを想定してないプロセスを適切に処理するために、軽量の init を PID 1 で実行する Docker 1.13 で追加されたオプションです。内部的には Tini が使用されています。Tini の大きな役目は次の2つです。
- デフォルトのシグナルハンドラを機能させる
- ゾンビプロセスを刈り取る(reaping)
この記事では Tini を使用しない場合にどのような問題が発生し、Tini を使用することでそれらが解決する様子を確認します。
準備
まず動作確認を行うためのファイルを準備します。作業用のディレクトリを作り以下のファイルを作成します。
DockerfileFROM 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^CDocker コンテナを起動したら以下のように
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 exitTini を使用した場合は
/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 exitedTini は一定間隔(0.5 秒?)で刈り取るべきプロセスがないかを確認し、対象となるプロセスがあれば刈り取ります。(
-vvvオプションを指定している場合は上記のReaped child with pid: '17'のようなログを出力を出力します。)補足
さて Tini の動作確認としてはここまでなのですが、検証中に気づいた点について補足します。
シェルもゾンビプロセスを刈り取ります
Dockerfile を次のように書き換えて Docker コンテナを起動してください。(Tini は使用しません)
DockerfileFROM 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.
参考
- 投稿日:2021-02-21T23:18:24+09:00
複数の形態素解析器と辞書を入れた Docker コンテナを作って Python で使う
はじめに
いくつかの形態素解析器(と辞書)を比較する機会があったので、まとめて動かせる環境を Docker コンテナにして Python で使えるようにしました。
やったこと
今回使ったのは、MeCab と spaCy と GiNZA の3つ、辞書は以下の通り MeCab 用の6つと spaCy 用の3つです。
- MeCab で使った辞書
- IPAdic
- UniDic(現代書き言葉版)
- JUMAN 辞書
- NAIST-jdic
- mecab-ipadic-NEologd
- mecab-unidic-NEologd
- spaCy で使った辞書
Docker コンテナを作る
これらをまとめて動かせる環境を Docker コンテナにできたら便利、というわけで、ネット上の情報1を参考にしながら、Ubuntu 20.04 の Docker イメージ をベースに必要なものをインストールする形で Dockerfile を書きました。
DockerfileFROM 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 : 複数 の 形態素 解析 エンジン を 切り替え て 使える コンテナ が 便利 ですおわりに
また形態素解析したくなったときには、即コンテナ化して使い始められます。
「dockerで動く mecab + python3 の環境を作る - Qiita」や「dockerでubuntu16+python3.6+mecab(neolog-ipadic)を構築する - メモ帳」などを参考にさせていただきました。ありがとうございます。 ↩
ネットワークなどの環境次第ですが、イメージの生成に数十分以上かかる場合もあると思います。また、生成されるイメージのサイズは 17GB ほどになります。 ↩
- 投稿日:2021-02-21T22:25:20+09:00
2/21~docker~
why~なぜdocker~
従来の仮想化技術はOS丸ごとイントールしていたが
how
コンテナ型で仮想化することで
what
素早く動作させることができる
dockerはコンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンソースソフトウェアあるいはオープンプラットフォームである。
OSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。
Dockerはコンテナ仮想化を核としたアプリケーションのためのオープンプラットフォームである。DockerエンジンによりDockerコンテナとして配備、実行できる。
Linux、Windows、Mac全て対応したDockerエンジンは開発・テスト・本番・デバッグなど様々な状況で用意かつ高速なアプリケーション配備、実行を可能にする。
メリット
一台のサーバー上に複数のOSを走らせる仮想技術は従来から存在していたがこれらはOSを丸ごとインストール必要があり、アプリケーションに必要のないサービスやファイルまで伴っていた。
アプリケーションとは関係のないライブラリやデータは仮想環境内で共有することが望ましく、これを実現するのがコンテナ型の仮想化である。
Dockerはアプリケーションとライブラリを同一のコンテナ内に固めてしまうので一度固めたコンテナは軽量であり移動が容易であり、比較的どの環境でも素早くアプリケーションを動作させることが可能である。
- 投稿日:2021-02-21T22:14:22+09:00
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
ご指摘などありましたらコメント欄によろしくお願いします。
- 投稿日:2021-02-21T21:59:38+09:00
初学者が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のトップページが表示されると思います。
ログインの情報はdocker-compose.ymlのpgadmin4のenvironmentに記述した内容を入力します。
サーバー(postgre)に接続
ログインが完了したら、右側のメニューからServersを右クリックし、Createにマウスポインターを合わせ、Server...を選択します。
Create-Serverウィンドウが表示されるので、GeneralタブのNameにpd-dockerと入力します。一応、docker-compose.ymlで記述したcontainer-nameと合わせていますが、必要ないかもしれません。
Connectionタブをクリックし、HostはPCのIPアドレス、Portは5432を入力します。Maintenance databaseとUsernameとPasswordは、docker-compose.ymlのenvironmentで設定した値を入力します。
Saveボタンをクリックし、問題がなければ接続が完了します。
注意点
冒頭にも書きましたが、ボリュームをマウントしていないのでコンテナがUpでなくなると(消すと?)、データベースも消えてしまうので運用する際は注意が必要です。
- 投稿日:2021-02-21T18:02:05+09:00
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 buildWindows
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
- 投稿日:2021-02-21T16:42:27+09:00
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_pgsqlAfter
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の拡張を入れる必要に迫られることは少なかった(ぶっちゃけ海外でもこういう人が多いっぽい)ので勉強になりました。
- 投稿日:2021-02-21T15:26:49+09:00
Dockerとはなにか
本記事の概要
この記事はDocker初学者の私が、Dockerの概要についてまとめた記事です。
学習に当たっては以下の書籍を参考にしました。コンテナ技術の概念から簡易的なWebアプリの構築等、実践的な内容まで含まれております。
また、DockerやKubernetesの設計や運用における勘所についても記載があり、勉強になる書籍でした。本記事で分かること
- コンテナ技術の概要
- Dockerとはなにか
コンテナ技術の概要
Dockerの説明に入る前に、そもそもコンテナとは何かについて説明します。
コンテナとは仮想化技術のうちの1つです。
コンテナ以外の仮想化技術には、ホストOS型(Virtual Box等)、ハイパーバイザー型(ESXi等)があります。図で表すとこうです。
コンテナ型
ホストOS型
ハイパーバイザー型
コンテナ型では仮想化ソフトウェアなしに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で構成されます。
dockerクライアントにて、コンテナの構築などを実行するためにはdockerデーモンと通信します。その通信をREST APIを通じて行います。Dockerが動く仕組み
dockerクライアントとdockerデーモンが通信することで動くわけなのですが、もう少し詳しく見てみます。
コンテナを構築するためにはイメージと呼ばれるテンプレートが必要です。例えば、Ubuntuの上にApacheをインストールしてWebサーバーを構築するとします。その際必要なUbuntuとApacheのイメージをレジストリと呼ばれるイメージの保管サーバからダウンロードし、コンテナを構築します。パブリックなレジストリとしてはDocker Hubがあり、多種多様なイメージが存在します。
プライベート環境にレジストリが必要な場合は、Docker Registryを使うといいでしょう。
- 投稿日:2021-02-21T14:13:23+09:00
【未経験PF / Rails / React / AWS / Docker / CircleCI】独学+メンターでここまで出来た!Web知識ゼロからモダンな技術アプリ開発までに利用した5つのサービス
0. はじめに
こんにちは!辻野(@ddpmtcpbr)と申します。
当記事は、「Webエンジニアへのキャリアチェンジを目指している開発未経験者が、モダンな技術を備えたアプリを開発するまでの学習過程」についてまとめたものです。
現在筆者は非IT系企業の社員として働いており、Web開発エンジニアとしての実務経験はありません。
そんな筆者がWebエンジニアとしてのキャリアチェンジをするためのポートフォリオとして、本アプリを開発しました。
学習開始から現時点までにおいて、プログラミングスクール等には通っておらず、学習はほぼ全て独学&一部メンターサービス利用の布陣で進めてきました。
独学中心でアプリ開発に挑戦したい、ポートフォリオを作成してWebエンジニアへのキャリアチェンジを進めていきたい、と考えている方々にとって、参考になればと思います。
最初に、今回私が開発したアプリの概要を紹介します。
アプリ名: 積読解消アプリ 「Yomukatsu!」
「あなたの積読解消をサポートします」をスローガンに掲げた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各項目の詳細は後述しています。
インフラ構成
モダンな技術を採用した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 技術スタック
再度、インフラ構成を載せます。
この内容について、ひとつひとつ解説します。
Back-end
Rails API+Nginxの組み合わせにしています。サーバーサイドフレームワークとしては他にも
Laravel,Django,Node.jsなどもあります。恐らく大体のことは、どれを選んでも実装・実現できる、と思うのですが、その中で今回 Rails を選んだ理由は、
- 採用している企業数が多い
- 日本語の教材が豊富なため学習のハードルが低い
- 国内コミュニティが発達しているため、インターネット上での日本語ドキュメントが豊富
最初の学習言語として 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.jsかVue.jsか、の二択になると思います。その中でもReact.jsを選んだ理由は、
- 自分が調べた範囲では、バックエンドに Rails を採用している企業群のうち、フロントに React を採用している企業の割合が高かった
- Vue.js よりも規約が厳格であり、初学者の自分であっても自然と可読性の高いコードを書くことができそう
- たまたま、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
皆大好き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チュートリアル
皆大好き(?) 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.jsやReact.jsといったJavaScriptフレームワークを使用するのが一般的。それに伴い、Railsは単独アプリとしてではなく、APIモードで開発する- テストフレームワークは、minitestではなく、
Rspecがデファクトスタンダード- 開発環境はPCローカルに構築する(
Vagrantで仮想マシンを構築するか、Dockerでコンテナ化するか)- アプリケーションのデプロイは、小規模であれば Heroku を使うこともあるが、企業が提供するような中・大規模なアプリケーションであれば、
AWSやGCPなどをよく用いられる次に習得すべきは、ここの技術領域であることが分かりました(個人的な話ですが、この辺りの時期からエンジニア採用ページに書かれている各技術がスタックが、どういった内容であるかが理解できるようになってきており、成長を実感していました)。
Railsチュートリアルを完走した方は、完走者向けのロードマップ紹介ページもありますので、まずはここを見てみるものよいかと思います。しかし私は、洗い出した上記項目をより体系的に学ぶことができるものがないかと考え、自分なりに色々と教材を探してみた結果、以下のサービスに辿りつきました。
3.3 Take off Rails
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 【とらゼミ】トラハックのエンジニア学習講座
現役の 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-appRedux & redux-thunkMaterial-UIFirebase: Google が提供する mBaaS。バックエンド+インフラを手軽にセットアップできるです。
※ 私のGithubリポジトリ: https://github.com/ddpmntcpbr/react-ec-app
こちらの動画については、学習備忘録記事をQiitaに投稿しております。よろしければこちらもご参考下さい。
参考ページ: 『日本一わかりやすいReact入門【実践編】#1~5 学習備忘録』
本学習講座を全て受講するためには、有料コミュニティ『とらゼミ』への加入が必要になりますが、筆者は無料公開範囲の動画で必要な知識は十分に身に付いたと感じたため、加入はしておりません。(代わりの記事として書くことで、宣伝として少しでもお役に立てればと思っています笑)
さて、ここまででフロント側も自力で開発ができる基礎が身に付きました。これくらいの時期に並行してアプリのコンセプトが決定していましたので、いよいよポートフォリオ作成に取り掛かり始めました。
しかし、開発を始めるといくつも壁が出てきます。基本的にはググりながらの解決をしていきましたが、どうしても解決できないエラーにもぶち当たりました。特に、
- ReactとRailsの繋ぎ合わせ
- AWSでのアプリの公開方法
- その他インフラ知識全般
あたりが、個人的な難所でした。その過程で頼らせてもらったのが、次のメンターサービスです。
3.5 TechTrain
有名企業のエンジニアから実務を学べるオンラインコミュニティです。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
- 投稿日:2021-02-21T14:13:23+09:00
【未経験】独学+メンターでここまで出来た!Web知識ゼロからモダンな技術アプリ開発までに利用した5つのサービス【Rails / React / AWS / Docker / CircleCI】
0. はじめに
こんにちは!辻野(@ddpmtcpbr)と申します。
当記事は、「Webエンジニアへのキャリアチェンジを目指している開発未経験者が、モダンな技術を備えたアプリを開発するまでの学習過程」についてまとめたものです。
現在筆者は非IT系企業の社員として働いており、Web開発エンジニアとしての実務経験はありません。
そんな筆者がWebエンジニアとしてのキャリアチェンジをするためのポートフォリオとして、本アプリを開発しました。
学習開始から現時点までにおいて、プログラミングスクール等には通っておらず、学習はほぼ全て独学&一部メンターサービス利用の布陣で進めてきました。
独学中心でアプリ開発に挑戦したい、ポートフォリオを作成してWebエンジニアへのキャリアチェンジを進めていきたい、と考えている方々にとって、参考になればと思います。
最初に、今回私が開発したアプリの概要を紹介します。
アプリ名: 積読解消アプリ 「Yomukatsu!」
「あなたの積読解消をサポートします」をスローガンに掲げた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各項目の詳細は後述しています。
インフラ構成
モダンな技術を採用した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 技術スタック
再度、インフラ構成を載せます。
この内容について、ひとつひとつ解説します。
Back-end
Rails API+Nginxの組み合わせにしています。サーバーサイドフレームワークとしては他にも
Laravel,Django,Node.jsなどもあります。恐らく大体のことは、どれを選んでも実装・実現できる、と思うのですが、その中で今回 Rails を選んだ理由は、
- 採用している企業数が多い
- 日本語の教材が豊富なため学習のハードルが低い
- 国内コミュニティが発達しているため、インターネット上での日本語ドキュメントが豊富
最初の学習言語として 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.jsかVue.jsか、の二択になると思います。その中でもReact.jsを選んだ理由は、
- 自分が調べた範囲では、バックエンドに Rails を採用している企業群のうち、フロントに React を採用している企業の割合が高かった
- Vue.js よりも規約が厳格であり、初学者の自分であっても自然と可読性の高いコードを書くことができそう
- たまたま、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
皆大好き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チュートリアル
皆大好き(?) 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.jsやReact.jsといったJavaScriptフレームワークを使用するのが一般的。それに伴い、Railsは単独アプリとしてではなく、APIモードで開発する- テストフレームワークは、minitestではなく、
Rspecがデファクトスタンダード- 開発環境はPCローカルに構築する(
Vagrantで仮想マシンを構築するか、Dockerでコンテナ化するか)- アプリケーションのデプロイは、小規模であれば Heroku を使うこともあるが、企業が提供するような中・大規模なアプリケーションであれば、
AWSやGCPなどをよく用いられる次に習得すべきは、ここの技術領域であることが分かりました(個人的な話ですが、この辺りの時期からエンジニア採用ページに書かれている各技術がスタックが、どういった内容であるかが理解できるようになってきており、成長を実感していました)。
Railsチュートリアルを完走した方は、完走者向けのロードマップ紹介ページもありますので、まずはここを見てみるものよいかと思います。しかし私は、洗い出した上記項目をより体系的に学ぶことができるものがないかと考え、自分なりに色々と教材を探してみた結果、以下のサービスに辿りつきました。
3.3 Take off Rails
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 【とらゼミ】トラハックのエンジニア学習講座
現役の 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-appRedux & redux-thunkMaterial-UIFirebase: Google が提供する mBaaS。バックエンド+インフラを手軽にセットアップできるです。
※ 私のGithubリポジトリ: https://github.com/ddpmntcpbr/react-ec-app
こちらの動画については、学習備忘録記事をQiitaに投稿しております。よろしければこちらもご参考下さい。
参考ページ: 『日本一わかりやすいReact入門【実践編】#1~5 学習備忘録』
本学習講座を全て受講するためには、有料コミュニティ『とらゼミ』への加入が必要になりますが、筆者は無料公開範囲の動画で必要な知識は十分に身に付いたと感じたため、加入はしておりません。(代わりの記事として書くことで、宣伝として少しでもお役に立てればと思っています笑)
さて、ここまででフロント側も自力で開発ができる基礎が身に付きました。これくらいの時期に並行してアプリのコンセプトが決定していましたので、いよいよポートフォリオ作成に取り掛かり始めました。
しかし、開発を始めるといくつも壁が出てきます。基本的にはググりながらの解決をしていきましたが、どうしても解決できないエラーにもぶち当たりました。特に、
- ReactとRailsの繋ぎ合わせ
- AWSでのアプリの公開方法
- その他インフラ知識全般
あたりが、個人的な難所でした。その過程で頼らせてもらったのが、次のメンターサービスです。
3.5 TechTrain
有名企業のエンジニアから実務を学べるオンラインコミュニティです。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
- 投稿日:2021-02-21T13:53:37+09:00
忙しい人のための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/695a30fd38444d065ae5Dockerのトラブルシューティング
コンテナ間での通信やイメージに関するトラブルが多い模様。
- 投稿日:2021-02-21T09:57:28+09:00
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のチップが組み込まれているベンダーのボードを使っている際など)このケースにはまる人はあまりいないかと思いましたが,同じことをしてしまった人のためにも情報を残しておきます.
ご参考までに.

















