## 1章: Docker概要
### p1-19: Dockerのインストール後の初期設定
[user01@ip-192-168-1-1 ~]$ systemctl status docker
p1-20:
[user01@ip-192-168-1-1 ~]$ sudo systemctl start docker
[user01@ip-192-168-1-1 ~]$ systemctl status docker [user01@ip-192-168-1-1 ~]$ grep docker /etc/group
[user01@ip-192-168-1-1 ~]$ sudo usermod -G docker user01
[user01@ip-192-168-1-1 ~]$ grep docker /etc/group
p1-21:再起動してグループに加入することを反映
[user01@ip-192-168-1-1 ~]$ id
[user01@ip-192-168-1-1 ~]$ sudo init 6
[user01@ip-192-168-1-1 ~]$ id
p1-22: インストールしたDockerの確認
[user01@ip-192-168-1-1 ~]$ docker –version
[user01@ip-192-168-1-1 ~]$ docker system info
[user01@ip-192-168-1-1 ~]$ docker version
## 2章: コンテナ・イメージの作成と管理
### p2-12: Docker Hubのイメージを検索とイメージのダウンロード
[user01@ip-192-168-1-1 ~]$ docker search centos
p2-13:
[user01@ip-192-168-1-1 ~]$ docker image ls
—
### p2-19: Dockerホストにダウンロードしたイメージからコンテナを作成
[user01@ip-192-168-1-1 ~]$ docker container run centos:latest echo “hoge hoge”
p2-20:
[root@3ed20b057e29 /]# ps -elf
[root@3ed20b057e29 /]# pwd
[root@3ed20b057e29 /]# ls
[root@3ed20b057e29 /]# touch file1
[root@3ed20b057e29 /]# ls
[root@3ed20b057e29 /]# exit
p2-21
[user01@ip-192-168-1-1 ~]$ docker container ls -a
p2-22:
[root@770fe8c0b749 /]# ls
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ docker container ls -a
—
### p2-24: デタッチドモードでのコンテナの起動とメインプロセスの標準出力の確認
[user01@ip-192-168-1-1 ~]$ docker container run centos:latest ping -c 15 127.0.0.1
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ docker container ls -a
p2-25:
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ docker container ls -a
[user01@ip-192-168-1-1 ~]$ docker container logs コンテナID
—
### p2-31: 端末をコンテナからデタッチ・アタッチ
[user01@ip-192-168-1-1 ~]$ docker container run -it centos:latest bash
[root@cd2c72fd9354 /]#
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container ls[user01@ip-192-168-1-1 ~]$ docker container attach コンテナID [root@cd2c72fd9354 /]# exit
### p2-32: Dockerホストのポートをコンテナのポートに割り当ててコンテナを作成
[user01@ip-192-168-1-1 ~]$ docker search httpd –filter=”is-official=true”
p2-33:
[user01@ip-192-168-1-1 ~]$ docker container run -d httpd:2.4
p2-34:
[user01@ip-192-168-1-1 ~]$ curl 172.17.0.X:80 #宛先のIPアドレスは実際にコンテナに設定されているIPアドレスを指定してください。
[user01@ip-192-168-1-2 ~]$ curl 172.17.0.2:80
→^Cでcurlコマンドを終了
p2-35:
※Server1の端末に移動
[user01@ip-192-168-1-1 ~]$ docker container run -d -p 8080:80 httpd:2.4
※Server2の端末に移動
[user01@ip-192-168-1-2 ~]$ curl -s 192.168.1.1:8080
—
### p2-37: コンテナ内でコマンドを実行し、プロセスを追加で作成
※Server1の端末に移動
[user01@ip-192-168-1-1 ~]$ docker container ls
root@30abb3887cd0:/usr/local/apache2# ls /proc
p2-38:
root@30abb3887cd0:/usr/local/apache2# more /proc/1/status
root@30abb3887cd0:/usr/local/apache2# more /proc/90番台のPID/status
root@30abb3887cd0:/usr/local/apache2# exit
[user01@ip-192-168-1-1 ~]$ docker container ls
—
### p2-41: コンテナの起動と停止
[user01@ip-192-168-1-1 ~]$ docker container run –name snow -it centos:latest bash
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container ls [user01@ip-192-168-1-1 ~]$ docker container stop snow [user01@ip-192-168-1-1 ~]$ docker container ls[user01@ip-192-168-1-1 ~]$ docker container ls -a
p2-42:
[user01@ip-192-168-1-1 ~]$ docker container start snow
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container rm snowp2-43:
[user01@ip-192-168-1-1 ~]$ docker container stop snow
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ docker container ls -a
[user01@ip-192-168-1-1 ~]$ docker container ls -a
—
### p2-48: アプリケーションのコンテナ化・配布のための独自イメージの作成
[user01@ip-192-168-1-1 ~]$ docker search AlmaLinux –filter=is-official=true
p2-49
[root@b08717596fab /]# dnf -y install nodejs procps
[root@b08717596fab /]# vi /app/emoji.js
const http = require(‘http’);
// 顔文字のリストを作成
const faces = [‘(@_@)’, ‘┐(`~`;)’, ‘(*^ω^*)’, ‘θ(^O^ )’];
// httpサーバーの作成
const server = http.createServer((req, res) => {
// ステータスコード200でレスポンスを送信
res.statusCode = 200;
// レスポンスのヘッダーを設定
res.setHeader(‘Content-Type’, ‘text/plain; charset=utf-8’);
// ランダムに顔文字を選択
const face = faces[Math.floor(Math.random() * faces.length)];
// 顔文字をレスポンスとして返す
res.end(face + ‘\n’);
});
// サーバーを起動
const port = 3000;
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
p2-50:
[root@b08717596fab /]# node /app/emoji.jsCtrl+P→Q
[user01@ip-192-168-1-1 ~]$ curl 192.168.1.1:8081[user01@ip-192-168-1-1 ~]$ curl 192.168.1.1:8081 [user01@ip-192-168-1-1 ~]$ docker image ls [user01@ip-192-168-1-1 ~]$ docker container commit emoji dockerintro数字/emoji:1.0 [user01@ip-192-168-1-1 ~]$ docker image ls
p2-51:
[user01@ip-192-168-1-1 ~]$ docker container run –name emoji2 -p 8082:3000 -d dockerintro数字/emoji:1.0 node /app/emoji.js
[user01@ip-192-168-1-1 ~]$ curl 192.168.1.1:8082
p2-52:
[user01@ip-192-168-1-1 ~]$ docker container exec emoji2 ps -elf
—
### p2-59: DockerHubへの独自イメージの保存
[user01@ip-192-168-1-1 ~]$ docker image ls
p2-60:
[user01@ip-192-168-1-1 ~]$ docker login
Username: dockerintro数字
Password: DockerIntro数字@
p2-62:
※Server2の端末に移動
[user01@ip-192-168-1-2 ~]$ docker container run –name emoji2 -p 8082:3000 -d dockerintro数字/emoji:1.0 node /app/emoji.js
## 3章: Dockerfile
### p3-21: Dockerfileでの独自イメージの作成
※Server1の端末に移動
[user01@ip-192-168-1-1 ~]$ cd emoji
[user01@ip-192-168-1-1 emoji]$ ls
const http = require(‘http’);
// 顔文字のリストを作成
const faces = [‘(ノ?ヮ?)ノ*:・゚?2.0’, ‘(づ。????。)づ2.0’, ‘(*^ω^*)2.0’, ‘(????)2.0?’];
// httpサーバーの作成
const server = http.createServer((req, res) => {
// ステータスコード200でレスポンスを送信
res.statusCode = 200;
// レスポンスのヘッダーを設定
res.setHeader(‘Content-Type’, ‘text/plain; charset=utf-8’);
// ランダムに顔文字を選択
const face = faces[Math.floor(Math.random() * faces.length)];
// 顔文字をレスポンスとして返す
res.end(face + ‘\n’);
});
// サーバーを起動
const port = 3000;
server.listen(port, () => {
console.log(`Server 2.0 running at http://localhost:${port}/`);
});
p3-22:
[user01@ip-192-168-1-1 emoji]$ vi Dockerfile
– ベースイメージの指定
FROM almalinux:9
– Maintainerの登録
LABEL maintainer=”abc@example.com”
– Node.jsのインストール
RUN dnf -y install nodejs procps && mkdir /app
– ファイルのコピー
COPY ./emoji.js /app/emoji.js
– ポートの設定
EXPOSE 3000
### アプリケーションの起動コマンド
ENTRYPOINT [“node”, “/app/emoji.js”]
[user01@ip-192-168-1-1 emoji]$ docker image build -t dockerintro数字/emoji:2.0 .
p3-23:
[user01@ip-192-168-1-1 emoji]$ docker image ls
p3-22:
[user01@ip-192-168-1-1 emoji]$ docker container run -p 8083:3000 -d –name emoji3 dockerintro数字/emoji:2.0
[user01@ip-192-168-1-1 emoji]$ curl 192.168.1.1:8083 [user01@ip-192-168-1-1 emoji]$ docker image push dockerintro数字/emoji:2.0
## 参考情報
cd ..
mkdir testweb-dev
cd testweb-dev
vi hello.js
var http = require(‘http’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(‘Hello World!!!\n’);
}).listen(80, ‘0.0.0.0’);
console.log(‘Server running at http://0.0.0.0:80/’);
docker container run -it -p 80:80 -v `pwd`:/src centos:7 bash #(ここまで1行で入力・「`」はバッククオーテーション)
ls
ls /src
node -v
yum -y install epel-release nodejs
yum -y install –enablerepo=epel npm
node -v
node hello.js
docker container stop `docker container ls -qa`
vi hello.js
var http = require(‘http’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(‘Hello World!!! (from Dockerfile!)\n’);
}).listen(80, ‘0.0.0.0’);
console.log(‘Server running at http://0.0.0.0:80/’);
※太字下線部を追記
vi Dockerfile
FROM centos:7
RUN yum -y install epel-release nodejs && yum -y install –enablerepo=epel npm
COPY . /src
WORKDIR /src
EXPOSE 80
ENTRYPOINT [“node”, “./hello.js”]
docker image build -t dockerintro数字/nodejs-app:1.0 .
docker image ls
docker container run -d -p 80:80 dockerintro数字/nodejs-app:1.0
docker container ls
ls ~/.ssh
[user01@ip-192-168-1-1 testweb]$ ssh-keygen
ls ~/.ssh
ls
echo “# testweb-dev” >> README.md
git init
ls
git add README.md Dockerfile hello.js
git commit -m “first commit”
git remote add origin https://github.com/dockerintro数字/testweb-dev.git
git push -u origin master
su –
パスワード: docker
useradd user02
usermod -G docker user02
su – user02
id
ls .ssh
ssh-keygen
ls
git clone git@github.com:dockerintro数字/testweb-dev.git(git cloneからここまで1行で入力)
cd testweb-dev
ls
more Dockerfile
FROM centos:7
RUN yum -y install epel-release nodejs && yum -y install –enablerepo=epel npm
COPY . /src
WORKDIR /src
EXPOSE 80
ENTRYPOINT [“node”, “./hello.js”]
vi hello.js
var http = require(‘http’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(‘Hello World!!!(from user02 Dockerfile)\n’);(下線部追記)
}).listen(80, ‘0.0.0.0’);
console.log(‘Server running at http://0.0.0.0:80/’);
docker image ls
docker image build -t user02-self-build-nodejs-app:1.0 .
docker container run -d -p 8080:80 user02-self-build-nodejs-app:1.0
docker container ls
## Docker2 command reference file (Version2) #
Dockerコース
演習環境アクセスマニュアル
https://docker-training-ctct.s3.ap-northeast-1.amazonaws.com/Z01.Docker%E3%82%B3%E3%83%BC%E3%82%B9+%E6%BC%94%E7%BF%92%E7%92%B0%E5%A2%83%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB.pdf
– 入門2 演習環境
https://docker-training-ctct.s3.ap-northeast-1.amazonaws.com/Docker%E5%85%A5%E9%96%802%E6%BC%94%E7%BF%92%E7%92%B0%E5%A2%83.pdf
## Chapter1: Dockerネットワーク
### デフォルトで作成のDockerネットワークの確認
p1-9:
[user01@ip-192-168-1-1 ~]$ sudo /home/user01/initial.sh
[sudo] password for user01: Komazaw@user01
p1-10:
[user01@ip-192-168-1-1 ~]$ docker network ls
[user01@ip-192-168-1-1 ~]$ docker network inspect bridge
p1-11:
[user01@ip-192-168-1-1 ~]$ ip link show docker0
[user01@ip-192-168-1-1 ~]$ brctl show
### ユーザ定義ネットワーク (種類: 単一ホストブリッジネットワーク)の作成
p1-12:
[user01@ip-192-168-1-1 ~]$ docker network create -d bridge br-net1
[user01@ip-192-168-1-1 ~]$ docker network ls
[user01@ip-192-168-1-1 ~]$ brctl show
p1-13:
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1 –format “{{json .IPAM.Config}}”
[user01@ip-192-168-1-1 ~]$ docker container run -it -d –name cont1 –network br-net1 alpine sh
[user01@ip-192-168-1-1 ~]$ docker container ls
p1-14:
[user01@ip-192-168-1-1 ~]$ brctl show
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1 –format “{{json .Containers}}”
p1-15:
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1 | jq ‘.[].Containers’
[user01@ip-192-168-1-1 ~]$ docker container run -it -d –name cont2 –network br-net1 alpine sh
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ brctl show
p1-16:
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1 –format ‘{{json .Containers}}’
[user01@ip-192-168-1-1 ~]$ docker container attach cont1
/ # ip a
p1-17:
/ # ping -c 3 172.18.0.3
/ # ping -c 3 cont2
/ # ping -c 3 192.168.1.1
p1-18:
/ # ping -c 3 192.168.1.2
[user01@ip-192-168-1-2 ~]$ ping -c 3 172.18.0.3
p1-19:
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker network disconnect br-net1 cont2
[user01@ip-192-168-1-1 ~]$ brctl show
[user01@ip-192-168-1-1 ~]$ docker network inspect br-net1 –format ‘{{json .Containers}}’
[user01@ip-192-168-1-1 ~]$ docker container attach cont1
/ # ping -c 3 cont2
p1-20:
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker network connect bridge cont2
[user01@ip-192-168-1-1 ~]$ brctl show
[user01@ip-192-168-1-1 ~]$ docker network inspect bridge –format ‘{{json .Containers}}’
[user01@ip-192-168-1-1 ~]$ docker container attach cont2
/ # ip a
p1-21:
/ # ping -c 3 172.18.0.2
/ # ping -c 3 cont1
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container stop `docker container ls -aq`
[user01@ip-192-168-1-1 ~]$ docker container rm `docker container ls -aq`
[user01@ip-192-168-1-1 ~]$ docker container ls -a
—
### 外部ネットワークからアクセスできるコンテナの作成 (ポートフォワーディング)
p1-28:
[user01@ip-192-168-1-1 ~]$ docker container run -p 3000:3000 -d –name hostinfo1 dockerintro23/hostinfo:v1
[user01@ip-192-168-1-1 ~]$ docker container ls
p1-29:
[user01@ip-192-168-1-1 ~]$ docker container inspect hostinfo1 –format “{{json .NetworkSettings.Networks}}”
※Server2の端末に移動
[user01@ip-192-168-1-2 ~]$ curl 192.168.1.1:3000
※Server1の端末に移動
[user01@ip-192-168-1-1 ~]$ docker container run -p 3000:3000 -d –name hostinfo2 dockerintro23/hostinfo:v1
p1-30:
[user01@ip-192-168-1-1 ~]$ docker container ls -a
[user01@ip-192-168-1-1 ~]$ docker container rm hostinfo2
[user01@ip-192-168-1-1 ~]$ docker container run -p 3001:3000 -d –name hostinfo2 dockerintro23/hostinfo:v1
[user01@ip-192-168-1-1 ~]$ docker container ls
p1-31:
※Server2の端末に移動
[user01@ip-192-168-1-2 ~]$ curl 192.168.1.1:3001
※Server1の端末に移動
[user01@ip-192-168-1-1 ~]$ docker container stop `docker container ls -aq`
[user01@ip-192-168-1-1 ~]$ docker container rm `docker container ls -aq`
—
☆外部ネットワークからアクセスできるコンテナの作成 (MACVLAN)(※任意演習)
※お使いいただいている演習環境がパブリッククラウドでプロミスキャスモードの有効化ができないため、このMACVLANの演習は実施できません。実施してみたい方は非パブリッククラウドの演習環境をご案内するので、講師に個別にお声がけください(なお、非パブリッククラウドの演習環境にアクセスするにはお手元でお使いのPCにアクセス制限が掛かっていないものをご準備いただき、CiscoAnyConnectというソフトウェアをインストールしていただく必要があります)。
p1-32:
[user01@docker01 ~]$ docker network ls
[user01@docker01 ~]$ docker network create -d macvlan -o parent=enp0s3 –subnet=192.168.1.0/24 –gateway=192.168.1.254 –ip-range=192.168.1.0/24 labnet1
[user01@docker01 ~]$ docker network ls
p1-33:
[user01@docker01 ~]$ docker network inspect labnet1
p1-34:
[user01@docker01 ~]$ ip a show enp0s3
[user01@docker01 ~]$ sudo ifconfig enp0s3 promisc
[sudo] password for user01: docker
[user01@docker01 ~]$ ip a show enp0s3
p1-35:
[user01@docker01 ~]$ docker container run –network=labnet1 –ip=192.168.1.153 -it -d –name hostinfo3 dockerintro23/hostinfo:v1
[user01@docker01 ~]$ docker container inspect hostinfo3 –format ‘{{json .NetworkSettings.Networks}}’
[user01@docker01 ~]$ docker container exec -it hostinfo3 sh
# ip a
p1-36:
# ip r
# ping -c 3 192.168.1.2
※「Docker入門 #2」のuser01のシェルに移動
[user01@docker02 ~]$ curl 192.168.1.153:3000
※「Docker入門」のuser01のシェルに移動
# ping -c 3 192.168.1.1
p1-37:
Ctrl+P→Q
[user01@docker01 ~]$ docker container run –network=labnet1 –ip=192.168.1.154 -it -d –name hostinfo4 dockerintro23/hostinfo:v1
[user01@docker01 ~]$ docker container exec -it hostinfo4 sh
# ip a
※「Docker入門 #2」のuser01のシェルに移動
[user01@docker02 ~]$ curl 192.168.1.154:3000
p1-38:
※「Docker入門」のuser01のシェルに移動
Ctrl+P→Q
[user01@docker01 ~]$ docker container stop `docker container ls -aq`
[user01@docker01 ~]$ docker container rm `docker container ls -aq`
[user01@docker01 ~]$ docker network rm br-net1 labnet1
## Chapter2: Dockerボリューム
### ボリュームの作成とコンテナへのアタッチ
p2-9:
[user01@ip-192-168-1-1 ~]$ docker volume ls
[user01@ip-192-168-1-1 ~]$ docker volume create volume1
[user01@ip-192-168-1-1 ~]$ docker volume ls
[user01@ip-192-168-1-1 ~]$ docker volume inspect volume1
p2-10:
[user01@ip-192-168-1-1 ~]$ docker container run -it –name cont5 –mount=source=volume1,target=/vol alpine sh
/ # ls /vol
/ # echo “This is a test data.” > /vol/file1
/ # more /vol/file1
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container ls
p2-11:
[user01@ip-192-168-1-1 ~]$ docker volume ls
[user01@ip-192-168-1-1 ~]$ docker container stop cont5
[user01@ip-192-168-1-1 ~]$ docker container rm cont5
[user01@ip-192-168-1-1 ~]$ docker container ls -a
[user01@ip-192-168-1-1 ~]$ docker volume ls
[user01@ip-192-168-1-1 ~]$ sudo ls /var/lib/docker/volumes
[sudo] password for user01: Komazaw@user01
p2-12:
[user01@ip-192-168-1-1 ~]$ sudo ls /var/lib/docker/volumes/volume1
[user01@ip-192-168-1-1 ~]$ sudo ls /var/lib/docker/volumes/volume1/_data
[user01@ip-192-168-1-1 ~]$ sudo more /var/lib/docker/volumes/volume1/_data/file1
[user01@ip-192-168-1-1 ~]$ docker container run -it –name cont5 –mount=source=volume1,target=/vol alpine sh
/ # ls /vol
/ # more /vol/file1
p2-13:
Ctrl+P→Q
[user01@ip-192-168-1-1 ~]$ docker container stop `docker container ls -aq`
[user01@ip-192-168-1-1 ~]$ docker container rm `docker container ls -aq`
[user01@ip-192-168-1-1 ~]$ docker container ls
[user01@ip-192-168-1-1 ~]$ docker volume rm volume1
[user01@ip-192-168-1-1 ~]$ docker volume ls
[user01@ip-192-168-1-1 ~]$ sudo ls /var/lib/docker/volumes
## Chapter3 : Docker Compose
### DockerホストのOS上で動作するToDoアプリの作成(参考演習)
3-13:
[user01@ip-192-168-1-1 ~]$ mkdir todo
[user01@ip-192-168-1-1 ~]$ cd todo
[user01@ip-192-168-1-1 todo]$
[user01@ip-192-168-1-1 todo]$ sudo vi /etc/yum.repos.d/mongo.repo
[sudo] password for user01: Komazaw@user01
3-14:
[user01@ip-192-168-1-1 todo]$ sudo dnf -y install mongodb-org
[user01@ip-192-168-1-1 todo]$ sudo systemctl start mongod
[user01@ip-192-168-1-1 todo]$ sudo systemctl enable mongod
[user01@ip-192-168-1-1 todo]$ mongosh
3-15:
test> quit()
[user01@ip-192-168-1-1 todo]$ ls
[user01@ip-192-168-1-1 todo]$ npm init -y
[user01@ip-192-168-1-1 todo]$ ls
3-16:
[user01@ip-192-168-1-1 todo]$ more package.json
[user01@ip-192-168-1-1 todo]$ npm install express mongoose body-parser ejs
[user01@ip-192-168-1-1 todo]$ ls
[user01@ip-192-168-1-1 todo]$ ls node_modules
3-17:
[user01@ip-192-168-1-1 todo]$ more package.json
3-18~19:
[user01@ip-192-168-1-1 todo]$ vi app.js
const mongoose = require(‘mongoose’);
const mongoURI = ‘mongodb://localhost:27017/todo-app’;
mongoose.connect(mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log(‘MongoDB Connected’);
}).catch(err => {
console.log(err);
});
const express = require(‘express’);
const bodyParser = require(‘body-parser’);
const ToDo = require(‘./models/ToDo’);
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + ‘/public’));
app.set(‘view engine’, ‘ejs’);
app.get(‘/’, async (req, res) => {
const todos = await ToDo.find();
res.render(‘index’, { todos });
});
app.post(‘/todos’, async (req, res) => {
const newTodo = new ToDo({
task: req.body.task
});
await newTodo.save();
res.redirect(‘/’);
});
app.get(‘/todos/:id’, async (req, res) => {
const todo = await ToDo.findById(req.params.id);
res.render(‘show’, { todo });
});
app.post(‘/todos/:id’, async (req, res) => {
const todo = await ToDo.findById(req.params.id);
todo.isComplete = !todo.isComplete;
await todo.save();
res.redirect(‘/’);
});
app.get(‘/todos/delete/:id’, async (req, res) => {
const todo = await ToDo.findByIdAndDelete(req.params.id);
res.redirect(‘/’);
});
app.post(‘/todos/delete/:id’, async (req, res) => {
const todo = await ToDo.findByIdAndDelete(req.params.id);
res.redirect(‘/’);
});
app.listen(3000, () => {
console.log(‘Server running on port 3000’);
});
3-20:
[user01@ip-192-168-1-1 todo]$ mkdir models
[user01@ip-192-168-1-1 todo]$ vi models/ToDo.js
const mongoose = require(‘mongoose’);
const ToDoSchema = new mongoose.Schema({
task: { type: String, required: true },
isComplete: { type: Boolean, default: false },
createdAt: { type: Date, default: Date.now }
});
const ToDo = mongoose.model(‘ToDo’, ToDoSchema);
module.exports = ToDo;
[user01@ip-192-168-1-1 todo]$ mkdir views3-21:
[user01@ip-192-168-1-1 todo]$ vi views/index.ejs
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>ToDo App</title>
</head>
<body>
<h1>ToDo App</h1>
<form method=”POST” action=”/todos”>
<input type=”text” name=”task” placeholder=”New ToDo”>
<button type=”submit”>Add ToDo</button>
</form>
<ul>
<% todos.forEach(todo => { %>
<li>
<a href=”/todos/<%= todo._id %>”>
<%= todo.task %>
</a>
<form method=”POST” action=”/todos/delete/<%= todo._id %>” style=”display: inline-block;”>
<button type=”submit”>Delete</button>
</form>
<% if (todo.isComplete) { %>
<span style=”color: green;”>(Complete)</span>
<% } else { %>
<form method=”POST” action=”/todos/<%= todo._id %>”>
<button type=”submit”>Complete</button>
</form>
<% } %>
</li>
<% }) %>
</ul>
</body>
</html>
3-22:
[user01@ip-192-168-1-1 todo]$ vi views/show.ejs
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>ToDo App – <%= todo.task %></title>
</head>
<body>
<h1><%= todo.task %></h1>
<% if (todo.isComplete) { %>
<p style=”color: green;”>Complete!</p>
<% } else { %>
<form method=”POST” action=”/todos/<%= todo._id %>”>
<button type=”submit”>Complete</button>
</form>
<% } %>
<p><%= todo.createdAt.toDateString() %></p>
<a href=”/”>Back to ToDo List</a>
</body>
</html>
3-23:
ご受講にご利用のお手元のPCのブラウザで「http://Server1のIPアドレス:3000」と入力し、ToDoアプリにアクセス
3-24:
新規ブラウザのタブで「https://Server1のIPアドレス/system/terminal」と入力し、Server1の端末をもう一つ作成
3-25:
[user01@ip-192-168-1-1 todo]$ mongosh
test> show dbs
test> use todo-app
3-26:
test> show collections
test> db.todos.find()
test> exit
[user01@ip-192-168-1-1 todo]$ sudo systemctl stop mongod
[user01@ip-192-168-1-1 todo]$ systemctl status mongod
3-27:
node app.jsを実行したServer1の端末でCtrl+Cを入力し、nodeコマンドを終了
—
### ToDoアプリのDocker Composeアプリケーション化
3-28:
[user01@ip-192-168-1-1 ~]$ cd /home/user01/todo
3-29:
[user01@ip-192-168-1-1 todo]$ vi docker-compose.yml
version: ‘3.9’
services:
app:
build: .
ports:
– “8086:3000”
networks:
– network1
depends_on:
– mongo
mongo:
image: mongo
networks:
– network1
restart: always
volumes:
– mongo-data:/data/db
networks:
network1:
driver: bridge
volumes:
mongo-data:
3-30:
[user01@ip-192-168-1-1 todo]$ vi Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json /app
RUN npm install
COPY . /app
EXPOSE 3000
ENTRYPOINT [ “node”, “app.js” ]
[user01@ip-192-168-1-1 todo]$ vi app.js
2行目のlocalhostをmongoに変更
3-31:
[user01@ip-192-168-1-1 todo]$ docker image ls
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ docker volume ls
[user01@ip-192-168-1-1 todo]$ docker compose up -d
3-32:
[user01@ip-192-168-1-1 todo]$ docker container ls
[user01@ip-192-168-1-1 todo]$ docker image ls
[user01@ip-192-168-1-1 todo]$ docker network ls
3-33:
[user01@ip-192-168-1-1 todo]$ docker container inspect todo-app-1 | jq ‘.[].NetworkSettings.Networks’
[user01@ip-192-168-1-1 todo]$ docker container inspect todo-mongo-1 | jq ‘.[].NetworkSettings.Networks’
3-34:
[user01@ip-192-168-1-1 todo]$ docker container exec todo-app-1 ping -c 3 mongo
[user01@ip-192-168-1-1 todo]$ docker volume ls
[user01@ip-192-168-1-1 todo]$ docker container inspect todo-mongo-1 | jq ‘.[].Mounts’
3-35:
[user01@ip-192-168-1-1 todo]$ docker compose ps
[user01@ip-192-168-1-1 todo]$ docker compose top
ご受講にご利用のお手元のPCのブラウザで「http://Server1のIPアドレス:8086」と入力し、ToDoアプリにアクセス
3-36:
[user01@ip-192-168-1-1 todo]$ docker compose stop
[user01@ip-192-168-1-1 todo]$ docker container ls
[user01@ip-192-168-1-1 todo]$ docker container ls -a
[user01@ip-192-168-1-1 todo]$ docker volume ls
3-37:
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ docker compose start
[user01@ip-192-168-1-1 todo]$ docker compose down
[user01@ip-192-168-1-1 todo]$ docker container ls -a
3-38:
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ docker volume ls
[user01@ip-192-168-1-1 todo]$ docker compose up -d
3-39:
[user01@ip-192-168-1-1 todo]$ docker container ls
[user01@ip-192-168-1-1 todo]$ docker compose down –volumes
3-40:
[user01@ip-192-168-1-1 todo]$ docker container ls
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ docker volume ls
## Chapter4: Docker Swarm
### Swarmクラスタの作成
4-8:
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ ip a show eth0
4-9:
[user01@ip-192-168-1-1 todo]$ docker swarm init –advertise-addr 192.168.1.1:2377 –listen-addr 192.168.1.1:2377
[user01@ip-192-168-1-1 todo]$ docker node ls
[user01@ip-192-168-1-1 todo]$ docker network ls
4-10:
[user01@ip-192-168-1-1 todo]$ docker swarm join-token manager
※Server2の端末に移動
[user01@ip-192-168-1-2 ~]$ docker swarm join –token トークン本体の文字列 192.168.1.1:2377
※Server3の端末にログイン
4-11:
[user01@ip-192-168-1-3 ~]$ docker swarm join –token トークン本体の文字列 192.168.1.1:2377
※Server1の端末に移動
[user01@ip-192-168-1-1 todo]$ docker swarm join-token worker
※Server4の端末にログイン
4-12:
[user01@ip-192-168-1-4 ~]$ docker swarm join –token トークン本体の文字列 192.168.1.1:2377
※Server5の端末にログイン
[user01@ip-192-168-1-5 ~]$ docker swarm join –token トークン本体の文字列 192.168.1.1:23774-13:
※Server1の端末に移動
[user01@ip-192-168-1-1 todo]$ docker node ls
### Swarmクラスタへのサービスの作成
4-22:
※Server1の端末を表示
[user01@ip-192-168-1-1 todo]$ cd /home/user01/hostinfo
[user01@ip-192-168-1-1 hostinfo]$ more hostinfo-v1.js
4-24:
[user01@ip-192-168-1-1 hostinfo]$ node hostinfo-v1.js
※もう1つのServer1の端末に移動
[user01@ip-192-168-1-1 ~]$ cd /home/user01/hostinfo4-25:
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
※node app.jsコマンドを実行したServer1の端末に戻り、Ctrl+Cでnode app.jsコマンドを終了
[user01@ip-192-168-1-1 hostinfo]$ vi DockerfileFROM node:16
COPY hostinfo-v1.js /hostinfo-v1.js
ENTRYPOINT [“node”, “hostinfo-v1.js”]
4-26:
[user01@ip-192-168-1-1 hostinfo]$ docker image build -t dockerintro数字/hostinfo:v1 .
[user01@ip-192-168-1-1 hostinfo]$ docker image ls
[user01@ip-192-168-1-1 hostinfo]$ docker login
Username: dockerintro数字
Password: DockerIntro数字@
4-27:
[user01@ip-192-168-1-1 hostinfo]$ docker service create –name hostinfo -p 3000:3000 –replicas=6 dockerintro数字/hostinfo:v1
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
4-28:
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker service logs hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker service logs レプリカID(タブ補完可能)
4-29:
[user01@ip-192-168-1-1 hostinfo]$ docker service inspect hostinfo
4-30:
[user01@ip-192-168-1-1 hostinfo]$ docker node inspect ip-192-168-1-1.ap-northeast-1.compute.internal | jq ‘.[].Status.Addr’
[user01@ip-192-168-1-1 hostinfo]$ docker node inspect ip-192-168-1-2.ap-northeast-1.compute.internal | jq ‘.[].Status.Addr’
[user01@ip-192-168-1-1 hostinfo]$ docker node inspect ip-192-168-1-3.ap-northeast-1.compute.internal | jq ‘.[].Status.Addr’
[user01@ip-192-168-1-1 hostinfo]$ docker node inspect ip-192-168-1-4.ap-northeast-1.compute.internal | jq ‘.[].Status.Addr’
[user01@ip-192-168-1-1 hostinfo]$ docker node inspect ip-192-168-1-5.ap-northeast-1.compute.internal | jq ‘.[].Status.Addr’
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
4-31:
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
4-32:
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.5:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.5:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.5:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.5:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.5:3000
4-33:
[user01@ip-192-168-1-1 hostinfo]$ ping -c 3 10.0.0.11
[user01@ip-192-168-1-1 hostinfo]$ docker container exec コンテナ名(タブ補完可能) ping -c 3 10.0.0.11
4-34:
[user01@ip-192-168-1-1 hostinfo]$ docker service scale hostinfo=10
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
4-35:
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker service scale hostinfo=3
4-36:
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
### Swarmクラスタのコンテナ内のアプリケーションの更新
4-41:
[user01@ip-192-168-1-1 hostinfo]$ cp hostinfo-v1.js hostinfo-v2.js
[user01@ip-192-168-1-1 hostinfo]$ vi hostinfo-v2.js
const appVersion = ‘2.0.0’; #1.0.0から2.0.0に変更
FROM node:16
COPY hostinfo-v2.js /hostinfo-v2.js
ENTRYPOINT [“node”, “hostinfo-v2.js”] [user01@ip-192-168-1-1 hostinfo]$ docker image ls
4-42:
[user01@ip-192-168-1-1 hostinfo]$ docker image build -t dockerintro数字/hostinfo:v2 .
[user01@ip-192-168-1-1 hostinfo]$ docker image ls
4-43:
[user01@ip-192-168-1-1 hostinfo]$ docker image push dockerintro数字/hostinfo:v2
[user01@ip-192-168-1-1 hostinfo]$ docker service scale hostinfo=6
4-44:
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
[user01@ip-192-168-1-1 hostinfo]$ while true ; do curl 192.168.1.1:3000; sleep 3; done
4-45:
[user01@ip-192-168-1-1 hostinfo]$ docker service update –image dockerintro数字/hostinfo:v2 –update-parallelism 2 –update-delay 15s hostinfo
4-46:
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
4-47:
[user01@ip-192-168-1-1 hostinfo]$ docker service rollback hostinfo
[user01@ip-192-168-1-1 hostinfo]$ while true ; do curl 192.168.1.1:3000; sleep 3; done
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
4-48:
[user01@ip-192-168-1-1 hostinfo]$ docker service rm hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker container ls
## 5章: Docker Stack
### Docker Stackでのhostinfoコンテナのデプロイ
5-9:
[user01@ip-192-168-1-1 todo]$ cd /home/user01/hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker network create -d overlay hostinfo-network
[user01@ip-192-168-1-1 hostinfo]$ docker network ls
5-10:
[user01@ip-192-168-1-1 hostinfo]$ vi hostinfo.yml
version: ‘3.9’
services:
hostinfo:
image: dockerintro数字/hostinfo:v1
ports:
– “3000:3000”
networks:
– hostinfo-network
deploy:
replicas: 6
networks:
hostinfo-network:
external: true
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker stack deploy -c hostinfo.yml hostinfo-stack
5-11:
[user01@ip-192-168-1-1 hostinfo]$ docker stack ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo-stack_hostinfo
5-12:
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
[user01@ip-192-168-1-1 hostinfo]$ curl 192.168.1.1:3000
version: ‘3.9’
services:
hostinfo:
image: dockerintro数字/hostinfo:v1
ports:
– “3000:3000”
networks:
– hostinfo-network
deploy:
replicas: 10
networks:
hostinfo-network:
external: true
5-13:
[user01@ip-192-168-1-1 hostinfo]$ docker stack deploy -c hostinfo.yml hostinfo-stack
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo-stack_hostinfo
5-14:
[user01@ip-192-168-1-1 hostinfo]$ vi hostinfo.yml
version: ‘3.9’
services:
hostinfo:
image: dockerintro数字/hostinfo:v2
ports:
– “3000:3000”
networks:
– hostinfo-network
deploy:
replicas: 10
networks:
hostinfo-network:
external: true
5-15:
※下のwhileコマンドは以前Server1の端末で実行したwhileコマンドの無限ループのタブを閉じてしまった方のみ、新しいタブからServer1の端末にアクセスして実行してください。whileコマンドのタブが残っている方は実行不要です。
[user01@ip-192-168-1-1 ~]$ while true ; do curl 192.168.1.1:3000; sleep 3; done
※ひとつ前のwhileコマンドを実行した方は元のServer1の端末に戻ります。
[user01@ip-192-168-1-1 hostinfo]$ docker stack deploy -c hostinfo.yml hostinfo-stack
5-16:
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo-stack_hostinfo
[user01@ip-192-168-1-1 hostinfo]$ while true ; do curl 192.168.1.1:3000; sleep 3; done
5-17:
※Server4の端末に移動
[user01@ip-192-168-1-4 ~]$ sudo at now + 5 minutes
[sudo] user01 のパスワード:Komazaw@user01
at> init 6
at> <EOT> (Ctrl+Dを入力)
[user01@ip-192-168-1-4 ~]$ sudo ip link set eth0 down
[sudo] password for user01: Komazaw@user01
※コマンドプロンプトが返って来なくなりますが問題ありませんので次の手順に進みます。
5-18:
※Server1の端末に移動
[user01@ip-192-168-1-1 hostinfo]$ docker service ls
[user01@ip-192-168-1-1 hostinfo]$ docker service ps hostinfo-stack_hostinfo
[user01@ip-192-168-1-1 hostinfo]$ docker stack rm hostinfo-stack
## 参考: Docker Stackでのtodoコンテナのデプロイ
5-23:
[user01@ip-192-168-1-1 hostinfo]$ cd /home/user01/todo
[user01@ip-192-168-1-1 todo]$ docker image tag todo-app dockerintro数字/todo-app
[user01@ip-192-168-1-1 todo]$ docker image ls
[user01@ip-192-168-1-1 todo]$ docker image push dockerintro数字/todo-app
5-24:
[user01@ip-192-168-1-1 todo]$ docker node inspect ip-192-168-1-5.ap-northeast-1.compute.internal | jq ‘.[].Spec.Labels’
[user01@ip-192-168-1-1 todo]$ docker node update –label-add nodename=docker05 ip-192-168-1-5.ap-northeast-1.compute.internal
[user01@ip-192-168-1-1 todo]$ docker node inspect ip-192-168-1-5.ap-northeast-1.compute.internal | jq ‘.[].Spec.Labels’
[user01@ip-192-168-1-1 todo]$ docker network create -d overlay todo-network
5-25:
[user01@ip-192-168-1-1 todo]$ docker network ls
[user01@ip-192-168-1-1 todo]$ docker network inspect todo-network
5-26:
[user01@ip-192-168-1-1 todo]$ vi todo-mongo.yml
version: ‘3.9’
services:
mongo:
image: mongo
volumes:
– mongo-data:/data/db
networks:
– todo-network
deploy:
placement:
constraints:
– node.labels.nodename == docker05
volumes:
mongo-data:
networks:
todo-network:
external: true
5-27:
[user01@ip-192-168-1-1 todo]$ docker stack deploy -c todo-mongo.yml todo-mongo
[user01@ip-192-168-1-1 todo]$ docker stack ls
[user01@ip-192-168-1-1 todo]$ docker service ls
[user01@ip-192-168-1-1 todo]$ docker service ps todo-mongo_mongo
5-28:
[user01@ip-192-168-1-1 todo]$ vi todo-app.yml
version: ‘3.9’
services:
app:
image: dockerintro数字/todo-app #数字はご自身の数字に変更
ports:
– “8086:3000”
networks:
– todo-network
networks:
todo-network:
external: true
[user01@ip-192-168-1-1 todo]$ docker stack ls
5-29:
[user01@ip-192-168-1-1 todo]$ docker service ls
[user01@ip-192-168-1-1 todo]$ docker service ps todo-app_app
※お手元のPCのブラウザでhttp://Server1のIPアドレス:8086でToDoアプリにアクセス(URLの先頭はhttps://ではなくhttp://)
5-30:
[user01@ip-192-168-1-1 todo]$ vi todo-app.yml
version: ‘3.9’
services:
app:
image: dockerintro数字/todo-app
ports:
– “8086:3000”
networks:
– todo-network
deploy: #新規登録
replicas: 5 #新規登録
networks:
todo-network:
external: true
[user01@ip-192-168-1-1 todo]$ docker service ls
5-31:
[user01@ip-192-168-1-1 todo]$ docker service ps todo-app_app
[user01@ip-192-168-1-1 todo]$ ssh user01@192.168.1.5
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
user01@192.168.1.5’s password: Komazaw@user01
5-32:
[user01@ip-192-168-1-5 ~]$ docker container ls
[user01@ip-192-168-1-5 ~]$ docker container rm -f MongoDBのコンテナ名(タブ補完可能です)
[user01@ip-192-168-1-5 ~]$ docker container ls
[user01@ip-192-168-1-5 ~]$ exit
5-33:
[user01@ip-192-168-1-1 todo]$ docker service ls
[user01@ip-192-168-1-1 todo]$ docker service ps todo-mongo_mongo
[user01@ip-192-168-1-1 todo]$ docker service ps todo-app_app
5-34:
[user01@ip-192-168-1-1 todo]$ docker container ls
[user01@ip-192-168-1-1 todo]$ docker container rm -f ToDoアプリのコンテナ名(タブ補完可能です)
[user01@ip-192-168-1-1 todo]$ docker service ps todo-app_app