はじめに
- ConohaのVPSを借りたのでDockerを入れようと思い、公式のチュートリアルをやってみようと思ったのでございます
環境
- VirtualBox 5.1.22 r115126
- ポートフォワーディング設定でアクセスできるようにしています
- Ubuntu16.04.2 LTS
- Docker version 17.03.1-ce, build c6d412e
- Dockerのインストールについては公式手順に沿って実施しております
チュートリアル
- Part 1: Orientation and Setup
- Part 2: Containers
- Part 3: Services
- Part 4: Swarms
- Part 5: Stacks
- Part 6: Deploy your app
Part 1: Orientation and Setup
tocyuki@vm01:~$ docker run hello-world
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.27/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
怒られたのでdockerグループにユーザーを追加し、シェルを入り直す
tocyuki@vm01:~$ sudo gpasswd -a $USER docker
Adding user tocyuki to group docker
再度実行
tocyuki@vm01:~$ 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.
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://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
Part 2: Containers
Dockerfileの作成
Dockerfile
# Use an official Python runtime as a base image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
Dockerfileで定義しているrequirements.txt
の作成
requirements.txt
Flask
Redis
app.pyの作成
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
ディレクトリ内の確認
tocyuki@vm01:~/docker_tutorial/part2$ ls
app.py Dockerfile requirements.txt
アプリのビルド
tocyuki@vm01:~/docker_tutorial/part2$ docker build -t friendlyhello .
Sending build context to Docker daemon 4.608 kB
Step 1/7 : FROM python:2.7-slim
2.7-slim: Pulling from library/python
10a267c67f42: Pull complete
f68a39a6a5e4: Pull complete
9beaffc0cf19: Pull complete
3c1fe835fb6b: Pull complete
Digest: sha256:fdee3139831a8e66543effffdc5addf73c7b18b66c575bd030f9f6f3a7052a6b
Status: Downloaded newer image for python:2.7-slim
---> 1c7128a655f6
Step 2/7 : WORKDIR /app
---> 58fb2cb39ce7
Removing intermediate container 62ac3b33d5b2
Step 3/7 : ADD . /app
---> b622ab3a4d89
Removing intermediate container c08462f54caa
Step 4/7 : RUN pip install -r requirements.txt
---> Running in e9f759585f93
Collecting Flask (from -r requirements.txt (line 1))
Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
Collecting Redis (from -r requirements.txt (line 2))
Downloading redis-2.10.5-py2.py3-none-any.whl (60kB)
Collecting itsdangerous>=0.21 (from Flask->-r requirements.txt (line 1))
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.4 (from Flask->-r requirements.txt (line 1))
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting Werkzeug>=0.7 (from Flask->-r requirements.txt (line 1))
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting click>=2.0 (from Flask->-r requirements.txt (line 1))
Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask->-r requirements.txt (line 1))
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis
Successfully installed Flask-0.12.2 Jinja2-2.9.6 MarkupSafe-1.0 Redis-2.10.5 Werkzeug-0.12.2 click-6.7 itsdangerous-0.24
---> 8253de36c294
Removing intermediate container e9f759585f93
Step 5/7 : EXPOSE 80
---> Running in 1a5aee83fd16
---> a19b6d05e75a
Removing intermediate container 1a5aee83fd16
Step 6/7 : ENV NAME World
---> Running in f40fb19d6e66
---> 03ce499faeb7
Removing intermediate container f40fb19d6e66
Step 7/7 : CMD python app.py
---> Running in ee9f921a2a28
---> 7f1578ee5e75
Removing intermediate container ee9f921a2a28
Successfully built 7f1578ee5e75
作成されたイメージの確認
tocyuki@vm01:~/docker_tutorial/part2$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest 7f1578ee5e75 2 minutes ago 195 MB
アプリの起動
- 4000番ポートをコンテナの80番へフォワードさせる
tocyuki@vm01:~/docker_tutorial/part2$ docker run -p 4000:80 friendlyhello
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
- バックグラウンドで起動させる場合
tocyuki@vm01:~/docker_tutorial/part2$ docker run -d -p 4000:80 friendlyhello
32a00753256cf419c262e28bbf5bf456fe66895b491d044fef1b802c18132101
アプリの起動確認
コマンドでの確認
tocyuki@vm01:~/docker_tutorial/part2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32a00753256c friendlyhello "python app.py" 28 seconds ago Up 27 seconds 0.0.0.0:4000->80/tcp jovial_newton
ブラウザからhttp://127.0.0.1:4000
へアクセス
コンテナの停止
tocyuki@vm01:~/docker_tutorial/part2$ docker stop 32a00753256c
32a00753256c
Docker Cloudへイメージのアップロード
docker login
の実施
tocyuki@vm01:~/docker_tutorial/part2$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: tocyuki
Password:
Login Succeeded
ローカルにあるイメージをリポジトリに関連付け
tocyuki@vm01:~/docker_tutorial/part2$ docker tag friendlyhello tocyuki/repository:tag
イメージのアップロード
tocyuki@vm01:~/docker_tutorial/part2$ docker push tocyuki/repository:tag
The push refers to a repository [docker.io/tocyuki/repository]
cb79c3ca3b0e: Pushed
a7c2dcf5a1b0: Pushed
50e365e5527d: Pushed
7b7f69d6236f: Mounted from library/python
667e68ed0db3: Mounted from library/python
5eac2de68a97: Mounted from library/python
8d4d1ab5ff74: Mounted from library/python
tag: digest: sha256:1ae82dcb5528f752c9c1fc57a55ec0dde097ee2b119011ed2d99b3b9e81228d8 size: 1787
Docker Cloudにアクセスしてみるとこんな感じでアップロードされていることが確認できる
Docker Cloud上のイメージからコンテナを起動させる
tocyuki@vm01:~/docker_tutorial/part2$ docker run -d -p 4000:80 tocyuki/repository:tag
4b463ae3362b945f19249c82325928068046770cf13faf2b8e855e23b3305e20
WEBブラウザからアクセスしてみると起動させたコンテナIDが表示されている
Part2で学習したコマンドのチートシート
# Create image using this directory's Dockerfile
docker build -t friendlyname .
# Run "friendlyname" mapping port 4000 to 80
docker run -p 4000:80 friendlyname
# Same thing, but in detached mode
docker run -d -p 4000:80 friendlyname
# See a list of all running containers
docker ps
# Gracefully stop the specified container
docker stop <hash>
# See a list of all containers, even the ones not running
docker ps -a
# Force shutdown of the specified container
docker kill <hash>
# Remove the specified container from this machine
docker rm <hash>
# Remove all containers from this machine
docker rm $(docker ps -a -q)
# Show all images on this machine
docker images -a
# Remove the specified image from this machine
docker rmi <imagename>
# Remove all images from this machine
docker rmi $(docker images -q)
# Log in this CLI session using your Docker credentials
docker login
# Tag <image> for upload to registry
docker tag <image> username/repository:tag
# Upload tagged image to registry
docker push username/repository:tag
# Run image from a registry
docker run username/repository:tag