20210510のdockerに関する記事は8件です。

初めてのDockerのお勉強〜備忘録〜

はじめに 書いているうちに長くなってしまったので、ストック/LGTMしてお暇なときに読んでください。誤字・脱字はひっそりと直していると思います。 初めて Docker というものに触れるにあたって、一から勉強していくことにしました。ここでは、私が勉強した内容を、私なりに簡潔にまとめていくことを目指します。そこで、記事としては見づらくなることを承知の上で、敢えて勉強していく過程で直面した順(をベース)に話を進めていくことにします1。 備忘録として残すことが主な目的ですが、経験を積むためにも投稿することにしました。極力間違いのないようにしていますが、理解不足などによる間違いが無いとも言い切れません2。その際は是非ご指摘頂けますと幸いです。 ※ 本記事に書いてあることは、基本的にブログ記事3を参考にしてまとめているので、より詳細に知りたい場合にご参照下さい。 Dockerとは まず、Dockerとはそもそも何者なのかについてまとめていきます。Dockerとは、簡単に一言で言うと、コンテナを扱うための便利なツールです。 Dockerを利用することで、誰かと共同作業する時に自慢の煩わしさを発揮する様々な環境整備(「環境整備」という言い回しの厳密性には触れませんがご容赦下さい)を高速・確実・楽にしてくれるようです。 コンテナとは コンテナ(型仮想化)4は、1種の仮想化手法です。 Dockerを初めて勉強する人が「仮想化」と言われると、VirtualBoxやParallels Desktopのように、仮想化用のソフトウェアをインストールして、その上でホストOS5とは異なるOS(ゲストOS)を利用する技術を思い浮かべるでしょう(私はそうでした)。 これに対して、コンテナでは、ホストOSのコマンドやライブラリから隔離された場所で、ホストOSのカーネルとコンテナ独自のコマンドやライブラリを利用して、あたかも別なOSが動いているように動作してくれます。そのため、コンテナは仮想化ソフトウェアやゲストOSを必要とせず、高速に動いてくれるのです。 仮想化とコンテナ(より良い図を描ける気がしないので 引用3) 上図のように、通常のプロセスではホストOSのコマンド・ライブラリを使用してホストOSのカーネルにアクセスします。 一方、コンテナはホストOSのコマンド・ライブラリから隔離されていて、コンテナ内のものを使用しますが、コンテナ内にはゲストOSが存在しないため、ホストOSのカーネルにアクセスします6。 コンテナのOSについて $ docker run -it centoOS:centoOS7 /bin/bash (まだ下の基本的な使い方を見ていない方の実行はオススメしませんが、)このコマンドを実行することで、CentOS7の環境を作ってbashを起動できます。(-itは実行時のオプション指定です) このOSのイメージは、Docker Hubという、インターネット上に公開されているリポジトリから取得されるそうです。 Docker を使う 前提 使用環境は下記の通りとします。 macOS Catalina バージョン10.15.7 この使用環境を前提に話を進めていきますが、ご了承ください。 他のOSなど、詳しくは、公式ドキュメント Docker docs の Supported platforms から、ご自身の使用環境への対応をご確認ください。m(_ _)m 準備 Mac で Docker を使用するために、 Docker Desktop for Mac をインストールします。 インストールが完了したら、 Docker.dmg を実行してアプリケーションを追加します。 これで Docker がお手元の Mac で利用することができます。 チュートリアル(になってたら嬉しい) コンテナの起動 Docker コンテナを起動するために以下のコマンドを実行します。 $ docker run --name tutorial centos:centos7 /bin/echo hoge 書式: docker run --name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実行するコマンド] 実行結果: hoge hogeと出力されました。 コマンドの書式について docker は、(筆者の経験上) Docker コマンドにはお決まりでくっついています。 run は、Docker コンテナを起動するための命令で、他にも起動中のコンテナを一覧で確認する ps など、様々な命令があります。 --name は、起動するコンテナに名前をつけるためのオプションです。上記のコマンドでは、tutorial という名前がつけられています。 centosは、Docker Hub 上での CentOS のOSを提供しているイメージの名前です。 centos7は、上で指定したイメージの中から、centos7というタグのつけられたバージョンのイメージを取得することを意味します。 /bin/echo hogeは、書式の通り、コンテナ起動直後に実行するコマンドです。今回の場合は、よく見る(?)echoコマンドで、実行結果のようにhogeを出力しています。/bin/echoはコマンドなので、実際にはホストOSのカーネルを利用しています。 ※ 本来、イメージを取得するには、Docker pull centos:centos7というコマンドが使用されますが、Docker runコマンドでも、指定したイメージが取得されていなければ自動で取得してくれるみたいです。 コンテナの確認 コンテナの起動をしたら、次のコマンドを実行してコンテナの状況を確認してみましょう。 $ docker ps 実行結果: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 表の列名のようなものしか出てこない。。。? docker psは、稼働中のコンテナの一覧を表示してくれます。 実は、コンテナは、起動した後、指定のコマンドを実行すると(内部で動作しているプロセスが終了すると)停止するようになっています。 では、停止中のコンテナも表示してくれるオプションをつけて再度確認してみましょう。 $ docker ps -a 実行結果: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 53f4db7f38f4 centos:centos7 "/bin/echo hoge" 12 minutes ago Exited (0) 12 minutes ago tutorial 各列の説明 CONTAINER_ID : 作成されたコンテナのID(上の例とは異なるはずです) IMAGE : コンテナに用いられていたイメージとそのタグ COMMAND : 起動直後に実行されたコマンド CREATED : コンテナが作成された時間(上の例とは異なるはずです) STATUS : コンテナの状態(時間の部分は、上の例とは異なるはずです) PORTS : ポートの接続関係(詳細は割愛) NAMES : コンテナの名前 確かに、tutorialという名前のコンテナがありますね。 STATUSがExitedになっていることから、コンテナが稼働中ではないことがなんとなくわかると思います。 また、COMMANDを見ると、/bin/echo hogeとなっています。 初めにコンテナを起動したときに、実行されるコマンドが決まるんですね。 コンテナの削除 (気にならない人は、やり方だけ確認して飛ばしてもらっても結構です) では、停止したまま残っているコンテナを一度削除してしまいましょう。 コンテナの削除には、次のコマンドを実行します。 $ docker rm tutorial 書式: docker rm [コンテナ名 or コンテナID] これで、先ほど作ったコンテナが削除されているはずです。docker ps -aで確認してみてください。 ちなみに、docker rm $(docker ps -aq)とすることで、停止している全てのコンテナを削除できます。 また、docker imagesでイメージの一覧表示、docker rmiで指定したイメージの削除もできます。 コンテナの起動(2) それでは、改めてコンテナの起動をしてみましょう。 次は、起動してもすぐに停止することのないようなコンテナを作成します。 $ docker run -itd --name tutorial2 centos:centos7 /bin/bash 実行結果: 3e98ba03038860506113697a075c4d2ce9a9a2a730edd3db3c625a099acada31 実行結果では、何やら不思議な数字と文字の羅列が出力されていると思います。 docker psで確認してみると、 3e98ba030388 centos:centos7 "/bin/bash" 3 seconds ago Up 3 seconds tutorial2 STATUSがUpのtutorial2という名前のコンテナが出来ていると思います。 コマンドの中で、コンテナの起動の時と違う部分について説明します。 /bin/bash先ほどは、/bin/echo hogeとなっていました。これは、bashを起動することになります。今皆さんが使っているはずのものです。(mac なら bash だったり zsh だったり) -itdはオプションです。オプションは繋げられるので-i -t -dでも同じです。 -i : interactive らしいです。インタラクティブシェルってことですね。ホストの標準入力をコンテナの標準入力にせつぞくしてくれるらしい。 -t : tty だそうです。どうやらコンテナ内の標準出力をホストの標準出力に繋いでくれるらしい。 -d : detach-mode らしい。バックグラウンドでコンテナが実行されます。 (run)コマンドのオプションについてはDocker公式のリファレンスなどを参照してみてください。 ※ ちなみに、オプションについては、-id、-tdでも同様の結果が得られました。これは、筆者自身、解釈に自信がないのですが、-dのみでは、バックグラウンドで実行された際に入出力プロセスが終了しているためにコンテナが停止してしまい、-iか-tどちらかでも追加されることで、入出力のプロセスが生き残ってコンテナが稼働したままなのだと思っています。(偉い人教えてください。。) コンテナにログイン 先ほどのコマンドを実行しただけでは、コンテナは稼働中でもコンテナを「使う」ことはできていないですよね。 オプションの説明でも描いたように、コンテナはバックグラウンドで動いています。 そこで、裏で待機してくれているコンテナに、下のコマンドでログインします。 $ docker exec -it tutorial2 /bin/bash 書式: docker exec [オプション] [コンテナ名 or コンテナID] [コマンド] 実行結果: [root@3e6c16e91968 /]# 上記のように、root@[コンテナID]という形でコンテナ内のbashに入れたと思います。 ここで、echo hogeを実行すると、期待通りhogeが出力されます。 コンテナを抜けるときは、exitコマンドを使用します(通常のターミナルのコマンドを同じですね)。 コンテナを抜けた後、もう一度docker psを実行すると、コンテナがちゃんと裏で待機してくれていることがわかります。 コンテナの停止 コンテナtutorial2は、バックグラウンドで稼働しているため、こちらから停止させる手段が欲しくなりますね。 そんなときには、次のコマンドを実行します。 $ docker stop tutorial2 実行結果: tutorial2 シンプルですね。docker psとdocker ps -aの出力を比較するとコンテナが停止していることをより実感できると思います。 コンテナの再起動 tutorial2コンテナを停止したけど、もう一度使いたい場合には、下のコマンドでコンテナを再起動してあげます。 $ docker restart tutorial2 書式: docker restart [コンテナ名 or コンテナID] これで、tutorial2コンテナを初めて起動した時を同じように、バックグラウンドで待機している状態になります。 最後に これで、Dockerのインストール、イメージの取得、コンテナの作成・起動、停止、再起動、ログイン、削除ができると思います。 ひとまず、ここまでで今回のまとめは終わりにしたいと思います。 筆者自身まだまだ勉強中の身なので、これからも頑張っていきたいと思います。 結論:世のエンジニアは偉い(異論は認めません) 用語などの全ての説明を保証する記事ではありません。 ↩ 特に、表現の仕方などには曖昧な表現が多分に含まれている可能性があります。 ↩ 【連載】世界一わかりみが深いコンテナ&Docker入門 ↩ 「コンテナ」という概念自体はDockerに特有のものではなく、(例えば、プログラミングにおけるデータ構造やクラスなど)いくつかの種類を持っているようです。 ↩ 実際に使用しているマシンのOS ↩ ホストOSのカーネルを利用するので、ホストOSのカーネルが対応していない操作はできないようです(ex : ホストが MacOS 系なのにコンテナ内では WindowsOS 系の操作を要求する場合) ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerイメージからコンテナを立ち上げる

背景 Dockerイメージからコンテナを立ち上げる方法が毎回「どうやるんだっけ」となっているので、メモしておく。 ちゃんと検証してないので、間違っていたらすみません!自分用のメモです! 結論 foo@gpu:~$ docker run -it --name container_name -d -p 5060:5000 \ -e SOME_ENV=foobar -v /home/foo/bar:/var/bar --restart=unless-stopped \ image_name python /var/bar/baz.py オプション(or上での文字列) 何をしているのか -i コンテナの標準入力を開きます。 -t ttyをつなげます。 --name コンテナ名を指定します。 -d コンテナをバックグラウンドで実行します。 -p ホストとコンテナのポートをつなぎます。(例ではホストの5060とコンテナの5000をつなぐ。) -e コンテナ内の環境変数を設定します。 -v マウントします。(例ではホストの/home/foo/barディレクトリとコンテナの/var/barディレクトリ) --restart 停止した場合に自動再起動するかどうかのオプション(no/on_failure/on_failure:回数n/always/unless-stopped) (image_name) 利用するDockerイメージ名を指定します。 (python /var/bar/baz.py) コンテナで実行するコマンド ※オプションは他にもありますが、基本的なものを列挙してます。 作ったコンテナに入るのは、以下。 foo@gpu:~$ docker exec -it container_name /bin/bash 補足 docker-composeで同じことをする場合は、以下のdocker-compose.ymlがあるのと同じディレクトリでdocker-compose up -dを実行します。 docker-compose.yml version: '3.8' services: container_name: image: image_name container_name: container_name stdin_open: true tty: true ports: - 5060:5000 environment: - SOME_ENV=foobar volumes: - /home/foo/bar:/var/bar restart: unless-stopped command: python /var/bar/baz.py
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[自分用メモ]Dockerのまとめ

はじめに 本記事は完全自分用の記事になります。予めご了承下さい Dockerとはなにか コンテナ型の仮想環境を作成、実行するためのプラットフォームのこと ユースケース ・アプリケーション開発環境 ・検証環境、本番環境 ・Webサーバ、データベースサーバなどの構築 Docker導入のメリット ・再現性の高い環境を用意できる ・プログラムの実行環境を素早く立ち上げることができる ・設定ファイル共有すればPJメンバーで同じ環境を立ち上げることができる ・PC環境を汚さずに済む(ごちゃつかない) ホスト型仮想化とコンテナ型仮想化 ホスト仮想型ハイパーバイザーのうえに、それぞれの複数の仮想マシンがあり、それぞれがゲストOSをもっている。そのため、イメージサイズが大きく、通常のOSと同じように起動に時間がかかる。また、ハードレベルで分離しているので分離レベルが大きい。 一方で、コンテナ型仮想化はDockerエンジンの上にこれぞれのコンテナがあり、これらはホストOSを共有する。そのため、イメージサイズが小さく軽量である。しかし、複数のOSは導入できない(ホストOSがひとつのため)。また、分離レベルは低い。 Dockerイメージ コンテナの雛形で、コンテナ実行に必要なファイルをまとめたファイルシステム。 イメージ上のデータはレイヤで構成され読み取り専用 コンテナを移動すると、コンテナレイヤーが追加され、このレイヤーは読み書き可能である コマンド一覧 以下にコマンドを一覧として記載してます。役割については、コメントアウトで記載中! $ docker images #取得したイメージの一覧 $ docker tag docker/whalesay my_whalesay #イメージ名を変える、ただしImageIDは変わらない $ docker tag docker/whalesay my_whalesay:ver1 #上記と同じだが、ImageIDも変わる $ docker inspect my_whale #詳細情報の表示 $ docker rmi docker/whalesay #イメージ削除 $ docker rmi -f docker/whalesay #イメージ強制削除 $ docker pull docer/whalesay #イメージを取得 $ docker build -t docker-whale . #Dockerfileからイメージをビルドするコマンド #docker hubにプッシュするための一連操作 $ docker login $ docker tag docker-whale ~~~/docker-whale:ver1 # Docker ID リポジトリ名/イメージ名:タグ名 $ docker push ~~~/docker-whale:ver1 $ docker run --name コンテナ名 -d -p ホスト側ポート番号:コンテナ型ポート番号 イメージ名#例:nginxのコンテナを立ち上げる方法(バックグラウンド) #nginxのコンテナを立ち上げるコマンド〜バインドマウントを使用するケース〜 $ docker run --name コンテナ名 -d -v ホストディレクトリ:コンテナ側のマウントポイント: $ docker cp <ホスト上のコピーしたいファイルパス> <コンテナ名>:<コピー先> $ docker cp <コンテナ名>:<コピーしたいファイルパス> <コピー先のパス> $ docker ps #コンテナ一覧 -aで起動してないものも表示 $ docker exec -it <コンテナ名> /bin/bash # コンテナのシェルに接続するコマンド,exitしてもコンテナは終了しない $ docker commit <コンテナ名> <イメージ名>:<タグ名># コンテナからイメージを作成,docker historyコマンドに記録されない おわりに Dockerの勉強超絶楽しいです(笑) 引き続き続けてまいります!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VScodeで日本語版LaTexをコンパイルするためにWindows版Dockerでtexlive-jaをインストールした

下図のようになった >docker run -d -p 80:80 docker/getting-started docker: error during connect: This error may indicate that the docker daemon is not running.: Post "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/create": open //./pipe/docker_engine: The system cannot find the file specified. See 'docker run --help'. daemonが動いていないと返答があったので原因を探った結果,Hyper-Vの有効化を行っていなかったことが原因だった Hyper-Vの有効化 仮想マシンを使うために必要らしい DockerDesktopのインストールとユーザー登録をおこなう https://docs.docker.com/docker-for-windows/install/ インストールしたら 右上歯車マークを押してUse the WSL based engine のチェックを外す あとの作業は以下のサイトが詳しく説明してくださっている
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OS XのアップデートしたらDockerが使えなくなった

事象の説明 OS Xのソフトウェア・アップデートを行いました。 すると、「Docker Desktop is starting...」とステータスに表示されたまま変わらず、Dockerが起動しなくなりました。 環境 使用しているPC MacBook Pro (13-inch, M1, 2020) チップ Apple M1 アップデートしたOSのversion macOS Big Sur ver 11.3.1 解決方法 以下のページで「AppleチップのMac」を押して、Dockerをインストールし、使用していたDockerと置き換えたところ解決しました。 元々M1チップMacは従来のインストールだとDockerは使えませんでした。 そのため、以下のページを参考に使えるように設定しました。 現在はM1チップに対応したDockerがリリースされているので、そちらをインストールすれば大丈夫です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

njsでAPIGatewayっぽいものを作ってローカルでLambdaを動かしてみる

そもそもnjsとはなんぞや?という感じですが、簡単に言うとNginxをJavaScriptで制御できるようにするためのモジュールです。 njsだけでなくメジャーなものでLuaというスクリプト言語があり、そちらの方が歴史も古く、nginxに対する制御も色々できるようですが、新しい構文を覚えるのが面倒だったので選択しませんでした。 njs自体の初出がここ最近ということもあり、ほとんどネット上に情報がなかったので筆を取りました。 経緯とか 個人でNext.jsで開発をしていたのですが、ローカルでLambda関数の実行ができてそのコードをそのままAWSに上げて実行することができた方が楽なのでまずバックエンド側の開発環境を作ろうというところが始まりでした。 まぁ既にDockerイメージにそういう感じのがあるだろうと思って探すと、amazon/aws-lambda-ruby:2.7というイメージがありました。 早速使ってみると curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}' といった感じで実行するとのことでした。 おや・・・?これだとパスとか指定できなくない? という感じで少し困りましたが、Lambda関数毎にDockerコンテナ作ってURLとコンテナを紐付けるミドルウェア的なルーター的なコンテナがあればいいんじゃね?という解決策を思いつきました。(後から調べるとAWS SAM Localを使うのが一般的という感じがしたので当時の自分に誰か教えてくれ。) 最初は脳死でRailsとかLaravelでルーティングしようとか思っていたのですが、ルーティングだけ使うのにフレームワークを入れるのは明らかにオーバースペックだったので、じゃあphp-fpmとかRackだけ入れてルーティング用のスクリプトを噛ませようと思いましたが、ブラウザ→Nginx→hoge.rb→Lambdaというリクエストのリレーは効率が悪いのと、結局hoge.rbからHttpClientを実行する必要があるので管理が面倒と感じて、nginxだけでリクエストとレスポンスを整形してプロキシできないか?という感じで調べてnjsに辿り着いたというわけです。 なので最初からnjsを使おうと思って使ったわけではありませんでした。 とりあえず作ってみる えみゅれーたーって言ってみたいのでapi_gateway_emulatorとしています。 あくまで「っぽいもの」なので、自分がローカルで開発するための最低限の部分しか作っていないのでご注意ください。 Dockerfile(api_gateway_emulator) # 1.19なら最初からnjsのモジュールが使える FROM nginx:1.19-alpine RUN apk --update add \ bash \ && rm -rf /var/cache/apk/* WORKDIR /api_gateway_emulator/js # njsのモジュールを読み込むconf COPY ./docker/settings/api_gateway_emulator/nginx.conf /etc/nginx/ # ルーティング等を行うconf COPY ./docker/settings/api_gateway_emulator/default.conf /etc/nginx/conf.d/ COPY ./docker/settings/api_gateway_emulator/js/* /api_gateway_emulator/js/ Dockerfile(Lambda) FROM amazon/aws-lambda-ruby:2.7 # ローカルにfunctionsディレクトリを作り、Lambda用のファイルを入れておく COPY ./functions/* /var/task/ nginx.conf ... # モジュール読み込み load_module modules/ngx_http_js_module.so; load_module modules/ngx_stream_js_module.so; ... http { ... } default.conf # jsファイルをインポート js_import /api_gateway_emulator/js/main.js; # jsの関数をインポートしてconf上で使用できるようにする js_set $createUrl main.createUrl; server { # subrequest(後述)を利用した場合、 # デフォルトのDNSサーバーで名前解決できなくなるので # DockerNetworkで名前解決をする resolver 127.0.0.11 ipv6=off; ... # バッファを設定する # 値は適当ですがファイルアップロードをしたい場合等に調整する必要があります subrequest_output_buffer_size 600k; # Originは開発環境に合わせて変更する add_header Access-Control-Allow-Origin 'http://localhost:22281'; add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS'; add_header Access-Control-Allow-Headers 'Accept,Authorization,Cache-Control,Content-Type,Keep-Alive,Origin,User-Agent,Cookie'; add_header Access-Control-Allow-Credentials true; # preflight対応 if ($request_method = 'OPTIONS') { return 200; } # ここを通してLambdaのコンテナにプロキシする location /container/proxy { proxy_pass $url; } # まずここにマッチする location / { # subrequest後に元のURIが保持されないようなのであらかじめ変数に入れておく # ここでlocalhost:9000/2015-03-31/...からコンテナ名への変換を行う # (http://container_name:9000/2015-03-31/...といった形) set $url $createUrl; # このjs内でLambdaが受け取れる形にRequestの整形をする # その後、/container/proxyへsubrequestを行う js_content main.requestLambda; } ... } default.confは結構ハマりポイントが多かったです。 subrequestはNginxの内部向けのリクエストと解釈していますが解釈として正しいかはわかりません。 /container/proxyはsubrequestを送るパスですが、別に名前はなんでもいいです。 js_setもNode.jsのimportっぽいようなそうでもない感じで、set $url $createUrl;も分かりにくいと思いました。 実際は$urlという変数に$createUrlという変数の中に入った関数(第一引数にリクエスト情報が入ったオブジェクトが暗黙的に入る)の結果をセットするという挙動になります。 続いてnjsの中身ですが、情報がないのでひたすらリファレンスを見るしかないです。 なのでnjsの記事を他の人も書いてくれという気持ちを込めてこの記事を書いています。 Lambda用のマッピングはこちらを参考にしました。 main.js // 必ず引数rをとる // rはリクエストに関する全ての値が入っている function requestLambda(r) { // Lambda用にリクエストを整形 r.subrequest("/container/proxy", { method: r.method, body: JSON.stringify({ "httpMethod": r.method, "headers": getHeaders(r), "body": r.requestBody, "queryStringParameters": r.args }) }) .then((result) => { // レスポンスの整形 var body = JSON.parse(result.responseBody); var responseBody = {}; if ("body" in body) { responseBody = body.body; } // ヘッダを読み取ったり整形したり if ("headers" in body) { ... if ("Location" in body.headers) { // リダイレクトの場合 r.return(301, body.headers["Location"]); return; } } // r.returnでブラウザにレスポンスを返して終了 r.return(body.statusCode, responseBody); }) .catch((result) => { // エラーの場合 // r.errorはコンソールにログ出すのに便利 r.error(result.message); r.return(result.status, result.message); }); } ... // 実際にコンテナ用のアドレスに変換している箇所 function createUrl(r) { var domain = convertSlash(r.uri); return "http:/" + domain + ":9000/2015-03-31/functions/function/invocations"; } // conf上で使う関数をエクスポートする export default { createUrl, requestLambda }; 流れをまとめると、 ブラウザから/hogehogeにリクエスト→location /でキャッチ→njsでリクエスト整形->/container/proxyにsubrequestを送る→Lambdaコンテナへproxyされる→njsでレスポンス整形→ブラウザにレスポンスを返すという感じになります。 実装は以上で、あとはdocker-compose.ymlを見ていきましょう。 docker-compose.yml version: '3' services: api_gateway_emulator: build: context: . dockerfile: ./docker/images/api_gateway_emulator/Dockerfile networks: - api_gateway_emulator ports: - 22280:80 command: bash -c "/usr/sbin/nginx -g 'daemon off;'" base: &lambda container_name: base build: context: . dockerfile: ./docker/images/lambda/Dockerfile volumes: - ./functions:/var/task:cached command: base.handler networks: - api_gateway_emulator tty: true # 関数が増えた場合はbaseを継承して追加していくだけ google_redirect: <<: *lambda container_name: google_redirect command: google_redirect.handler networks: api_gateway_emulator: external: true 関数が増えてもcontainer_nameとcommandを追加していくだけなので簡単です。 この状態でdocker-compose upをすればcurl http://localhost:22280/baseのようにすれば結果が返ってきます。 あとはdocker networkで他のコンテナから繋いだりして開発していくことができます。 解説用にコード改変や省略をしているので、全コードはgitに置いてあります。 誰かの参考になれば幸いです。 あとがき 今回njsでAPI Gatewayっぽいものを作ってみましたが、かなり色々応用が効く技術だと思います。 開発環境で外部APIを利用箇所用のMockサーバーを作ったりできますし、LuaだとできるようですがNginxから直接MySQLを実行できるようになればマイクロサービスであればバックエンドのフレームワークが不要になるかもしれません。 そうなるとnjs部分をTypeScriptで記述したりすることにもなると思います。 Luaすごい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker環境でサクッとPythonコードの文法確認をする

はじめに 軽くコードを実行して文法を確認したいとき、ローカルで行おうとするとファイルの保存場所など少し考えることがあります。 使い捨てのDockerコンテナを利用することで、何も考えることなくテストすることができるので、便利に思いました。 動作環境 Windows Terminal Docker Ubuntu20.04LTS(WSL2) 手順 ここでは、「JSONの読み込み方これであってたかな?」の確認をすることにします。 # コンテナの実行(終了時に自動削除) docker run --rm -it python bash # Vimをインストール apt update && apt install -y vim # 必要なファイルを作成する(後述) # どうせ使い捨てだからルートディレクトリでいい vim data.json vim main.py # 実行 python main.py # 満足したらコンテナの終了&削除 exit ↓使用データ data.json [ { "name": "Satoshi", "age": 21 }, { "name": "Pica-Chu", "age": 17 } ] main.py import json f = open("data.json", "r") json = json.load(f) f.close print(json[0]["name"]) さいごに もちろん、ローカル環境整えたり、クラウドで試したりするのもいいです。 使い捨ての環境でかんたんに試せるというのが楽だと思い、場合によってはこれでいいだろうと思った次第です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

セットアップ - Docker on WSL 2 + Windows ターミナル

はじめに セットアップ シリーズ、Windows 10 向け Docker 編。 macOS なら Docker Desktop をインストールするだけで良いが、WSL に依存する Windows だとそうもいかない。 便利なので、WSL のついでに Windows ターミナルも紹介する。 確認環境: Windows 10 Home バージョン 20H2(ビルド 19042) Windows 10 Home バージョン 20H1(2004、ビルド 19041) WSL とは? 公式サイトでは、WSL(Windows Subsystem for Linux)を以下のように説明している。 WSL の対象ユーザーは誰ですか。 これは、主に開発者向けのツールです。 特に Web 開発者と、オープン ソース プロジェクトで作業している開発者が対象です。 これにより、Bash、一般的な Linux ツール (sed、 awk など)、および多くの Linux ファースト ツール (Ruby、Python など) を使用する必要があるユーザーは、Windows でそれらのツールチェーンを使用できます。 WSL ですべての Linux アプリを実行できますか。 いいえ。 WSL は、Bash およびコア Linux コマンド ライン ツールを必要とするユーザーが Windows 上でそれらを実行できるようにすることを目的としたツールです。 WSL は、GUI デスクトップやアプリケーション (例: Gnome、KDE など) をサポートすることを目的としていません。更新については、コマンドラインのブログを参照してください。 また、多くの一般的なサーバー アプリケーション (Redis など) を実行できる場合でも、実稼働サービスをホストする目的には WSL をお勧めしません。 Microsoft は、Azure、Hyper-V、Docker で実稼働 Linux ワークロードを実行するためのさまざまなソリューションを提供しています。 もう少し細かい話: WSL は、従来の「仮想マシン」や「デュアルブート」よりも軽量に、「Windows 環境」と「GNU/Linux 環境」を併用できる仕組み。 WSL はただの仮想マシンではなく、Linux と Windows との併用を前提としている。 今では「WSL 1」と呼ばれる初代から進化して、本物の Linux カーネルを直接実行する「WSL 2」ができた。 WSL 2 の詳細: Windows 10 バージョン 2004(20H1)で正式リリースされた。 開発中のプレビュー版を利用する Windows Insider Program への参加が不要に。 Windows 10 に Linux カーネルが含まれており、マシン上では「Windows カーネル」と「Linux カーネル」が並行稼働する。 WSL 2 は「Light Weight utility Virtual Machine」(軽量ユーティリティー VM。単に WSL 2 VM とも)という専用の仮想マシン上で動作することになる。 cf. 完全な Linux が Windows 10 上で稼働する? 「WSL 2」とは:Windows 10 The Latest - @IT Linux 側のファイルシステムは仮想ディスクを使う。 そのためルート配下は Linux の支配下で、パスには Windows の禁則文字も使えるが、Linux にマウントされた Windows 上のファイルシステムは Windows の規則に従う。 WSL 1 と比べ、WSL 2 は Windows ファイルシステムへのアクセスが低速なため、Linux 側のファイルシステムと往復する場合は WSL 1 の利用が推奨される。 その他、「WSL 1」と「WSL 2」の細かい違いは以下。 cf. WSL 2 と WSL 1 の比較 | Microsoft Docs cf. Announcing WSL 2 | Windows Command Line Docker とは? Docker 社が提供する、あらゆるアプリケーションをどこでも開発・導入・実行するためのプラットフォーム。 正確には、Linux ファイルシステムのスナップショットを Docker イメージとしてパッケージ化し、コンテナーとして動かす。 イメージは、Dockerfile(テキストファイル)上の命令文から簡単に作成できる。各命令文がレイヤーとして積み重なってイメージを作る。 コンテナーは、読み取り専用レイヤーのみで構成されるイメージに、書込み可能な最上位レイヤーが追加されたもの。 コンテナーはホスト上のプロセス ツリーから独立したプロセスで、自身のファイルシステムとネットワークを持つ。 WSL 2 の登場以降、Docker Desktop はデフォルトでは「WSL 2 VM」上で以下の 2 つのディストリビューションを動作させる方式が採用された。 docker-desktop: ブートストラップ ディストリビューション Docker エンジン本体 docker-desktop-data: データ ストア ディストリビューション Docker イメージやコンテナーを格納 WSL 2 は、現時点では追加の仮想ディスク(VHD)を直接マウントできないため、クロス ディストリビューション マウントする方式になったそうだ Windows 用 Docker のバックエンドが「WSL 2」の場合と、それ以前の「Hyper-V」の場合の違いは以下。 cf. Introducing the Docker Desktop WSL 2 Backend - Docker Blog Windows ターミナルとは? Microsoft 社の提供する、ターミナル アプリケーション。 コマンド プロンプト、PowerShell、WSL などの各種コマンドライン ツールを横断的に扱うことができる。 今回は、Ubuntu(WSL)を利用するための使う。 ? WSL 2 cf.Windows Subsystem for Linux (WSL) を Windows 10 にインストールする | Microsoft Docs システム要件: この手順は x64 マシンを想定する。 x64 システムの場合: Windows 10 バージョン 1903 以降、ビルド 18362 以上。 cf. Windows 10 のビルド番号一覧 インストール方法の違い: WSL は、現在ふたつのインストール方法がある。 ➊ 簡略化されたインストール Windows Insider Program に参加して、Windows 10 のプレビュー ビルド(OS ビルド 20262 以降)を使う ➋ 手動インストール Windows Insider Program に参加していない場合用 プレビュー版の Windows が使いたいわけではないので、「➋ 手動インストール」の方法を採用する。 インストール: 公式の手順どおり。悩む点はない。 # 管理者として PowerShell を開く # Linux 用 Windows サブシステムを有効にする PS C:\> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart # 仮想マシン プラットフォーム オプション機能を有効にする PS C:\> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # 以下のパッケージをダウンロードし、インストール # x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ # https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi # WSL 2 を既定のバージョンとして設定(デフォルトでは WSL 1 を使わないように) PS C:\> wsl --set-default-version 2 設定: メモリ枯渇問題への対策 メモ帳などの任意のテキストエディターで %USERPROFILE%\.wslconfig(C:\Users\<yourUserName>\.wslconfig) に、以下のファイルを作成する。 (この機能は Windows 10 ビルド 19041 以降でしか使えない。) .wslconfig [wsl2] memory=8GB この手順では、上記の設定反映の手順は不要。(この時点で WSL 2 VM が起動してないので) もし稼働中の WSL 2 VM があれば再起動することで適用される(wsl --shutdown or wsl -t <ディストリビューション名>)。面倒なら Windows を再起動でも良い。 (以下、細かいことが気になる方向け) 現時点の WSL 2 でも、残念ながら「メモリを食いつぶす問題」は残っているらしい。 たしかに Vmmem プロセス(WSL 2 VM 全体のプロセス?)のメモリー使用率は高いので気になる。 GitHub 上の Issues のアドバイスにしたがって、WSL のグローバルオプション設定である .wslconfig を作成し、WSL 2 VM が確保するメモリー上限を設定している。 公式サイトによれば、デフォルトのままだと PC 搭載メモリーの 80 % が上限となるそうなので、もっと安全な値に変更している。 Windows 10 ビルド 20175 以降(プレビュー版)なら、デフォルトは搭載メモリーの 50 % or 8 GB の少ない方が上限となり、この変更をする必要はない。 今回は「ビルド 20175 以降の仕様」を参考に、とりあえず 8 GB にする。 Ubuntu 20.04 Server Edition のシステム要件を参考にすると、RAM は 1 GB 以上。 Docker のシステム要件の RAM は 4 GB 以上。 上記 Qiita の参考記事では swap=0 でスワップの無効化を設定しているが、後述のとおり利用するドライブを SSD から HDD へ変更するので、今回の手順では不要。 補足: cf. Linux ディストリビューションの管理 | Microsoft Docs ディストリビューションごとの起動設定は、各ディストリビューション内の /etc/wsl.conf を参照する。 たとえば [interop] セクションの appendWindowsPath を false にすることで、WSL が Windows パス要素を $PATH 環境変数に追加しないようにできる。 今回は特に困らなかったので、設定しない。 ? Ubuntu(WSL) WSL VM 上に、Linux ディストリビューションをインストールする。 Docker を使う上では必須ではないが、WSL を試す際には何かと必要になる。 (Linux ディストリビューションがひとつもインストールされていないとエラーになったりして後々面倒なことも。) こだわりはないが、WSL は Ubuntu の開発元の Canonical 社との連携で生まれたようなので、相性の良さそうな「Ubuntu」を採用。 なお、Windows ストア上の「Alpine Linux」は、開発元(Alpine Linux development team)が公開しているわけではなさそうなので、採用を見送り。 インストール: 利用可能な Ubuntu のリリースは以下で確認できる。 https://wiki.ubuntu.com/WSL#Ubuntu_on_WSL Windows ストアへのリンクがあるので、そこからインストール。 各 LTS もあるが、今回はアプリ名に「リリースバージョンなし」の常に推奨リリースを使うものを採用。 (現在は「Ubuntu 20.04 LTS」がインストールされる。) 念の為にインストールしたディストリビューションを確認しておく。 # WSL にインストールされているディストリビューションとその詳細を確認 ## --list, -l ディストリビューションの一覧を表示します。 ## --verbose, -v すべてのディストリビューションについての詳細情報を表示します。 PS C:> wsl -l -v NAME STATE VERSION * Ubuntu Stopped 2 # バージョンが 2 なら、WSL 2 で動作している # デフォルトのディストリビューションを変更する場合は以下 # wsl --set-default <ディストリビューション名> # すでに WSL 1 で動作しているディストリビューションを WSL 2 へ移行するには以下(逆もできる) # wsl --set-version <ディストリビューション名> 2 使い方: Windows ストアからインストール後、「Ubuntu」を起動すると、Ubuntu が構築 & 起動するまでしばらく待たされる。 起動後、Linux ユーザー名とパスワードを設定を促されるので入力。(パスワードはスーパーユーザーへの昇格時に必要となるなので忘れないように。) exit コマンドで終了。 なお、WSL 上では poweroff や reboot コマンドは制限されており、利用できない。 (おそらく、WLS はひとつのハードウェア上で Windows と Linux を併用するので、何をシャットダウンするコマンドか分かりにくいため?) どうしてもディストリビューション(WSL 2 VM)を停止させたい場合は、PowerShell などから wsl -t <ディストリビューション名> コマンドを使う。 設定: cf. Docker のイメージ&コンテナの配置フォルダを変更 - Qiita WSL 2 VM のディスクは「仮想ディスク」(.vhdx)形式で保持される。 デフォルトの保存先は %LocalAppData%(C:\Users\<yourUserName>\AppData\Local)配下のため、C ドライブが SSD の場合はよろしくない。 cf. SSD の選び方(3/5):SSD の寿命を縮める使いかた - Qiita Windows ストアから取得したディストリビューションの仮想ディスクの保存先は、以下の方法で確認できる。 # cf. [Windows Subsystem for Linux 2(WSL 2)をセットアップしてみた | Developers.IO](https://dev.classmethod.jp/articles/how-to-setup-wsl2/) # PackageFamilyName を取得 PS C:> $packageName = Get-AppxPackage -Name "*Ubuntu*" | Select-Object -ExpandProperty PackageFamilyName PS C:> $packageName # 対象フォルダーを確認 PS C:> dir "$env:LOCALAPPDATA\Packages\$packageName\LocalState\" 仮想ディスクを「別のドライブ」へ移行する手順は以下のとおり。 今回は HDD の D ドライブがあるのでそこに。 # 利用中の WSL 2 VM があれば切断する # 稼働中の WSL 2 VM を確認 PS C:> wsl -l -v # 稼働中のものがあれば、以下のコマンドですべて終了させる PS C:> wsl --shutdown # vhdx を tar としてエクスポート、登録解除、tar をインポート PS C:> cd D:\ PS D:> wsl --export <ディストリビューション名> <ディストリビューション名>.tar PS D:> wsl --unregister <ディストリビューション名> PS D:> wsl --import <ディストリビューション名> <インストール先パス> D:\<ディストリビューション名>.tar # 例: # wsl --export Ubuntu Ubuntu.tar # wsl --unregister Ubuntu # wsl --import Ubuntu D:\wsl\Ubuntu D:\Ubuntu.tar # 複数の WSL 2 VM がある場合は、上記手順を繰り返す # WSL 2 VM を再確認 PS D:> wsl -l -v # デフォルトのディストリビューションが変更されている場合は、以下のコマンドで再指定 PS D:> wsl --set-default <ディストリビューション名> zsh、tmux について 別記事参照。 セットアップ - zsh - Qiita セットアップ - tmux - Qiita ? Windows ターミナル cf. Windows ターミナルのインストール | Microsoft Docs インストール: Windows ストアからインストールするだけ。 https://aka.ms/terminal 設定: 起動時に「Ubuntu (WSL)」を開くなど、設定を調整する。 Windows ターミナルを起動する。 設定 (Ctrl + ,) を開き、既定のプロファイル を Ubuntu に変更 > 保存 ボタンをクリック。 画面左のサイドバーの 三 ボタン > Ubuntu > 外観 タブで、以下を設定して 保存 ボタンをクリック。 配色: One Half Dark フォント フェイス: HackGenNerd Console Windows ターミナルの公式上では Cascadia(カスカディア) が提供されているが、日本語フォントを含んでいないので、採用は見送り。 フォントサイズ: 10 ポインター: アンダースコア(▁) 背景画像: Ubuntu 20.04 LTS (Focal Fossa) 画面左のサイドバーの 三 ボタン > Azure Cloud Shell > ドロップダウンからプロファイルを非表示にする を有効に > 保存 ボタンをクリック。 更に、Azure Cloud Shell を使う予定がないので、非表示に。 ? Docker Desktop cf. Install Docker Desktop on Windows | Docker Documentation やっと Docker Desktop のセットアップに入る。 (Docker Engine、Docker CLI client、Docker Compose、Notary、Kubernetes、Credential Helper が含まれる) システム要件: WSL 2 が有効なこと WSL2 Linux カーネル更新プログラム パッケージ がインストールされていること インストールされていない場合は、途中でインストールを促される。 インストール: インストーラーは以下から入手。 cf. Docker Desktop for Mac and Windows | Docker Docker Desktop Installer.exe を実行する。 Install required Windows components for WSL 2(WSL 2 に必要な Windows コンポーネントをインストール)にチェックが入っていることを確認する。 インストーラーに促されるまま OS 再起動後する。 Docker Desktop が再起動するので、しばらく待つ。 (タスクトレイのクジラのアイコンのアニメーションが止まるまで数分かかった) タスクトレイから Docker Desktop の画面を表示すると、チュートリアルが開始される。 (別に初学者に優しいチュートリアルでもないなので、ファイアウォールで通信をあらかじめ許可することが主な役割だと割り切ってスキップしても良い) # 一応、チュートリアル内容について説明する。 # alpine/git の Docker イメージを取得 & コンテナーとして起動し、コンテナー内で clone コマンドを実行 ## --name オプションで、「コンテナー名」を割り当て ## cf. alpine/git <https://hub.docker.com/r/alpine/git> $ docker run --name repo alpine/git clone https://github.com/docker/getting-stared.git # コンテナー内の clone したリポジトリーを、ホストのカレントディレクトリーへコピー $ docker cp repo:/git/getting-started/ . # コピーしたフォルダーへ移動 $ cd getting-started # コピーしたフォルダー内の Dockerfile を元に、「docker101tutorial」というイメージ名で Docker イメージを作成 ## -t オプションで、「イメージ名」を割り当て(タグを省略したため、自動的に latest に) $ docker build -t docker101tutorial . # 作成した Docker イメージ「docker101tutorial」をコンテナーとして起動 ## -d オプションで、バックグラウンド実行 ## -p <ホスト側のポート>:<コンテナー側のポート> で、ホストとコンテナー間のポートフォワード設定(デフォルトだと、コンテナー内と通信できないため) ## --name オプションで、「コンテナー名」を割り当て $ docker run -d -p 80:80 --name docker-tutorial docker101tutorial Windows Defender ファイアウォールなどが Docker をブロックするので、許可する。 この後の You must be signed in to Docker Hub to share your image. Sign in here. 以降は、 Docker Hub の案内なので無視しても良い。(Docker イメージを公開する予定がなければ関係ないし、あとでもできる) チュートリアルの最後に、docker101tutorial のコンテナー内の Web サーバー上のページが表示される。(http://localhost/tutorial/) 確認が終われば Docker Desktop の GUI から docker101tutorial コンテナーを停止させる。 確認: # WSL にインストールされているディストリビューションとその詳細を確認 ## --list, -l ディストリビューションの一覧を表示します。 ## --verbose, -v すべてのディストリビューションについての詳細情報を表示します。 PS C:\Users\user> wsl -l -v NAME STATE VERSION docker-desktop-data Running 2 docker-desktop Running 2 # バージョンが 2 なら、WSL 2 で動作している 追加設定: cf. WSL2 Docker のイメージ・コンテナの格納先を変更したい (WSL2 の vhdx ファイルを移動させたい) - Qiita Docker の使う WSL 2 VM の仮想ディスク(VHD)のドライブを変更する手順は、以下のとおり。 (SSD の寿命問題への対策。手順は上記の Ubuntu のものと同じ) 参考: デフォルトの仮想ディスクの格納先パス docker-desktop: %LocalAppData%\Docker\wsl\data\ext4.vhdx docker-desktop-data: %LocalAppData%\Docker\wsl\distro\ext4.vhdx # タスクトレイのクジラのアイコンを右クリック > Quit Docker Desktop # その他に利用中の WSL 2 VM があれば切断する # 稼働中の WSL 2 VM を確認 PS C:> wsl -l -v # 稼働中のものがあれば、以下のコマンドですべて終了させる PS C:> wsl --shutdown # vhdx を tar としてエクスポート、登録解除、tar をインポート PS C:> cd D:\ PS C:> wsl --export <ディストリビューション名> <ディストリビューション名>.tar PS C:> wsl --unregister <ディストリビューション名> PS C:> wsl --import <ディストリビューション名> <インストール先パス> D:\<ディストリビューション名>.tar # 例: # wsl --export docker-desktop docker-desktop.tar # wsl --unregister docker-desktop # wsl --import docker-desktop D:\wsl\docker-desktop D:\doc\docker-desktop.tar # # wsl --export docker-desktop-data docker-desktop-data.tar # wsl --unregister docker-desktop-data # wsl --import docker-desktop-data D:\wsl\docker-desktop-data D:\doc\docker-desktop-data.tar # WSL 2 VM を再確認 PS C:> wsl -l -v # デフォルトのディストリビューションが変更されている場合は、以下のコマンドで再指定 PS C:> wsl --set-default <ディストリビューション名>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む