diff --git a/SUMMARY.md b/SUMMARY.md index c700a4d..92f3884 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -5,4 +5,9 @@ * [資料を追加するには](docs/misc/wiki-usage/how-to-add-post.md) * [エディタを選ぼう](docs/lecture/select-editor/select-editor.md) * [JavaScript(ES6)入門](docs/lecture/js-getting-started.md) +* [Docker](docs/lecture/introducing-docker/0-index.md) + * [Dockerとは?](docs/lecture/introducing-docker/1-what-is-docker.md) + * [Dockerを使う](docs/lecture/introducing-docker/2-use-docker.md) + * [Dockerの概念](docs/lecture/introducing-docker/3-docker-concepts.md) + * [Dockerまとめ・参考文献](docs/lecture/introducing-docker/4-conclusion.md) diff --git a/book.json b/book.json index 2827682..1be58be 100644 --- a/book.json +++ b/book.json @@ -1,3 +1,4 @@ { - "language": "ja" + "language": "ja", + "plugins": ["hints"] } diff --git a/docs/lecture/introducing-docker/0-index.md b/docs/lecture/introducing-docker/0-index.md new file mode 100644 index 0000000..0c4ceb6 --- /dev/null +++ b/docs/lecture/introducing-docker/0-index.md @@ -0,0 +1,45 @@ +# Docker + +- Author: [coord.e](https://twitter.com/coord_e) + +## この記事について + +ここでは、[Docker](https://www.docker.com/)というソフトウェアについて + +- 何をするものか +- 導入の利点 +- 各種概念(イメージ、コンテナなど)について +- 使用方法 + +について解説する。なおここでは以下の点には触れないため、各自[参考文献](./4-conclusion.html#参考文献--further-reading)を別途参照されたし。 + +- Docker内部の仕組み(cgroups、コンテナランタイムなど) +- 発展的な利用(マルチアーキテクチャ、マルチステージビルドなど) +- インフラに組み込んだ活用 + +### 対象読者 + +- 自分の開発を効率化するためにDockerを使いたい人 +- Dockerについて聞いたことがあるが、なんだかわからないか使えるようになりたい人 +- SakutenDevでインフラを担当する人 +- など + +なお、この記事は読者としてある程度GNU/Linuxの扱いに慣れている人を想定している(コマンドライン操作、`/usr/local`などのファイル構造など)。知らないと読めないわけでもないが、わかりにくい点や伝わらない表現があるかもしれない。違和感を感じたらDiscordなどで気軽に質問してほしい。 + +## 用語について + +一般的に様々な意味で使用される用語について、この記事内では特に以下の意味合いで使用している。 + +- 環境: ソフトウェアを実行する際のファイルやプロセスの状態 +- ソフトウェア: 主にユーザーと直接のインタラクションなしで動くようなソフトウェア([MySQL](https://www.mysql.com/jp/)、[nginx](https://nginx.org/ja/)など) +- ライブラリ: 共有ライブラリ。([glibc](https://www.gnu.org/s/libc/)など) + + +## 表記について + +- `$ command`: $から始まるコードブロックは、コマンドラインを示している。Windowsならcmd.exeやpowershell、macOSならTerminal.appやiTerm2、GNU/Linuxなら好きなターミナルで、`$`から後の部分を打ち込む。 +- `< something >`: そのまま入力するのではなく、適宜読み替えてほしい + +## 次 + +[Dockerとは?](1-what-is-docker.md) diff --git a/docs/lecture/introducing-docker/1-what-is-docker.md b/docs/lecture/introducing-docker/1-what-is-docker.md new file mode 100644 index 0000000..9560ee0 --- /dev/null +++ b/docs/lecture/introducing-docker/1-what-is-docker.md @@ -0,0 +1,62 @@ +## Dockerとは? + +> Docker(ドッカー)はコンテナ型の仮想化環境を提供するオープンソースソフトウェアである。 + +[Docker - Wikipedia](https://ja.wikipedia.org/wiki/Docker) + +意味がわからないので噛み砕いて説明する(Wikipediaにマウントを取ろうとするオタクなので) + +## 例として考えるシステム + +ここでは例として、以下のようなシステムを動かす状況を考える。 + +1. ソフトウェアA: ライブラリBのバージョン1.0以下とライブラリCのバージョン3.0以上が必要 +2. ソフトウェアD: ライブラリBのバージョン2.0以上が必要 +3. ソフトウェアE: ソフトウェアAとソフトウェアCと通信する必要がある + +(以下、このシステムを「システムS」と呼ぶことにする) + +{% hint style='info' %} +具体的に考えたければ、 + +- システムS → Webアプリケーションのバックエンド +- ソフトウェアA → データベース +- ライブラリB → ネットワーク処理ライブラリ +- ライブラリC → ファイル操作ライブラリ +- ソフトウェアD → サーバーソフト +- ソフトウェアE → 管理コントロールパネルアプリ + +と置き換えるとイメージが湧きやすいと思う。 +{% endhint %} + +## 何が嬉しいのか + +Dockerによってもたらされることの本質は、「環境を共有できること」で(あると私は考えてい)る。 + +何かソフトウェアを動かそうとした時に、環境構築に悩まされたことは誰しもある経験だと思う。 +環境構築が必要なのは、本質的には「ソフトウェアが動作するために必要な要件を実行環境に課しているから」であると言える。例えばシステムSで言えば、ソフトウェアDは「ライブラリBのバージョン2.0以上が存在している」という要件をを環境に課している。そのため、ソフトウェアDを動作させるためにはまずライブラリBのバージョン2.0以上を環境に導入して、その要件を満たす必要がある。 +しかし、(ライブラリ1つ程度ならまだしも)要件が複雑になっていくにつれて、動作させるための正確な環境を用意するのは難しくなってくる。システムSで言えば、ソフトウェアAがその一例である。多くの人がそのソフトウェアを使用する場合、その全員に同じ環境を用意してもらうのが骨の折れる作業であることは容易に想像がつくだろう。さらに特定の条件の環境でのみ発生するバグがあった場合、それを複数の開発者が再現させるのはさらに至難の技になる。 + +この問題(環境に対する動作要件が複雑だと困る、ということ)に対し、ソフトウェア開発者たちは様々なアプローチを行ってきた。例えば最近のパッケージマネージャは"lockfile"という、ソフトウェア間の依存関係を正確に記述しておくファイルを生成することが多くなっている([package-lock.json](https://docs.npmjs.com/files/package-lock.json), [yarn.lock](https://yarnpkg.com/lang/ja/docs/yarn-lock/), [Cargo.lock](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html)など)。この手法では、全てのユーザーが簡単なコマンドで(そのパッケージマネージャが管理する範囲内で)同じ環境を用意できるようになっている。 + +しかし、それでもこのアプローチ(lockfile)はそのパッケージマネージャが扱う範囲内でしか問題を解決してくれない。システムの深い部分 -ライブラリが依存しているCのライブラリなど- は、依然としてユーザーごとの環境に依存してしまっているため、ある程度は先述の問題が避けられなくなってしまう。 + +ここで登場するのがDockerだ。Dockerを使うと、「環境それ自体」を丸ごと配布(共有)できる。システムSで例えるならば、ソフトウェアAを配布する際に、ソフトウェアAの動作に必要なライブラリBとライブラリCを含んだ環境を配布するということだ。ユーザーはそれを使って、意図された環境で確実にソフトウェアAを動作させることができるのである。また利用者全員に同じ環境を配布しているので、バグの再現も容易だ。 + +別の言い方をすると、例えばソフトウェアAが「Ubuntu 18.04にパッケージXを入れた環境」で動作確認ができている場合、「Ubuntu 18.04にパッケージXを入れた環境」をそのままユーザーに配布すればみんな同じ環境で実行できるよね、というなかなか強引な考えなわけだ。とはいえ、Dockerのこのアプローチは世間で広く認められ、非常に広い分野で活用されている。 + +## VirtualBox, Vagrant, VMwareなどとの違い + +技術に詳しい読者なら、VirtualBoxなどのイメージを配布すればいいではないかと思うかもしれない。しかしご存知の通り、これらハイパーバイザ型仮想化ソフトウェアで使用するイメージは巨大で、配布するのは一苦労だ(数GBのファイルを不特定多数に共有するのは大変でしょう)。さらにOSを丸ごと仮想化しているため、仮想環境の起動/終了に非常に時間がかかる。内部ではパソコンを起動/終了するのと同じことをシミュレートしているわけなので、これは避けられないコストだ。 + +Dockerがこれらの仮想化ソフトウェアと違う点は、OS(正確にはカーネル)をホスト環境と共有している点だ。これによってイメージを軽量に保つことができ([Ubuntu 18.10は29MB](https://hub.docker.com/_/ubuntu?tab=tags))、さらに起動/終了も高速に行うことができる。 + +## 不変性/再現性 + +Webアプリケーションなどの複雑なシステムでは、環境の一部を変更しただけでシステム全体の障害につながるということが簡単に起こりうる。Dockerの用意する「環境」は、それ自体不変のもので、変更を加えても容易に以前の状態に戻すことができる。これにより障害に対する対応が簡単になったり、開発の際にトライアンドエラーで試すといったような際の効率が圧倒的に上がったりする。(この辺りは試した方がよくわかると思うので、今は「ふーんそうなんだ」程度に思ってもらえれば構わない) + +## 次 + +次章では、実際に手を動かしながらこれらの利点について体験してもらうと共に、Dockerを構成する基本概念について説明する。 + +[Dockerを使う](2-use-docker.md) diff --git a/docs/lecture/introducing-docker/2-use-docker.md b/docs/lecture/introducing-docker/2-use-docker.md new file mode 100644 index 0000000..d25e199 --- /dev/null +++ b/docs/lecture/introducing-docker/2-use-docker.md @@ -0,0 +1,113 @@ +# Dockerを使う + +さて、長々しい説明も終わったので実際にDockerを使っていこう。 + +## Dockerのエディション(Edition)について + +- [Docker Enterprise Edition (Docker EE)](https://docs.docker.com/ee/) +- [Docker Community Edition (Docker CE)](https://docs.docker.com/install/) + +の2エディションが存在している。EEは企業向けのものなので、私たちが個人で使う分には基本的にDocker CEを使うことになるだろう。 + +Docker CEは無料で利用できる。 + +## Dockerをインストールする + +インストール方法は本当によく変わるので、英語が読める人は[公式ドキュメント](https://docs.docker.com/install/)を読むのがいいと思う。 + +{% hint style='info' %} +あまり私の所有していないプラットフォームでのインストール方法については自信がないので、あえて抽象的な説明にとどめておく。ごめんなさい。わからなかったら気軽にDiscordなどで質問してください。 +{% endhint %} + +### macOSの人 + +1. [ここ](https://hub.docker.com/editions/community/docker-ce-desktop-mac)から、`Docker.dmg`をダウンロードし、中に入っているappをインストールする。 +1.1. (なおHomebrew Caskを使っている人は`brew cask install docker`で入る) +2. `Docker.app`を起動し、指示に従う。(パスワードを聞かれたりします) + +### Windowsの人 + +Microsoft Windows 10 64-bitのProfessionalまたはEnterpriseが必要。 + +1. [ここ](https://hub.docker.com/editions/community/docker-ce-desktop-windows)からインストーラをダウンロードする。 +2. インストーラを実行し、指示に従う。 +3. インストールが完了したら、`Docker for Windows`を起動し、指示に従う。 + +なお、Windows 10 64-bit ProfessionalまたはEnterpriseではないWindows(Windows 10 Homeなど)では、[Docker Toolbox](https://docs.docker.com/toolbox/overview/)を使うことでDockerを使用することができる。しかし、個人的には無料のGNU/Linuxに移行するか新しいWindowsをインストールすることをお勧めする。 + +### GNU/Linuxの人 + +[CentOS](https://docs.docker.com/install/linux/docker-ce/centos/)、[Debian](https://docs.docker.com/install/linux/docker-ce/debian/)、[Fedora](https://docs.docker.com/install/linux/docker-ce/fedora/)、[Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/)向けのインストールガイドが公式にあるのでそれを見て、インストールする。 + +(全部書けないです、ごめんなさい、わからなかったらぜひ質問してください) + +## Dockerを使ってみる (Hello World) + +```shell +$ docker -v +``` + +バージョンが出てきたと思う。 + +{% hint style='tip' %} +GNU/Linuxユーザーで権限がどうとか言われた場合は[これをみて](https://docs.docker.com/install/linux/linux-postinstall/) +{% endhint %} + +ではいよいよHello Worldだ。いざ + +```shell +$ docker run hello-world +``` + +なんか色々英語で出てきたと思う。正常に実行されたならば、以下のようなメッセージが表示されたはずだ。 + +``` +Hello from Docker! +This message shows that your installation appears to be working correctly. + +To generate this message, Docker took the following steps: + 1. The Docker client contacted the Docker daemon. + 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. + (amd64) + 3. The Docker daemon created a new container from that image which runs the + executable that produces the output you are currently reading. + 4. The Docker daemon streamed that output to the Docker client, which sent it + to your terminal. + +To try something more ambitious, you can run an Ubuntu container with: + $ docker run -it ubuntu bash + +Share images, automate workflows, and more with a free Docker ID: + https://hub.docker.com/ + +For more examples and ideas, visit: + https://docs.docker.com/get-started/ +``` + +🎉 + +## もうちょっと役に立つことをする + +下のコマンドを入力してほしい。 + +```shell +$ docker run -p 8080:80 nginx +``` + +なんだかダウンロードが始まるので、しばらく待つ。 + +下のようなメッセージが表示されたら、ブラウザで[http://localhost:8080](http://localhost:8080)を開いてみよう。 + +``` +Status: Downloaded newer image for nginx:latest +``` + +ブラウザから、以下のようにnginxが起動している様子が見えると思う。 + +![nginx](assets/nginx.png) + +このように、なんの環境構築をすることもなく、Webサーバーが構築できてしまった。これが先に述べた「環境を共有する」ということだ。 + +## 次 + +[Dockerの概念](3-docker-concepts.md) diff --git a/docs/lecture/introducing-docker/3-docker-concepts.md b/docs/lecture/introducing-docker/3-docker-concepts.md new file mode 100644 index 0000000..952d40b --- /dev/null +++ b/docs/lecture/introducing-docker/3-docker-concepts.md @@ -0,0 +1,241 @@ +# Dockerの概念 + +さてここまで色々やってきたわけだが、ここでは今までやってきたことがどういった操作だったのかについて詳しく説明する。 + +とりわけ以下のようなDocker特有の概念について、実例を交えながら説明していく。 + +- [イメージ(image)](#イメージimage) +- [コンテナ(container)](#コンテナcontainer) +- [レジストリ(registry)](#レジストリregistry) + +## イメージ(image) + +イメージとは、今までこの記事で「環境」と呼んでいたものそのものだ。 +ソフトウェアを動作させるために必要なファイル群をまとめたもの、とも言える。 +なお一般的にイメージというと色々な意味があるので、「Dockerイメージ」と呼ばれることが多い。 + +最初に`docker run`を実行した時、なんだかダウンロードが始まったと思うが、あれはイメージをダウンロードしている。 +イメージはソフトウェアを実行するために必要なものを全て同梱しているため、容量が大きくなることが多い。(とはいえ普通は1GBを超えない程度だ) + +全てのイメージには一意なIDが振られている。イメージを変更することはできず(read only)、変更を加えるときは別のIDを持ったイメージを再度作成することになる。 + +また、IDに対して"タグ"をつけることができる。これは特定のIDにわかりやすく目印をつけるためのものである。 + +{% hint style='tip' %} +イメージIDはgitのコミットハッシュ、タグはgitのタグをイメージしてほしい +{% endhint %} + +### イメージを作ってみる + +イメージは`Dockerfile`という名前のファイルから、`docker image build`コマンドで作成することができる。 + +{% hint style='info' %} +わかりやすさのために`docker image build`を使用しているが、[`docker build`](https://docs.docker.com/engine/reference/commandline/build/)と同義である。 +{% endhint %} + +`Dockerfile`はいわば"イメージの設計図"で、そこにはどうやってイメージを作成するか、指示を書いていく。 + +ここでは例として、「[`cowsay`というジョークプログラム](https://ja.wikipedia.org/wiki/Cowsay)を実行して牛の絵を表示するDockerイメージ」を作ってみる。 + +結論からいうとこんな感じだ。 + +```dockerfile +FROM ubuntu:18.10 + +RUN apt-get update -y +RUN apt-get install -y cowsay + +CMD ["/usr/games/cowsay", "This is working!"] +``` + +一行づつ説明していく。 + +#### `FROM`コマンド + +これは、これからイメージを組み立てていく上で「既存のイメージをベースにするよ」というコマンドだ。 +ここでは`ubuntu:18.10`と書いてある。これは「`ubuntu`イメージの`18.10`というタグを使う」という意味だ。 + +#### `RUN`コマンド + +このコマンドに渡した文字列(ここでは`apt-get update -y`など)は、コマンドと解釈され、構築中のイメージの中で実行される[^1]。 + +ubuntuユーザーにとってはおなじみのコマンドで、`cowsay`をインストールしているのがわかると思う。 + +{% hint style='tip' %} +コマンドは`/bin/sh`で走るので、`&&`や`>`などは動く。 +{% endhint %} + +[^1]: 正確にはビルド時に生成される一時コンテナの中で実行される + +#### `CMD`コマンド + +`CMD`では、イメージが実行される時に[^2]実行するコマンドを指定する。 + +ここでは`/usr/games/cowsay`というプログラムに、`This is working!`という文字列を渡している。すなわちcowsayで「This is working!」と表示するコマンドというわけだ。 + +{% hint style='tip' %} +ご覧の通り配列形式で指定しているが、実はこれは下のように書いても動く。 + +```dockerfile +CMD /usr/bin/cowsay "This is working!" +``` + +だが、配列形式ではなくシェル形式(上の書き方)で書いた場合`/bin/sh`を経由して実行することになる。さらに引数の明示性の観点からも、`CMD`では配列形式が好まれる。 +{% endhint %} + +[^1]: 正確にはイメージから生成されたコンテナが実行される時 + +#### イメージをビルドする + +というわけで、イメージをビルドしよう。 + +`Dockerfile`が存在するディレクトリで、以下のコマンドを実行する。 + +```shell +$ docker image build . -t example-image +<色々ログが流れる> +Successfully tagged example-image:latest +``` + +[docker image build | Docker documentation](https://docs.docker.com/engine/reference/commandline/image_build/) + +これでイメージが生成できた。 + +なおここでは`-t`で名前として`example-image`を指定しているため、以降このイメージは`example-image`として参照できることになる。 + +実際にイメージが生成できているのか確認してみよう。 + +```shell +$ docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +example-image latest f839d43061a3 38 minutes ago 138MB +``` + +[docker image ls | Docker documentation](https://docs.docker.com/engine/reference/commandline/image_ls/) + +{% hint style='info' %} +わかりやすさのために`docker image ls`を使用しているが、[`docker images`](https://docs.docker.com/engine/reference/commandline/images/)と同義である。 +{% endhint %} + +このように、先ほど生成したイメージの情報が表示される。なおタグはデフォルトで`latest`になっている。 + +次はもう一つの重要な概念、"コンテナ"について説明する。 + +## コンテナ(container) + +コンテナは、実際にDockerを使ってソフトウェアを実行する際に作られる隔離環境のことだ。 +コンテナの中からはコンテナは独立したシステムであるように見える。実際コンテナはホストのシステムとはある程度隔離されており、例えば + +- ディレクトリ + - 例: ルート`/`が独立して存在している +- プロセス + - 例: PID0 (init)が独立して存在している +- ユーザー + - 例: ルートユーザー`root`が独立して存在している + +がホストから独立している。 + +{% hint style='tip' %} +他にも色々あるので気になる人は"linux namespace"や"cgroups"で検索 +{% endhint %} + + +これにより、(基本的に)コンテナ内部から外のシステムにはアクセスできないようになっている。(そもそも内部からは外の存在すらわからない) + +また、コンテナは揮発性を持つと言える。コンテナの中でファイルを変更することはできるが、コンテナの削除の際にその変更はなかったことになる。永続化するには、後述する方法でイメージにするしかない。 + +コンテナは2つの状態を持っている。「実行中」と「停止中」だ。 + +### コンテナを作成/実行してみる + +コンテナはイメージから作成する。 +ここでは先ほど作成した`example-image`からコンテナを作ってみる。次のコマンドを実行してみよう。 + +```shell +$ docker container create exmaple-image +<コンテナIDが出力される> +``` + +[docker container create | Docker documentation](https://docs.docker.com/engine/reference/commandline/container_create/) + +{% hint style='info' %} +わかりやすさのために`docker container create`を使用しているが、[`docker create`](https://docs.docker.com/engine/reference/commandline/create/)と同義である。 +{% endhint %} + +これで`example-image`からコンテナを作成できた。 + +`0fa275c5b6c0c983de67dfb4c2ea91fd8ec38365a9c9a99ae28307aefe189386`のような文字列が出力されたと思う。これが作成されたコンテナの"コンテナID"だ。 + +実際に作成できたのかどうか、以下のコマンドで確かめよう。 + +```shell +$ docker container ls --all +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +0fa275c5b6c0 example-image "/usr/games/cowsay '…" 18 seconds ago Created dreamy_bardeen +``` + +[docker container ls | Docker documentation](https://docs.docker.com/engine/reference/commandline/container_ls/) + +{% hint style='info' %} +わかりやすさのために`docker container ls`を使用しているが、[`docker ps`](https://docs.docker.com/engine/reference/commandline/ps/)と同義である。 +{% endhint %} + +{% hint style='tip' %} +`NAMES`に書いてある文字列(ここでは`dreamy_bardeen`)は、コンテナの"名前"である。コンテナIDは覚えにくい(それはそう!)ため、覚えやすい名前がコンテナ作成時に自動的に付与される。 +名前はコンテナIDの代わりに使うことができる。コンテナ作成時に自分で名前をつけることもできる。(`--name`オプション) +{% endhint %} + +では作成したコンテナを実行しよう。 + +```shell +$ docker container start --attach <コンテナID/名前> + __________________ +< This is working! > + ------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +このようにイメージ作成時に`CMD`に指定したコマンドが実行されたことが確認できると思う。 + +{% hint style='tip' %} +`--attach`オプションは、stdin/stdoutをホストのものと繋げるためにつけている。 +{% endhint %} + +## イメージとコンテナの関係 + +このようにコンテナはイメージから作るわけだが、実はイメージはコンテナから作ることもできる。[^3] + +[^3]: 注意深くログを見ればわかるが、`docker image build`も、結局は一時コンテナを作ってイメージを再生成しているのだ + +とはいえ手動でコンテナからイメージを作ることはほとんどないので、とりあえず現時点では + +- イメージ: 永続的で不変な環境。配布できる。ファイルのようなもの +- コンテナ: 揮発的な環境。実行できる。プロセスとメモリのようなもの + +と思ってもらえればOKだ。 + +### `docker run` + +前々から出てきている`docker run`コマンド、これは「イメージからコンテナを作成し、それを実行」ということをやっている。 + +すなわち`docker container create`と`docker container start`を一緒にやってくれている。便利なのでよく使われる。 + +## レジストリ(registry) + +レジストリは、Dockerイメージを保持し、共有するシステムだ。 +一般的にインターネット上にサービスとして存在し、そこと通信することで利用する。 + +今まで使ってきた`nginx`や`ubuntu`のイメージは全てレジストリ上にあり、そこから取得していたのだ。(だからダウンロードが必要だった) + +デフォルトのレジストリは[Docker Hub](https://hub.docker.com/)であり、特に指定しない場合はここが使われる。 +他にも[quay.io](https://quay.io/)のようなレジストリサービスが存在しているほか、自分でレジストリを立てることもできる。 + +`docker image push`、`docker image pull`でそれぞれレジストリにイメージをアップロード、ダウンロードできるが、ここでは扱わない。詳しくは参考文献を参照してほしい。 + +## 次 + +[まとめ](4-conclusion.md) diff --git a/docs/lecture/introducing-docker/4-conclusion.md b/docs/lecture/introducing-docker/4-conclusion.md new file mode 100644 index 0000000..59109fc --- /dev/null +++ b/docs/lecture/introducing-docker/4-conclusion.md @@ -0,0 +1,17 @@ +# まとめ + +この記事では、Dockerの利点と使用方法、重要な概念について説明した。 + +現時点ではまだDockerの恩恵を感じきれていないと思う。そこで、この記事を読んでくれた皆さんにはこれから積極的にDockerを使ってもらいたいと思っている。 + +またSakutenDevでは、開発環境・デプロイ環境どちらでも大いにDockerを活用している。是非これを機にコードをのぞいてみてほしい。 + +長くなってしまいましたが、最後まで読んでいただきありがとうございます。 + +## 参考文献 / further reading + +- [Docker Documentation](https://docs.docker.com/) +- [Docker ドキュメント日本語化プロジェクト](http://docs.docker.jp/) +- [Dockerfile reference | Docker documentation](https://docs.docker.com/engine/reference/builder/) +- [docker container / image コマンド新旧比較 - Qiita](https://qiita.com/zembutsu/items/6e1ad18f0d548ce6c266) +- [Docker内部で利用されているLinuxカーネルの機能 (namespace/cgroups)](https://qiita.com/wellflat/items/7d62f2a63e9fcddb31cc) diff --git a/docs/lecture/introducing-docker/assets/nginx.png b/docs/lecture/introducing-docker/assets/nginx.png new file mode 100644 index 0000000..2a73346 Binary files /dev/null and b/docs/lecture/introducing-docker/assets/nginx.png differ diff --git a/package.json b/package.json index 42f4868..132436b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "gitbook-cli": "^2.3.2" }, "scripts": { - "start": "yarn gitbook serve" + "start": "yarn gitbook serve", + "prepublish": "gitbook install" } }