- 投稿日:2019-10-02T20:20:13+09:00
今日のdocker error: requested access to the resource is denied
macOS$ docker commit 92edaa5cf839 kaizenjapan/posix sha256:150b4e135e37ffec6d92901c95d54b2e886a11a6377fe68ca199c3b35b4af7a3 $ docker push kaizenjapan/posix The push refers to repository [docker.io/kaizenjapan/posix] 3bc9aa75c2c1: Preparing 18f7e20c4125: Preparing bdb3ef4d81d2: Preparing 5c4512ea6db7: Preparing 01da96bac413: Preparing 8c487c756d71: Waiting 05c027e771c8: Waiting e9313b51f46d: Waiting 46601dcd4114: Waiting 31b0e148310d: Waiting denied: requested access to the resource is denied
- 投稿日:2019-10-02T20:20:13+09:00
今日のdocker error: requested access to the resource is denied: 解決
macOS$ docker commit 92edaa5cf839 kaizenjapan/posix sha256:150b4e135e37ffec6d92901c95d54b2e886a11a6377fe68ca199c3b35b4af7a3 $ docker push kaizenjapan/posix The push refers to repository [docker.io/kaizenjapan/posix] 3bc9aa75c2c1: Preparing 18f7e20c4125: Preparing bdb3ef4d81d2: Preparing 5c4512ea6db7: Preparing 01da96bac413: Preparing 8c487c756d71: Waiting 05c027e771c8: Waiting e9313b51f46d: Waiting 46601dcd4114: Waiting 31b0e148310d: Waiting denied: requested access to the resource is denied $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE kaizenjapan/posix latest 150b4e135e37 13 minutes ago 1.14GB kaizenjapan/http3a latest 863371d53d45 4 weeks ago 98.1MB kaizenjapan/http3 <none> 863371d53d45 4 weeks ago 98.1MB debian buster-slim 83a10817c894 7 weeks ago 69.2MB gcc latest e05f48a4f898 2 months ago 1.14GB $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 92edaa5cf839 gcc "/bin/bash" 23 hours ago Up 23 hours bold_minsky # docker rmi 83a10817c894 Error response from daemon: conflict: unable to delete 83a10817c894 (cannot be forced) - image has dependent child imagesdocker loginしなおしたらpushできた。
commit時点でエラーが出なかった理由は不明。
- 投稿日:2019-10-02T15:02:26+09:00
DockerfileのRUNコマンドを繋げて書く
RUNをまとめてorつなげて書く
RUNで不要な処理が生まれないように繋げてorまとめて書く
参考
https://qiita.com/c18t/items/f3a911ef01f124071c95
--squash
オプションを使えばその限りでは無いようですが…
繋げて書きたい!!RUNをつなげるにはバックスラッシュ
\
を使う改行を繋げるだけなら
\
でOK
別の処理が入るようなものをつなげるなら追加で&&
が必要になります!RUN apt-get -y update \ && apt-get install -y git \ && yarn global add @vue/cli -gこの時、個人的な好みですが
&&
が先頭に来るように書くと見やすくてなお良しです。↓こちらの記事の方も同じ意見のようです。
https://qiita.com/yuyakato/items/4e8616ad83d67e35bc5a
- 投稿日:2019-10-02T13:27:45+09:00
DockerのElixir環境にVSCodeでリモート接続してデバッグする【Windows環境】
Dockerコンテナ上に構築された環境にVSCodeからリモートアクセスしてデバッグまでできるそうなので、Elixirで試してみました。なお、せっかくなのでErlang、Elixirのバージョンは2019/10/1時点で最新のものを使っていきたいと思います。
環境
- Windows 10 Pro 64bit
- VSCode 1.38.1
- Docker Desktop for Windows 2.1.0.3
- Docker Engine 19.03.2
事前準備
こちらを参考に以下をインストールしました。
- VSCodeのインストール
- VSCodeのリモート開発の拡張機能インストール
- Dockerのインストール
Dockerfileの作成
- 作業用ディレクトリを作り、VSCodeで開きます。
F1キーを押してコマンドパレットを開き、
Remote Containers: Add Development Container Configuration Files...
を実行します。
ベースとなる開発環境を選択しますが、DockerFileを編集するので何でも良いです。とりあえず
Ubuntu 18.04 & Git
を選択します。
作業用ディレクトリに
.devcontainer
ディレクトリが作成され、devcontainer.json
とDockerfile
が自動生成されますので、Dockerfile
をElixir環境用に変更します。
- Elixri1.9.1のDockerfileの内容をコピーして自動生成された
Dockerfile
に上書きします。- Elixri1.9.1のDockerfileから以下の箇所を変更しました。
- LANGUAGE、LC_ALLの追加
- mix local.hexの実行を追加
- iexの起動の削除
FROM erlang:22 # elixir expects utf8. ENV ELIXIR_VERSION="v1.9.1" \ - LANG=C.UTF-8 + LANG=C.UTF-8 \ + LANGUAGE=C.UTF-8 \ + LC_ALL=C.UTF-8 RUN set -xe \ && ELIXIR_DOWNLOAD_URL="https://github.com/elixir-lang/elixir/archive/${ELIXIR_VERSION}.tar.gz" \ && ELIXIR_DOWNLOAD_SHA256="94daa716abbd4493405fb2032514195077ac7bc73dc2999922f13c7d8ea58777" \ && curl -fSL -o elixir-src.tar.gz $ELIXIR_DOWNLOAD_URL \ && echo "$ELIXIR_DOWNLOAD_SHA256 elixir-src.tar.gz" | sha256sum -c - \ && mkdir -p /usr/local/src/elixir \ && tar -xzC /usr/local/src/elixir --strip-components=1 -f elixir-src.tar.gz \ && rm elixir-src.tar.gz \ && cd /usr/local/src/elixir \ && make install clean \ + && cd $HOME \ + && mix local.hex --force - CMD ["iex"]コンテナにリモート接続し、拡張機能を有効化する
ここまで出来たらコンテナを立ち上げ、VSCodeからリモート接続します。
VSCodeの左下の
リモートウィンドウを開く
を押すとリモート機能に関するメニューが出てくるので、Remote-Containers: Reopen in Container
を選択します。そうすると、コンテナのビルドが行われリモート接続が完了します。
ターミナルを表示し、
elixir -v
を実行してバージョンを確認します。Erlang/OTP:22、Elixir:1.9.1がインストールされていることが確認できました。
リモートコンテナでは、ローカル環境でインストールしていた拡張機能が適用されていないため、Elixir関連の以下の拡張機能を有効にしておきます。インストールしたら再読み込みします。
- vscode-elixir
- ElixirLS
- ElixirFormatter
Elixirでコードを動かす
とりあえずHelloWorldが動くことを確認します。
mix new hello
で動作確認用プロジェクトを作成します。ターミナルを表示しcd hello
を行いHelloプロジェクトのディレクトリへ移動します。- VSCodeのエクスプローラーから
hello/lib/hello.ex
を選択して開きます。Helloモジュールにhello
関数ができているため、関数名をworld
に変更します。docも併せて変更しておきます。変更が終わったら保存します。defmodule Hello do @moduledoc """ Documentation for Hello. """ @doc """ Hello world. ## Examples - iex> Hello.hello() + iex> Hello.world() :world """ - def hello do + def world do :world end end
- ターミナルで
iex -S mix
を実行し、プロジェクトのモジュールをiexで開きます。Hello.world
で:wold
が返ってくることが確認できました。Ctrl + C
を2回押してiexを終了します。ブレークポイントを張ってデバッグする
デバッグが可能であることを確認します。
launch.json
にデフォルトのデバッグ構成が追加され開かれます。projectDir
が${workspaceRoot}
になっており、このままではmix.exsが見つからないためエラーとなるので、{workspaceRoot}/hello
に変更します。
hello/lib/hello.ex
を開き、デバッグ確認用のコードを追加します。defmodule Hello do @moduledoc """ Documentation for Hello. """ @doc """ Hello world. ## Examples iex> Hello.world() :world """ def world do + x = 1 + x = 2 :world end end
hello/test/hello_test.exs
のテストコードが自動生成されたままとなっているので、関数名を変更します。変更した行にブレークポイントを設定します。defmodule HelloTest do use ExUnit.Case doctest Hello test "greets the world" do - assert Hello.hello() == :world + assert Hello.world() == :world end end
- デバッグウィンドウを開き、デバッグ構成で
mix test
を選択した上でデバッグを開始します。ブレークポイントで止まっていることが確認できました。また、デバッグ確認用のコードがステップ実行できることも確認できました。所感
コンテナなのでローカル環境に影響が無い。コーディングはVSCodeの機能を活用できる。ローカルのディレクトリをマウントしているため、コンテナを終了しても成果物が残り続ける。結構良い感じなのではないでしょうか。次はコンテナ内でビルドする必要があるためにコーディングが中々捗らなかったElixirをAWS Lambdaで動かすための環境を整えたいと思います。
参考
- 投稿日:2019-10-02T11:29:00+09:00
Mac で docker login 時に User interaction is not allowed エラー
macOS Mojave(MacOS 10.14.6)で
docker login
するとerror storing credentials
User interaction is not allowed
が出ます。TL;DR
ログイン時の情報を KeyChain に書き込めないことによるエラーです。アンロックして KeyChain に追加できるようにします。
$ security unlock-keychain password to unlock default:TS;DR
ローカルでビルドした Docker イメージを Docker Hub にプッシュ(
docker push
)するために、docker login
する必要がありました。しかし、他の Mac ではdocker login
出来たのに、SSH 接続したヘッドレスの Mac ではログインできなかったのです。$ 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: keinos Password: Error saving credentials: error storing credentials - err: exit status 1, out: `error storing credentials - err: exit status 1, out: `User interaction is not allowed.``アカウント名とパスワードが同じなのはコピペピピックして確認済みです。
落ち着いてエラー内容を読むと、
error storing credentials
(「認証情報の保存エラー」) とあるのでログイン情報の保存時にエラーが発生しているようです。また、続けてUser interaction is not allowed
(「ユーザとのやりとりは禁止されています」) とあるので、権限的な問題が原因のようです。せやかて
sudo
て、と不安になりましたが「docker login User interaction is not allowed」でググったら出てきた以下の Qiita 記事で一発解消。助かりました。
- 投稿日:2019-10-02T11:14:59+09:00
AWS EC2 Amazon Linux2でDocker, Docker Composeをインストールする(忘備)
2019年10月現在で有効だった為、忘備録として残しておく
EC2 への Docker インストール
[root@ip-172-31-46-207 ~]# sudo yum install -y docker Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Resolving Dependencies --> Running transaction check Installed: docker.x86_64 0:18.06.1ce-10.amzn2 Dependency Installed: libcgroup.x86_64 0:0.41-15.amzn2 libtool-ltdl.x86_64 0:2.4.2-22.2.amzn2.0.2 pigz.x86_64 0:2.3.4-1.amzn2.0.1 Complete! [root@ip-172-31-46-207 ~]# sudo service docker start Redirecting to /bin/systemctl start docker.service [root@ip-172-31-46-207 ~]#ec2-user を docker グループに追加する
$ sudo usermod -a -G docker ec2-userEC2 への Docker Compose インストール(スーパーユーザー)
[root@ip-172-31-46-207 ~]# sudo -i [root@ip-172-31-46-207 ~]# curl -L "https://github.com/docker/compose/releases/download/1.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 617 0 617 0 0 2346 0 --:--:-- --:--:-- --:--:-- 2346 100 8066k 100 8066k 0 0 2894k 0 0:00:02 0:00:02 --:--:-- 3416k [root@ip-172-31-46-207 ~]# chmod +x /usr/local/bin/docker-compose [root@ip-172-31-46-207 ~]# exit logout [root@ip-172-31-46-207 ~]# docker-compose --version docker-compose version 1.11.2, build dfed245 [root@ip-172-31-46-207 ~]#aliasを付与
[root@ip-172-31-46-207 ~]# alias d='docker' [root@ip-172-31-46-207 ~]# alias dc='docker-compose'参考サイト
https://qiita.com/shinespark/items/a8019b7ca99e4a30d286
- 投稿日:2019-10-02T10:39:15+09:00
コンテナ型仮想化技術 Study01 / Docker基礎
はじめに
コンテナ型仮想化技術(主にDocker, Kubernetes辺り)を中心としたお勉強のログです。主に以下の書籍を軸にしながら、色々手を動かしたり調査した時の情報を整理していきます。
Docker/Kubernetes 実践コンテナ開発入門
15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用まではじめはDockerについて。
関連記事
コンテナ型仮想化技術 Study01 / Docker基礎
コンテナ型仮想化技術 Study02 / Docker レジストリ
コンテナ型仮想化技術 Study03 / Docker Compose
コンテナ型仮想化技術 Study04 / Minikube & kubectl簡易操作
コンテナ型仮想化技術 Study05 / Pod操作
コンテナ型仮想化技術 Study06 / ReplicaSet, Deployment, Service
コンテナ型仮想化技術 Study06' / Kubernetesネットワーク問題判別
コンテナ型仮想化技術 Study07 / ストレージ
コンテナ型仮想化技術 Study08 / Statefulset, Ingress
コンテナ型仮想化技術 Study09 / Helm参考情報
Docker Documentation
Docker HubLinuxコンテナ(LXC)の基礎をまとめ直す
なぜDockerではホストOSと違うOSベースのコンテナイメージが動くのか
Docker ライフサイクル 概要図 & 環境複製手順
Dockerイメージの理解とコンテナのライフサイクルDocker・Kubernetes周辺の動向を整理してみた件
コンテナランタイムの動向を整理してみた件
コンテナの標準仕様について調査してみた件
dockerと称するもの
今話題のいろいろなコンテナランタイムを比較してみた
Kubernetesのエコシステム ー コンテナランタイム編Dockerfileを既存のDockerイメージから生成する方法
Dockerfileを楽に作りたい(imageから自動生成したい)環境
Dockerインストール
oneWEX導入メモ / Ubuntu編※上で作ったUbuntu環境を使うことにする
DockerCEvagrant@ubuntu-xenial:~$ sudo docker version Client: Version: 18.09.6 API version: 1.39 Go version: go1.10.8 Git commit: 481bc77 Built: Sat May 4 02:35:27 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.6 API version: 1.39 (minimum version 1.12) Go version: go1.10.8 Git commit: 481bc77 Built: Sat May 4 01:59:36 2019 OS/Arch: linux/amd64 Experimental: false用語の整理
最初、この辺の用語が混乱しやすい...
Dockerコンテナ: Dockerイメージを基にして作成される仮想環境のインスタンス。
Dockerイメージ: Dockerコンテナを作成するためのテンプレート。ハッシュ値によるIMAGE IDが生成されて管理されるが、一般的にはリポジトリ名+タグ名(≒バージョン)で識別される。
Dockerリポジトリ: 同じ内容の異なるDockerイメージ(異なるバージョン)の集合。
Dockerレジストリ: Dockerリポジトリを集約して管理し、ホスティング機能を提供するサービス(Docker Hub, AWS ECR など)。補足:
"リポジトリ名"と"イメージ名"はほぼ同義的に使われていることも多い(例: example/echo)。イメージのBuild時に、docker image build コマンドの--tagオプションで、
name:tag
という指定ができ、ここで指定したnameがリポジトリ名として表示される。
参考: docker build例_Dockerイメージのリストvagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE example/echo 0.1.0 b128bbc227f5 3 hours ago 750MB example/echo latest b128bbc227f5 3 hours ago 750MB <none> <none> 1bab7e1d9051 5 days ago 750MB hello-world latest fce289e99eb9 9 months ago 1.84kB ibm-wex-ee 12.0.2.417 68b237b78230 11 months ago 5.17GB golang 1.9 ef89ef5c42a9 14 months ago 750MB gihyodocker/echo latest 3dbbae6eb30d 21 months ago 733MB例_Dockerコンテナのリストvagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e90108256ea9 example/echo:latest "go run /echo/main.go" 2 hours ago Up 2 hours test-echo ed7b9fdea5f0 1bab7e1d9051 "go run /echo/main.go" 19 hours ago Exited (2) 19 hours ago keen_khayyam 697fbfadd1bd 1bab7e1d9051 "go run /echo/main.go" 5 days ago Exited (2) 19 hours ago frosty_bose 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 5 days ago Exited (2) 5 days ago romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) 5 days ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hoover通常、コンテナを実行する時には、docker container runというコマンドが使われますが、この時引数として指定するのは、コンテナのIDではなくDockerイメージのIDもしくはイメージ名(リポジトリ名)+タグ(バージョン)です。
例:docker container run example/echo:latest
docker container runコマンドを実行すると、指定したイメージからコンテナを作成し、その後開始する、という処理が行われます(内部的にcreate + start が行われます)。参考: docker run
The docker run command first creates a writeable container layer over the specified image, and then starts it using the specified command. That is, docker run is equivalent to the API /containers/create then /containers/(id)/start. A stopped container can be restarted with all its previous changes intact using docker start. See docker ps -a to view a list of all containers.
この辺りが従来のインフラ管理の考え方からすると分かりにくいのですが、動的に環境を増やしたり減らしたりというような、いわゆるクラウドちっくな利用を想定する場合、環境の作成と起動というのはセットで、不要になったら停止して破棄する、というのがベースの考え方のようです。
最初に環境を作って(create)、それを開始(start)/停止(stop)で運用を回す、という感じではないんでしょうね(こういう思考回路だと最初は違和感半端ない)。
これは、「イミュータブル・インフラストラクチャー(Immutable infrastructure)」という概念に基づくもので、クラウド環境においてはかなり重要な考え方になっているようです。Dockerイメージを識別するのに、"example/echo:0.1.0"といったように、リポジトリ名(イメージ名) + タグ(バージョン)がよくつかわれますが、正確には、もう一つレジストリ名が修飾子として付きます。
"example/echo:0.1.0"はレジストリ名が省略された形で、デフォルトだとDockerHubが参照されることになるようです。
DockerHub以外のレジストリ(GitLab.comやローカルのレジストリサーバーなど)を使用する場合は、先頭にレジストリ名を付けて、"myregistryhost:5000/example/echo:0.1.0" といった形式で識別することになります。参考: docker tag
docker command help
vagrant@ubuntu-xenial:~$ docker --help Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/home/vagrant/.docker") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/home/vagrant/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/home/vagrant/.docker/cert.pem") --tlskey string Path to TLS key file (default "/home/vagrant/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Management Commands: builder Manage builds config Manage Docker configs container Manage containers engine Manage the docker engine image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services stack Manage Docker stacks swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container deploy Deploy a new stack or update an existing stack diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command.docker image
vagrant@ubuntu-xenial:~$ docker image --help Usage: docker image COMMAND Manage images Commands: build Build an image from a Dockerfile history Show the history of an image import Import the contents from a tarball to create a filesystem image inspect Display detailed information on one or more images load Load an image from a tar archive or STDIN ls List images prune Remove unused images pull Pull an image or a repository from a registry push Push an image or a repository to a registry rm Remove one or more images save Save one or more images to a tar archive (streamed to STDOUT by default) tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE Run 'docker image COMMAND --help' for more information on a command.docker container
vagrant@ubuntu-xenial:~$ docker container --help Usage: docker container COMMAND Manage containers Commands: attach Attach local standard input, output, and error streams to a running container commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem exec Run a command in a running container export Export a container's filesystem as a tar archive inspect Display detailed information on one or more containers kill Kill one or more running containers logs Fetch the logs of a container ls List containers pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container prune Remove all stopped containers rename Rename a container restart Restart one or more containers rm Remove one or more containers run Run a command in a new container start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers wait Block until one or more containers stop, then print their exit codes Run 'docker container COMMAND --help' for more information on a command.操作例
単純なコンテナの作成/実行
イメージ取得 / docker image pull
途中経過vagrant@ubuntu-xenial:~$ sudo docker image pull gihyodocker/echo:latest latest: Pulling from gihyodocker/echo 723254a2c089: Extracting [=========> ] 8.716MB/45.12MB abe15a44e12f: Download complete 409a28e3cc3d: Download complete 503166935590: Downloading [=====================================> ] 37.18MB/50.02MB abe52c89597f: Downloading [===========> ] 13.43MB/57.5MB ce145c5cf4da: Waiting 96e333289084: Waiting 39cd5f38ffb8: Waiting 22860d04f4f1: Pulling fs layer 7528760e0a03: Waiting完了vagrant@ubuntu-xenial:~$ sudo docker image pull gihyodocker/echo:latest latest: Pulling from gihyodocker/echo 723254a2c089: Pull complete abe15a44e12f: Pull complete 409a28e3cc3d: Pull complete 503166935590: Pull complete abe52c89597f: Pull complete ce145c5cf4da: Pull complete 96e333289084: Pull complete 39cd5f38ffb8: Pull complete 22860d04f4f1: Pull complete 7528760e0a03: Pull complete Digest: sha256:4520b6a66d2659dea2f8be5245eafd5434c954485c6c1ac882c56927fe4cec84 Status: Downloaded newer image for gihyodocker/echo:latestコンテナ作成,実行 / docker container run
vagrant@ubuntu-xenial:~$ sudo docker container run -t -p 9000:8080 gihyodocker/echo 2019/09/26 08:14:33 start server別な端末からcurlでコンテナ上のサービスにアクセスしてみる。
vagrant@ubuntu-xenial:~$ curl http://localhost:9000/ Hello Docker!!コンテナ状況確認 / docker container ls
vagrant@ubuntu-xenial:~$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 2 minutes ago Up 2 minutes 0.0.0.0:9000->8080/tcp romantic_neumannvagrant@ubuntu-xenial:~$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 5 minutes ago Up 5 minutes 0.0.0.0:9000->8080/tcp romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) 2 months ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hooverコンテナ停止 / docker container stop
vagrant@ubuntu-xenial:~$ sudo docker container stop 09c96d2fe2b8 09c96d2fe2b8コンテナ状況確認
vagrant@ubuntu-xenial:~$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES vagrant@ubuntu-xenial:~$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 13 minutes ago Exited (2) 29 seconds ago romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) 2 minutes ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hooverDockerイメージ作成
GO言語による簡単なWebサーバーが動くDockerイメージを作成する。
(GO言語環境が含まれているイメージをDocker Hubから取得して、それをベースにして新たなイメージを作成する)Go言語アプリのソース
main.gopackage main import ( "fmt" "log" "net/http" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ log.Println("received request") fmt.Fprintf(w, "Hello Docker!") }) log.Println("start server") server := &http.Server{Addr: ":8080"} if err := server.ListenAndServe(); err != nil { log.Println(err) } }Dockerfile
DockerfileFROM golang:1.9 RUN mkdir /echo COPY main.go /echo CMD ["go", "run", "/echo/main.go"]基本、DockerfileにはDokcerイメージ作成時に実行される操作を記載しておく。
ただし、CMDに記載された内容は、このイメージからコンテナーが起動される時に実行される!(ENTRYPOINTも同様)
参考: [docker] CMD とENTRYPOINT の違いを試してみたDockerイメージ作成 / docker image build
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image build -t example/echo:latest . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM golang:1.9 1.9: Pulling from library/golang 55cbf04beb70: Pull complete 1607093a898c: Pull complete 9a8ea045c926: Pull complete d4eee24d4dac: Pull complete 9c35c9787a2f: Pull complete 8b376bbb244f: Pull complete 0d4eafcc732a: Pull complete 186b06a99029: Pull complete Digest: sha256:8b5968585131604a92af02f5690713efadf029cc8dad53f79280b87a80eb1354 Status: Downloaded newer image for golang:1.9 ---> ef89ef5c42a9 Step 2/4 : RUN mkdir /echo ---> Running in d250ae9c747d Removing intermediate container d250ae9c747d ---> 3a640bd707fd Step 3/4 : COPY main.go /echo ---> 573acfbcaf8d Step 4/4 : CMD ["go", "run", "/echo/main.go"] ---> Running in 3998edcee3ce Removing intermediate container 3998edcee3ce ---> 1bab7e1d9051 Successfully built 1bab7e1d9051 Successfully tagged example/echo:latest vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE example/echo latest 1bab7e1d9051 2 minutes ago 750MB hello-world latest fce289e99eb9 8 months ago 1.84kB ibm-wex-ee 12.0.2.417 68b237b78230 11 months ago 5.17GB golang 1.9 ef89ef5c42a9 14 months ago 750MB gihyodocker/echo latest 3dbbae6eb30d 21 months ago 733MBDockerコンテナの作成,実行 / docker container run
実行vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container run example/echo 2019/09/26 09:10:51 start server状況確認vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f509be8d7bb3 example/echo "go run /echo/main.go" 36 seconds ago Up 35 seconds musing_noyce停止vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container stop f509be8d7bb3 f509be8d7bb3コンテナ作成 & バックグラウンドでの起動 / docker container run -d
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container run -d example/echo 697fbfadd1bdb5669cbcf778d2759505a5a40a04374cb4ec2c8fe3749c312493 vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 697fbfadd1bd example/echo "go run /echo/main.go" 9 seconds ago Up 8 seconds frosty_bose f509be8d7bb3 example/echo "go run /echo/main.go" 4 minutes ago Exited (2) 2 minutes ago musing_noyce 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" About an hour ago Exited (2) About an hour ago romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) About an hour ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hoover※docker container run は、イメージからコンテナを作成して実行するので、コンテナがどんどん増えていく!
前のコンテナ削除 / docker container rm
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container rm f509be8d7bb3 f509be8d7bb3docker container start/stopを使うのがいいのかと思ったのだが、docker container startだとバックグラウンドで実行するオプションが無い???!!!
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container start --help Usage: docker container start [OPTIONS] CONTAINER [CONTAINER...] Start one or more stopped containers Options: -a, --attach Attach STDOUT/STDERR and forward signals --detach-keys string Override the key sequence for detaching a container -i, --interactive Attach container's STDIN...と思ったら、勝手にバックグラウンドでの起動になったっぽい。
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container start 697fbfadd1bd 697fbfadd1bd vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 697fbfadd1bd example/echo "go run /echo/main.go" 7 minutes ago Up 16 seconds frosty_bose 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" About an hour ago Exited (2) About an hour ago romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) About an hour ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hooverポートフォワード
作成したDockerコンテナでは、8080ポートをListenするhttpサーバー(Go言語での実装)が起動するが、そのままだと外部からアクセスできない。そのため、コンテナ上でListenしているポートとホスト側ポートをマッピングする必要がある。
ホスト側ポート:9000 とコンテナポート:8080を紐づけてみる
vagrant@ubuntu-xenial:~$ sudo docker container run -d -p 9000:8080 example/echo:latest ed7b9fdea5f0956fccea31f3af98c798582191dad7aa5b7dc851fe2463e11570 vagrant@ubuntu-xenial:~$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ed7b9fdea5f0 example/echo:latest "go run /echo/main.go" 24 seconds ago Up 23 seconds 0.0.0.0:9000->8080/tcp keen_khayyam vagrant@ubuntu-xenial:~$ netstat -an | grep 9000 tcp6 0 0 :::9000 :::* LISTENCurlでアクセスしてみる。
vagrant@ubuntu-xenial:~$ curl http://localhost:9000 Hello Docker!アクセスできるようになった。
Dockerイメージを再度Build
main.goを編集後、再Build
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image build -t example/echo:latest . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM golang:1.9 ---> ef89ef5c42a9 Step 2/4 : RUN mkdir /echo ---> Using cache ---> 3a640bd707fd Step 3/4 : COPY main.go /echo ---> 24ed88e37920 Step 4/4 : CMD ["go", "run", "/echo/main.go"] ---> Running in 730f96c78672 Removing intermediate container 730f96c78672 ---> b128bbc227f5 Successfully built b128bbc227f5 Successfully tagged example/echo:latest vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE example/echo latest b128bbc227f5 5 seconds ago 750MB <none> <none> 1bab7e1d9051 5 days ago 750MB hello-world latest fce289e99eb9 9 months ago 1.84kB ibm-wex-ee 12.0.2.417 68b237b78230 11 months ago 5.17GB golang 1.9 ef89ef5c42a9 14 months ago 750MB gihyodocker/echo latest 3dbbae6eb30d 21 months ago 733MBlatestで新しく作ったイメージに別のタグ(バージョン)を付けて分かりやすくする。
vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image tag example/echo:latest example/echo:0.1.0 vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE example/echo 0.1.0 b128bbc227f5 8 minutes ago 750MB example/echo latest b128bbc227f5 8 minutes ago 750MB <none> <none> 1bab7e1d9051 5 days ago 750MB hello-world latest fce289e99eb9 9 months ago 1.84kB ibm-wex-ee 12.0.2.417 68b237b78230 11 months ago 5.17GB golang 1.9 ef89ef5c42a9 14 months ago 750MB gihyodocker/echo latest 3dbbae6eb30d 21 months ago 733MB名前付きコンテナ作成
※同名のコンテナをrunする場合には既存のものは削除しないといけないので、本番環境ではあまり使われないらしい
作成_実行vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container run -t -d --name test-echo example/echo:latest e90108256ea94a2e36d55daf043798dbc1defce69ada25317cbc7902736b22af vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e90108256ea9 example/echo:latest "go run /echo/main.go" 10 seconds ago Up 9 seconds test-echo停止vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container stop test-echo test-echo vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e90108256ea9 example/echo:latest "go run /echo/main.go" 3 minutes ago Exited (2) 15 seconds ago test-echo ed7b9fdea5f0 1bab7e1d9051 "go run /echo/main.go" 16 hours ago Exited (2) 16 hours ago keen_khayyam 697fbfadd1bd 1bab7e1d9051 "go run /echo/main.go" 5 days ago Exited (2) 16 hours ago frosty_bose 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 5 days ago Exited (2) 5 days ago romantic_neumann 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) 5 days ago elastic_ramanujan 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hoover実行vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container start test-echo test-echo vagrant@ubuntu-xenial:~/docker_test/test01$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e90108256ea9 example/echo:latest "go run /echo/main.go" 4 minutes ago Up 29 seconds test-echoコンテナ内でのコマンド実行
docker container execコマンドで、仮想環境であるコンテナ内でコマンドを実行することができます。
参考: docker execvagrant@ubuntu-xenial:~$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e90108256ea9 example/echo:latest "go run /echo/main.go" 4 hours ago Up 4 hours test-echo vagrant@ubuntu-xenial:~$ sudo docker container exec test-echo pwd /go標準入力をオープンにする-iオプションと、仮想端末を割り当てる-tオプションをつけて、shを実行すると、sshで仮想環境にログインしたようなイメージで操作できます。
vagrant@ubuntu-xenial:~$ sudo docker container exec -it test-echo sh # pwd /go # whoami root # hostname e90108256ea9 # ls / bin boot dev echo etc go home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varコンテナ稼働状況確認
vagrant@ubuntu-xenial:~$ sudo docker container stats CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS e90108256ea9 test-echo 0.00% 5.355MiB / 17.64GiB 0.03% 5.54kB / 0B 1.14MB / 8.19kB 23 ed7b9fdea5f0 keen_khayyam 0.00% 6.902MiB / 17.64GiB 0.04% 2.77kB / 0B 8.19kB / 8.19kB 15ストレージ管理
イメージやらコンテナはホストOS上のどこに保持されるのか?
参考:
Manage data in Docker
About storage drivers物理的には、/var/lib/docker/以下が消費されるようです。
(この下のimage, containersディレクトリ辺りですね)vagrant@ubuntu-xenial:/var/lib/docker$ pwd /var/lib/docker vagrant@ubuntu-xenial:/var/lib/docker$ sudo ls -la 合計 72 drwx--x--x 14 root root 4096 10月 2 01:21 . drwxr-xr-x 74 root root 4096 7月 15 10:12 .. drwx------ 2 root root 4096 6月 15 10:40 builder drwx------ 4 root root 4096 6月 15 10:40 buildkit drwx------ 8 root root 4096 10月 2 02:44 containers drwx------ 3 root root 4096 6月 15 10:40 image drwxr-x--- 3 root root 4096 6月 15 10:40 network drwx------ 125 root root 20480 10月 2 02:44 overlay2 drwx------ 4 root root 4096 6月 15 10:40 plugins drwx------ 2 root root 4096 10月 2 01:21 runtimes drwx------ 2 root root 4096 6月 15 10:40 swarm drwx------ 2 root root 4096 10月 2 02:22 tmp drwx------ 2 root root 4096 6月 15 10:40 trust drwx------ 3 root root 4096 6月 17 01:14 volumes以下のコマンドで、イメージ、コンテナごとに消費されるディスクのサイズを確認することができます。
イメージのサイズvagrant@ubuntu-xenial:/var/lib/docker$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE example/echo 0.1.0 b128bbc227f5 6 hours ago 750MB example/echo latest b128bbc227f5 6 hours ago 750MB <none> <none> 1bab7e1d9051 5 days ago 750MB hello-world latest fce289e99eb9 9 months ago 1.84kB ibm-wex-ee 12.0.2.417 68b237b78230 11 months ago 5.17GB golang 1.9 ef89ef5c42a9 14 months ago 750MB gihyodocker/echo latest 3dbbae6eb30d 21 months ago 733MBコンテナのサイズvagrant@ubuntu-xenial:/var/lib/docker$ sudo docker container ps -a -s CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE e90108256ea9 example/echo:latest "go run /echo/main.go" 5 hours ago Up 5 hours test-echo 8.4MB (virtual 758MB) ed7b9fdea5f0 1bab7e1d9051 "go run /echo/main.go" 21 hours ago Exited (2) 21 hours ago keen_khayyam 4.2MB (virtual 754MB) 697fbfadd1bd 1bab7e1d9051 "go run /echo/main.go" 5 days ago Exited (2) 21 hours ago frosty_bose 12.6MB (virtual 762MB) 09c96d2fe2b8 gihyodocker/echo "go run /echo/main.go" 5 days ago Exited (2) 5 days ago romantic_neumann 4.2MB (virtual 738MB) 8484e0182dd6 hello-world "/hello" 2 months ago Exited (0) 5 days ago elastic_ramanujan 0B (virtual 1.84kB) 8fcc80ffdeee hello-world "/hello" 3 months ago Exited (0) 3 months ago recursing_hoover 0B (virtual 1.84kB)Dockerイメージを作成すると、イメージレイヤと呼ばれるReadOnlyのデータエリアが確保されます(ミドルウェアやアプリ稼働に必要なモジュール等を含むファイルシステムなど)。
このDockerイメージを基にコンテナが作成されると、イメージレイヤに加えてコンテナレイヤと呼ばれるRead/Write可能なエリアが追加されます。
イメージレイヤは同一Dockerイメージから作成された複数コンテナで共有され、コンテナレイヤは各コンテナごとに作成されるようです。
上のdocker container ps -s
コマンドのSIZEの欄に表示されるのは、各コンテナのコンテナレイヤ(R/W)のみのサイズで、カッコ内のvirtualで示されるのはコンテナレイヤ(R/W)+イメージレイヤ(R/O)のサイズのようです。
(virtualで示されるサイズには、複数コンテナで共有している部分も含むため、これを全部足してしまうと、実際のサイズより大きくなってしまいます。)コンテナの一時的な利用
コンテナ間の通信の確認や、ホストOSからは操作できないことなどがある場合、テンポラリーにテスト用のコンテナ立ち上げて利用するということがしばしばあります。そういう時によく利用されるのが、BusyBoxやAlipne Linuxと呼ばれる軽量なLinuxイメージです。
ubuntuやmysqlのイメージと比較すると、busyboxやalpineのイメージのサイズが格段に小さいのが分かります。
vagrant@nfsserver:~$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest b534869c81f0 8 days ago 1.22MB ubuntu 16.04 56bab49eef2e 2 weeks ago 123MB mysql 5.7 1e4405fe1ea9 2 weeks ago 437MB alpine latest 965ea09ff2eb 7 weeks ago 5.55MBBusyBox
組み込み系のシステムでよく利用されているLinuxディストリビューションのようです。/bin/busyboxというバイナリにユーティリティを集約してサイズを縮小化を図っているようです。
必要最低限のものしか提供されておらず、パッケージマネージャーも提供されていません。そのため、これをベースに足りないパッケージを追加して環境を作るというのはあまり向いていません。
bashは提供されておらず、代わりにash(Almquist Shell)と呼ばれる軽量なシェルが提供されています。BusyBox
BusyBoxベースのDockerイメージ=> https://hub.docker.com/_/busybox利用イメージ
vagrant@nfsserver:~$ sudo docker container run -it --rm busybox sh / #これでbusyboxのコンテナ起動して、shで接続した状態になるので、このコンテナ内での操作が可能です。exitで抜けるとコンテナ終了して破棄されます。
-i: 標準入力をオープン
-t: 仮想端末を割り当て
--rm: 終了時にコンテナ破棄上で起動中のコンテナに別のシェルを接続する場合
vagrant@nfsserver:~$ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f374592aa2f1 busybox "sh" 54 seconds ago Up 53 seconds modest_cerf vagrant@nfsserver:~$ sudo docker container exec -it f374592aa2f1 sh / #Alpine Linux
Alpine Linuxも軽量なLinuxディストリビューションの一種で、busyboxをベースに利用しやすいように機能拡張がされているようです。
特徴的なのは、apkというパッケージマネージャーが提供されている点です。Ubuntuのaptとは若干コマンドのキーワード等が異なるようですが、それほど違和感なく使えそうです。
apk update: ローカルのインデックスキャッシュの更新
apk serach: 利用可能なパッケージの検索
apk add: パッケージのインストールAlpine Linux
Alpine LinuxベースのDockerイメージ=> https://hub.docker.com/_/alpine利用イメージ
vagrant@nfsserver:~$ sudo docker container run -it --rm alpine ash / # tree -? ash: tree: not found / # apk update fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz v3.10.3-77-g9739986c1e [http://dl-cdn.alpinelinux.org/alpine/v3.10/main] v3.10.3-68-ge1e42c5d6c [http://dl-cdn.alpinelinux.org/alpine/v3.10/community] OK: 10341 distinct packages available / # apk search tree tree-1.8.0-r0 lddtree-1.26-r2 samba-client-4.10.11-r0 libnl3-cli-3.4.0-r0 geany-plugins-treebrowser-1.35-r0 freeradius-3.0.20-r1 ostree-dev-2019.1-r0 perl-xml-treepp-0.43-r1 gconf-3.2.6-r5 perl-xml-treepp-doc-0.43-r1 perl-html-tree-5.07-r0 psmisc-23.2-r1 pstree-2.39-r0 perl-html-tree-doc-5.07-r0 ostree-2019.1-r0 py-django-treebeard-4.3-r0 perl-tree-simple-doc-1.33-r0 mtools-4.0.23-r0 i3wm-save_tree-4.16.1-r2 perl-template-toolkit-2.29-r1 git-subtree-2.22.2-r0 perl-tree-dag_node-1.31-r0 pax-utils-1.2.3-r0 rspamd-1.9.4-r0 libmtp-examples-1.1.16-r0 ostree-doc-2019.1-r0 perl-tree-dag_node-doc-1.31-r0 pstree-doc-2.39-r0 perl-tree-simple-1.33-r0 git-subtree-doc-2.22.2-r0 tree-doc-1.8.0-r0 / # apk add tree (1/1) Installing tree (1.8.0-r0) Executing busybox-1.30.1-r2.trigger OK: 6 MiB in 15 packages / # tree -? tree: Invalid argument -`?'. usage: tree [-acdfghilnpqrstuvxACDFJQNSUX] [-H baseHREF] [-T title ] [-L level [-R]] [-P pattern] [-I pattern] [-o filename] [--version] [--help] [--inodes] [--device] [--noreport] [--nolinks] [--dirsfirst] [--charset charset] [--filelimit[=]#] [--si] [--timefmt[=]<f>] [--sort[=]<name>] [--matchdirs] [--ignore-case] [--fromfile] [--] [<directory list>]※alpineのコンテナに入ってtreeコマンド実行すると、デフォルトでは提供されていないので、apkによりtreeパッケージを追加インストールしている例です。
その他メモ
Go言語(コンテナと関係ないけど...)
インストールvagrant@ubuntu-xenial:~/docker_test/test01$ go version プログラム 'go' はまだインストールされていません。 'go' を利用するために、コンピュータの管理者に 'golang-go' をインストールすることを相談してください vagrant@ubuntu-xenial:~/docker_test/test01$ sudo apt-get update ヒット:1 https://download.docker.com/linux/ubuntu xenial InRelease 取得:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [109 kB] ヒット:3 http://archive.ubuntu.com/ubuntu xenial InRelease <略> 取得:12 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 DEP-11 Metadata [5,328 B] 1,582 kB を 13秒 で取得しました (115 kB/s) パッケージリストを読み込んでいます... 完了 vagrant@ubuntu-xenial:~/docker_test/test01$ sudo apt-get install golang-go パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 <略>実行例vagrant@ubuntu-xenial:~/docker_test/test01$ cat main.go package main import ( "fmt" "log" "net/http" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ log.Println("received request") fmt.Fprintf(w, "Hello Docker!") }) log.Println("start server") server := &http.Server{Addr: ":8080"} if err := server.ListenAndServe(); err != nil { log.Println(err) } } vagrant@ubuntu-xenial:~/docker_test/test01$ go run main.go 2019/09/26 08:51:51 start server
- 投稿日:2019-10-02T08:35:28+09:00
dockerのコンテナの中に入る
- 投稿日:2019-10-02T07:59:27+09:00
【Rails on Docker on Heroku】ActiveStorage + Cloudinaryで画像を管理するメモ
はじめに
この記事はRuby on RailsのActiveStorageとCloudinaryを使って画像を管理するアプリを作るためのメモです。PaaSとしてHerokuを使います。
ActiveStorageはRails 5.2以上で動作するクラウドストレージサービスへのファイルのアップロードやActiveRecordオブジェクトへのファイルのアタッチをやってくれる便利なモデルです。
Cloudinaryは画像や動画のCDNや編集の機能を有するSaaSです。Herokuのadd-onsとしても存在しています。
この記事のゴール
この記事では、Heroku上でユーザー名とプロフィール写真を管理するRuby on Railsアプリケーション(on Docker)をHeroku上で動作させることをゴールにします。DB/StorageはHerokuのadd-onsからPostgres/Cloudinaryを使います。
前提
- Rails on Dockerの準備ができていること --> Quickstart: Compose and Rails | Docker Documentation
- Herokuのアカウントが準備できていること
メモ
1. ActiveStorageのアプリを作る
こちらの記事が参考になりました。
【Rails 5.2】 Active Storageの使い方 - QiitaまずファイルをアタッチするモデルとしてUserモデルをscaffoldで作っておきます。
$ docker-compose run --rm web rails g scaffold user name:string $ docker-compose run --rm web rails db:migrate続いて、ActiveStorageをインストール。
$ docker-compose run --rm web rails active_storage:install $ docker-compose run --rm web rails db:migrateActiveStorageはモデルに
has_one_attached
を定義するだけでファイルを扱えるようになる優れものです。app/models/user.rbclass User < ApplicationRecord has_one_attached :photo endこれで
photo
という名前のファイルをActiveStorageが勝手に管理してくれます。
ファイルのアップロードと参照ができるようにview/controllerも手直ししておきます。app/controllers/users_controller.rbdef user_params # photoの登録を許可 params.require(:user).permit(:name, :photo) endapp/views/users/_form.html.erb<!-- 以下をいい感じのところに追加 --> <div class="field"> <%= form.label :photo %> <%= form.file_field :photo %> </div>app/views/users/show.html.erb<!-- 以下をいい感じのところに追加 --> <div> <% if @user.photo.attached? %> <%= image_tag @user.photo %> <% end %> </div>これで
User
モデルでphoto
としてファイルを管理できるようになりました。
この段階ではphoto
として登録されるファイルはstorage/
に保存されていきます。これはconfig/environments/development.rbconfig.active_storage.service = :localconfig/storage.ymllocal: service: Disk root: <%= Rails.root.join("storage") %>で定義されています。
2. Herokuの準備
HerokuはHeroku CLIで操作していきます。まずはadd-onsでpostgresとcloudinaryの準備が必要です。まずHerokuにログインしてアプリを作成します。
$ heroku login $ heroku create app-nameこのアプリに対してpostgresとcloudinaryのadd-onsを追加してきます。postgresは無料のhobby-dev、cloudinaryも無料のstarterというプランを使っていきます。cloudinary:starterはクレカ登録してないと使えないみたいですね。
$ heroku addons:create heroku-postgresql:hobby-dev $ heroku addons:create cloudinary:starter3. ActiveStorageとCloudinaryを連携させる
ActiveStorageとCloudinaryを連携させるためにGitHub - 0sc/activestorage-cloudinary-serviceを利用します。
READMEの通りにやっていけばOKです!
Gemfilegem 'cloudinary', require: false gem 'activestorage-cloudinary-service'$ docker-compose buildCloudinaryと連携するための
cloud_name
、api_key
、api_secret
の情報をRailsアプリに登録してきます。これらの情報はHerokuサイトでOverviewのところから各アドオンのサイトにリンクされているんですが、リンク先のCloudinaryのDashboardに情報が載ってます。
Rails5.2以降であればcredentials
を利用しているかと思いますので、そちらの方法で。$ docker-compose run --rm -e EDITOR="vim" web rails credentials:editcloudinary: cloud_name: xxxxxxxxxx api_key: xxxxxxxxxx api_secret: xxxxxxxxxx※vimがないとか言われる場合は【Rails 5.2.2】Rails on Dockerでcredentialsをeditしたい - Qiitaあたりを参考にしていただけますと!
この設定をconfig/storage.yml
から呼び出します。config/storage.yml# 以下を追加 cloudinary: service: Cloudinary cloud_name: <%= Rails.application.credentials.dig(:cloudinary, :cloud_name) %> api_key: <%= Rails.application.credentials.dig(:cloudinary, :api_key) %> api_secret: <%= Rails.application.credentials.dig(:cloudinary, :api_secret) %>そして、
config/environments/development.rb
で指定されているconfig.active_storage.service
も書き換えます。config/environments/development.rb# config.active_storage.service = :local config.active_storage.service = :cloudinary本当は
production.rb
を書き換えて、heroku側のconfigもRAILS_ENV=production
とするべきなのですが、今回のメモはお試しなのでdevelopmentで進めますね。ここまででRailsアプリ、Herokuのadd-onsの準備は完了になりますので、あとはこのアプリをdeployしていくだけです。
4. Rails on DockerをHerokuにDeployする
Rails on DockerのHerokuへのDeploy方法は以下の記事でもまとめています。
Rails on DockerをHerokuでDeployするまで - Qiitaこの記事ではpostgresのadd-ons追加などが完了しているので必要なところだけ書いていきます。
$ heroku container:login $ heroku container:push web $ heroku container:release web $ heroku run rails db:migrateこれでアプリのデプロイが完了するはずなので、あとはサイトを開いてみます。
$ heroku openローカルでテストしてみた時と同じようにファイルをアップロードできるはずです。
また、Cloudinaryのサイトの「Media Library」にその画像ファイルが登録されているのみ見れるはずです。ちなみにActiveStorageはそのモデルが削除されるときに画像ファイルも一緒にdeleteしてくれるのもすごい便利ですね。
あとがき
ということで、Rails on Docker on HerokuでActiveStorage + Cloudinaryの画像管理ができました。
Carrier Waveとかなしで画像扱えるのは便利でした〜。herokuも1コマンドでアドオンが追加できて便利!