- 投稿日:2020-11-16T23:32:26+09:00
5分でわかる!!Dockerの使い方
5分でわかる!!Dockerの使い方
Dockerの解説を5分で行うぞ!!
これを読めば、論文の環境を再現することも出来る!!
細かい話はドキュメントを読んでくれ!!Dockerの使い方は、以下の通り!!
1.Dockerfileを書く!!
2.Dockerfileを元に、buildコマンドを実行しimageを作成する!!
3.runする!!たったの3ステップ!!
もう一回書くぞ!!
1.Dockerfileを書く!!
2.Dockerfileを元に、buildコマンドを実行しimageを作成する!!
3.runする!!dokcerにおけるimageとは、プログラムのようなもの!!
そして、それが動いている状態をコンテナと呼ぶ!!これは、プログラムとプロセスの関係に似ている!!
他の例えだと、クラスとインスタンスの関係に似ている!!それじゃあ、各ステップの解説に入るぞ!!
1.Dockerfileを書く!!
Dockerfileには、imageに焼き付けたい情報を書くのだ!!
つまり、コンテナが動く段階で備わって欲しいやつを書いていくのだ!!下に例を示すぞ!!!
FROM ubuntu:18.04 RUN apt-get update && apt-get install -y vimDockerfile内の各行は、
コマンド空白引数
で構成されている!!よく使うコマンドを紹介するぞ!!
たったの2つだ!!FROMとRUN
だけ覚えておけば何とかなる!!
まずは慣れることが大事だ!!FROMとは、元となるimageを指定するのだ!!
これを書くことによって、image作成が楽になる!!
例えば、tensorflow環境が欲しいなら、それ用のimageが配布されているのだ!!
分からん人は、クラス継承だと思ったらいいのだ!!RUNとは、Linuxコマンドを実行するためのコマンドなのだ!!
RUN空白Linuxコマンドによって、Linuxコマンドを実行するのだ!!imageにやきつけたいことをRUNによって、実行するのだ!!
例えば、vimを仮想環境立ち上げ時に備わって欲しいなら、
RUN apt-get install -y vimをDockerfile内で書くだけなのだ!!
次にimage作成方法に入っていくよ!!
2.Dockerfileを元に、buildコマンドを実行しimageを作成する!!
Dockerfileが出来上がれば、あとはbuildコマンドによって、imageを作成するだけなのだ!!
docker build -t image名 Dockerfileへのパスたったのこれだけでimageが出来上がるのだ!!
なんてことはないだろ?
3.runする!!
クラスが出来上がれば、インスタンスを作りたくなり、
プログラムが出来上がれば、プロセスとして動かしたくなるもんだ!!それと同じで、imageが出来上がれば、コンテナを立ち上げたくなるだろ!!
docker run -it --rm image名これで、晴れて現ターミナル内でコンテナが動くようになるぞ!!
終わりに
dockerが分からなくても、
3ステップが頭に入っていれば、何とかなるのだ!!
- 投稿日:2020-11-16T22:41:30+09:00
Dockerイメージを別サーバへ移行する
実現したいこと
あるサーバで作成したDockerイメージを別サーバに移行したいと思います。
移行するDockerイメージは前々回の記事で作成したものを使用します。
移行元/移行先どちらのサーバもOSはAmazon Linux 2です。Docker imageの保存
Dockerのイメージを確認します。
「ansible-demo」という名前のイメージを移行します。$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ansible-demo latest 590a85caf1ec 5 days ago 553MB続いて、イメージをtarファイルに出力します。
$ docker save ansible-demo > ansible-demo.tar $ ls ansible-demo.tarTagでバージョンなどを指定している場合は、以下のように実行すれば
指定のTag名が与えられたイメージを保存でき、Tag名も引き継がれます。$ docker save ansible-demo:3.9.0-slim-buster > ansible-demo.tar移行先のサーバにtarファイルをコピー
scpコマンドを使用して移行先のサーバにtarファイルをコピーします。
$ sudo scp -i .ssh/秘密鍵ファイル ansible-demo.tar ec2-user@10.0.1.100:/home/ec2-user ansible-demo.tar 100% 568MB 64.2MB/s 00:08Docker imageの読み込み
移行先のサーバでDocker imageを読み込みます。
$ sudo docker load < ansible-demo.tar d0fe87fa8b8c: Loading layer [==================================================>] 72.49MB/72.49MB 225ef83ca30a: Loading layer [==================================================>] 7.316MB/7.316MB 83dcc4a0d3e6: Loading layer [==================================================>] 31.29MB/31.29MB d93c07014f51: Loading layer [==================================================>] 4.608kB/4.608kB b36284d246c4: Loading layer [==================================================>] 8.972MB/8.972MB 21aeb0eb9f43: Loading layer [==================================================>] 3.072kB/3.072kB 7f1f16e48b7f: Loading layer [==================================================>] 390.2MB/390.2MB 0ba8cec4031f: Loading layer [==================================================>] 85.38MB/85.38MB Loaded image: ansible-demo:latest以下の通り、イメージファイルが読み込まれていることが確認できます。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ansible-demo latest 590a85caf1ec 6 days ago 553MB動作確認
では、にDockerコンテナを起動してみます。
DockerfileにWORKDIRを指定しているので、ディレクトリ作成から実行します。
移行元と同じコンテナが起動できました!$ sudo mkdir /usr/src/app $ cd /usr/src/app $ sudo docker run -it --rm -v $(pwd):/usr/src/app ansible-demo /bin/bash root@ff8c4ae0d144:/usr/src/app#
- 投稿日:2020-11-16T18:41:13+09:00
Line botをrails5+Docker+Herokuでデプロイ備忘録
目標
- RubyonRails5(RoR)開発環境をdocker-composeで構築
- Herokuへデプロイ
- LINE DVELOPERSで新規チャネル作成
- オウム返しBOTの作成
前提条件
※MACの方が対象です。
- home brewでgit,herokuのインストール済み
- dockerインストール済み
- Heroku,gitHub,Dockerで会員登録済みRoR開発環境構築
$ mkdir Linebot $ cd Linebot $ vi DockerfilesDockerfile# ruby2.3.3のイメージレイヤの上で下記のコマンド実行しますよ宣言 FROM ruby:2.3.3 # apt-getはパッケージマネージャみたいなやつ # updateでリスト更新&必須なパッケージをインスト RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs # 作業ディレクトリの作成、設定 RUN mkdir /app_name ##作業ディレクトリ名をAPP_ROOTに割り当てて、以下$APP_ROOTで参照 ENV APP_ROOT /app_name WORKDIR $APP_ROOT # ホスト側(ローカル)のGemfileを追加する ADD ./Gemfile $APP_ROOT/Gemfile ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock # Gemfileのbundle install RUN bundle install ADD . $APP_ROOT$ vi docker-compose.ymldocker-compose.ymlversion: '3' services: db: image: postgres:13.0 environment: POSTGRES_PASSWORD: 'postgres' ports: - "3306:3306" web: build: . command: rails s -p 3000 -b '0.0.0.0' volumes: - .:/app_name ports: - "3000:3000" depends_on: - dbwebとdbというコンテナ起動
$ touch Gemfile.lock $ vi GemfileGemfilesource 'https://rubygems.org' gem 'rails', '~> 5.2.2'$ docker-compose run app rails new . --force --database=postgresql --skip-bundle $ docker-compose build -d $ docker-compose up -d web-dオプションはデタッチモードで起動する(ログを流さずバックエンドで動作させる)
ログを見たいなら外していいけど止めるとコンテナも止まるから面倒
※dockerfileに手を加えたときだけ再度ビルドする必要があるので注意
※docker-compose.ymlの更新なら再度upする必要あり/config/database.ymldefault: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: db username: postgres password: postgres .... production: <<: *default database: app_name_production username: postgres password: <%= ENV['APP_NAME_DATABASE_PASSWORD'] %>開発、本番でpostgresqlを使うと書いておく
後述のHerokuを使う場合、postgresqlが標準だからよき
まあMySQLでもいいっちゃいいんだけどさGemfile#LINE API用 gem 'line-bot-api' #access tokenなどを管理する用(環境変数管理) gem 'dotenv-rails' #heroku環境用postgresql gem 'pg'$ docker-compose run web bundle install $ docker-compose run web rails db:create $ docker-compose run web rails g controller top index $ docker-compose run web rails g controller linebot collbackデータベース作っておかないと怒られるよ
Herokuでtop画面が必要なので何でもいいからとりあえず作っておこう
(volumeをコマンドだけじゃなくて直でいじったりはあんまりよくない気がするけど無視無視)routes.rbpost '/callback' => 'linebot#callback' root 'top#index'/app/controllers/linebot_controllerclass LinebotController < ApplicationController require 'line/bot' # gem 'line-bot-api' # callbackアクションのCSRFトークン認証を無効 protect_from_forgery :except => [:callback] def client @client ||= Line::Bot::Client.new { |config| config.channel_secret = ENV["LINE_CHANNEL_SECRET"] config.channel_token = ENV["LINE_CHANNEL_TOKEN"] } end def callback body = request.body.read signature = request.env['HTTP_X_LINE_SIGNATURE'] unless client.validate_signature(body, signature) head :bad_request end events = client.parse_events_from(body) events.each { |event| case event when Line::Bot::Event::Message case event.type when Line::Bot::Event::MessageType::Text message = { type: 'text', text: event.message['text'] } client.reply_message(event['replyToken'], message) when Line::Bot::Event::MessageType::Image, Line::Bot::Event::MessageType::Video response = client.get_message_content(event.message['id']) tf = Tempfile.open("content") tf.write(response.body) end end } head :ok end end$ touch .env.envLINE_CHANNEL_SECRET=XXXXXXXXXXX LINE_CHANNEL_TOKEN=XXXXXXXXXXXXXXXXXXXXXXはあとで作成するLine Developersのやつを書いてね
もしもローカルのコンテナを落としたいなら
$ docker-compose down
でやったらOK
Ctl+Cとかで落とした場合
$ rm tmp/pids/server.pid
をやっておいた方がよきHerokuへのデプロイ
$ vi heroku.ymlheroku.ymlbuild: docker: web: Dockerfile run: web: bundle exec puma -C config/puma.rbこれ書いておかないとビルドできないよ
heroku.ymlでdevelopment/productionの切り替えとかそれに伴うdbの切り替えとかもできそう(やってない)$ heroku login $ heroku create $ heroku addons:create heroku-postgresql:hobby-dev $ heroku container:login $ heroku container:push web $ git init $ heroku git:remote -a <自分のherokuリポジトリ名> $ git add . $ git commit -am "いい感じのコメント" $ heroku stack:set container $ git push heroku master $ heroku container:release web $ heroku openブランチ切らないなら今後はgitと同じくaddしてcommitしてheroku pushで更新していけるよ神かな?
この辺、コンテナプッシュしたりイメージプッシュしたりごちゃっとしてるのであんまり真似しない方がいいかも
- なんかサーバーの調子がおかしいときは
$ heroku restert
を打ってみたらよき- ログを確認したいときは
$ heroku logs --tail
でおk- サーバーのファイルを見たいなら
$ heroku run bash
でcatコマンド打ったりで見たら良き(vimが使えんのがお怒りポイント)Lineのチャネルとコンテナを接続
- Messaging APIでチャネル作成
- チャネルシークレットとチャネルアクセストークンを発行して.envファイルに貼り付けておく
- webhookを有効にするために応答メッセージと挨拶メッセージをオフに
- webhookを有効にしたらwebhookURLに<自分のURL>/callbackを入力して検証(成功にならなければheroku restartとかしてみて)
おまけ
テストしたいけどデプロイまでしたくない!ローカルで外部公開したい!
ngrok使うがよろしとりあえず検証でリクエスト送りたい!
Talend API Tester使うがよろしお世話になった記事
LINEのBot開発 超入門(前編) ゼロから応答ができるまで
https://qiita.com/nkjm/items/38808bbc97d6927837cdDockerComposeでコンテナベースのRailsアプリを作成してHerokuにデプロイする
https://qiita.com/akirakudo/items/16a01271b0a39316e439丁寧すぎるDocker-composeによるrails5 + MySQL on Dockerの環境構築(Docker for Mac)
https://qiita.com/azul915/items/5b7063cbc80192343fc0
- 投稿日:2020-11-16T17:47:30+09:00
YellowfinをEC2でDockerのインストールから始めてコンテナで動作させるまで
まずはじめに
アプリのコンテナ化が流行りということもあってか、YellowfinもDocker、Kubernetesで動かせるようになったようなので何もないところからDockerで動かすところまでを記事にしたいと思います。これがあるとほんとに短期間のPOC(All-in-oneパッケージ)やサンドボックス、中長期のPOC(App-only-image)でもすぐできてしまうところがありがたいです。
dockerファイルなどはこちらに用意されています。
https://github.com/YellowfinBI/Docker
https://hub.docker.com/u/yellowfinbiそしてここではAWSのEC2上で起動する場合を想定して説明していきます。
事前準備
dockerのインストールの前にサーバーの設定を行います。
大まかに言えば、まず最新化して言語設定・タイムゾーン設定を日本のものに合わせて、dstatでサーバーリソースを見れるようにします。sudo yum update sudo localectl set-locale LANG=ja_JP.UTF-8 sudo timedatectl set-timezone Asia/Tokyo sudo yum install dstatdockerのインストール
yumでdockerをインストールし、サービススタート、サーバー起動時サービス自動スタートの設定を行います。
4行目のusermodはユーザをdockerグループに追加すると,sudoなしでdockerコマンドを実行できるらしいので追加します。
再起動後、ユーザーでversion確認して無事にコマンドを叩けるかテストします。sudo yum install docker sudo systemctl start docker sudo systemctl enable docker sudo usermod -aG docker $USER sudo reboot //適用するために再起動 docker --versionこれでdocker自体のインストールは完了です。
docker-composeのインストール
docker-composeは、Dockerビルドやコンテナ起動のオプションなどを含め、複数のコンテナの定義をymlファイルに書き、それを利用してDockerビルドやコンテナ起動をすることができます。一つの簡単なコマンドで複数のコンテナを管理できるようになります。
Yellowfinの設定もymlファイルで書かれているのでこれをインストールします。↓でdocker-composeの最新のバージョンを覚えてください。
https://github.com/docker/compose/releases
コマンドで打つ時は1.27.4の部分を確認したバージョンに置き換えてください
2行目で実行権限を付与しています。sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --versionDockerでYellowfinを動かす
ここから2通りのパターンでYellowfinを起動します。
1パターン目のAll-in-oneパッケージははpostgreSQLも含めてYellowfinが構成されるのでちょっと試すくらいであればこちらで大丈夫です。でもDBと同居しているのでサービスを落とした瞬間にデータが全て失われます。。
2パターン目のApp-only-imageはYellowfinのリポジトリを外部ですでに作成しておき、Yellowfinのアプリだけをコンテナ化する方法です。そのため、このサービスを落としてもデータはDBに持っているためサービスを上げ直せばまた続けて作業することができます。ただアプリとリポジトリDBのバージョンを合わせないといけないことだけ注意が必要です。Yellowfin9.3.1のときはリポジトリDBも9.3.1の構成になっている必要があります。YellowfinをAll-in-oneパッケージで動かす
このコマンドでイメージを取得します。
docker pull yellowfinbi/yellowfin-all-in-one:latesthttps://github.com/YellowfinBI/Docker/blob/master/Docker%20Files/yellowfinAllInOne/Dockerfile
ここから設定ファイルをダウンロードし、名前をdocker-compose.ymlにして保存します。
保存したディレクトリで下記のコマンドを打てば立ち上がります。[ec2-user@ip-172-31-4-99 all-in-one]$ docker-compose up -d Creating all-in-one_yellowfin-all-in-one_1 ... doneその後、xxx.xxx.xxx.xxx:8080にアクセスするとYellowfinのログインページが開かれます。
YellowfinをApp-only-imageで動かす
この方法は事前にこれから動かすバージョンで作成・更新されたリポジトリDBがあらかじめ必要です。そのため、いちから作るにはまずYellowfinのフルバージョンをインストールすることで、リポジトリDBを作成しておき初回起動までは済ませておく必要があります。
最初からの作成の場合はこちらをご覧ください。EC2にYellowfinのベストなテスト環境を構築するまでのメモそれでは手順ですが、まず、https://portal.yellowfinbi.com/yf_latestbuild.jsp からリンクをコピーし最新ビルドのフルバージョンをダウンロードします。
wget https://files.yellowfin.bi/downloads/9.3/yellowfin-9.3.1-20201022-full.jarその後このファイル名をymlで読み込めるように変更します。
mv yellowfin-9.3.1-20201022-full.jar yellowfin-installer.jarここからDockerfileとperform_docker_configuration.shを同じディレクトリにダウンロードします。
https://github.com/YellowfinBI/Docker/tree/master/Docker%20Files/yellowfinAppOnlyシェルファイルに実行権限を与えます。
sudo chmod 764 perform_docker_configuration.shイメージを作成します。
docker build . -t yellowfin-app-onlyすると、Dockerfileを読み込み、コマンドが実行されていきます。
リポジトリ情報を書き換えてコマンド実行してください。
sudo docker run -d -p 80:8080 \ -e JDBC_CLASS_NAME=org.postgresql.Driver \ -e JDBC_CONN_URL=jdbc:postgresql://dbhost:5432/yellowfinDatabase \ -e JDBC_CONN_USER=dbuser \ -e JDBC_CONN_PASS=dbpassword \ yellowfin-app-only:latestこの場合80番ポートにルーティングしているので、xxx.xxx.xxx.xxxにアクセスするとYellowfinのログインページが表示されます。
この時のコンテナの状態はこちら。All-in-oneパッケージは落として、App-only-imageのコンテナだけ上がっているのがわかります。
役に立ったコマンド
//イメージのダウンロード docker pull [オプション] イメージ名[:タグ名] //ローカル環境のDockerイメージの一覧表示 docker images //コンテナのバックグラウンド実行 docker run -d イメージ名[:タグ名] [引数] //すべてのコンテナを表示する docker ps -a //コンテナの起動 docker start コンテナID //コンテナを停止 docker stop コンテナID //コンテナを削除 docker rm コンテナIDということで
これを構築しておくとすぐにサンドボックスを作成できたり、DBと分離したサービスとして立ち上げられたりするのでより手離れがいい感じに環境が作成できます。慣れないとコマンドが難しかったりしましたがなんだか使ってるうちにわかってきた気がします。
正式なドキュメントはYellowfin Japanにお問い合わせすればホワイトペーパーがもらえると思うので聞いてみてください。
Dockerでのクラスター化や、Kubernetesでの構築についてはいつか時間ができた時にチャレンジしたいと思います。参考にさせていただきました。
dockerとdocker-composeのインストール(Linux編)
Docker入門(第六回)〜Docker Compose〜
Dockerコマンド一覧
- 投稿日:2020-11-16T17:47:30+09:00
YellowfinをDockerで動作させる
まずはじめに
アプリのコンテナ化が流行りということもあってか、YellowfinもDocker、Kubernetesで動かせるようになったようなので何もないところからDockerで動かすところまでを記事にしたいと思います。これがあるとほんとに短期間のPOC(All-in-oneパッケージ)やサンドボックス、中長期のPOC(App-only-image)でもすぐできてしまうところがありがたいです。
dockerファイルなどはこちらに用意されています。
https://github.com/YellowfinBI/Docker
https://hub.docker.com/u/yellowfinbiそしてここではAWSのEC2上で起動する場合を想定して説明していきます。
事前準備
dockerのインストールの前にサーバーの設定を行います。
大まかに言えば、まず最新化して言語設定・タイムゾーン設定を日本のものに合わせて、dstatでサーバーリソースを見れるようにします。sudo yum update sudo localectl set-locale LANG=ja_JP.UTF-8 sudo timedatectl set-timezone Asia/Tokyo sudo yum install dstatdockerのインストール
yumでdockerをインストールし、サービススタート、サーバー起動時サービス自動スタートの設定を行います。
4行目のusermodはユーザをdockerグループに追加すると,sudoなしでdockerコマンドを実行できるらしいので追加します。
再起動後、ユーザーでversion確認して無事にコマンドを叩けるかテストします。sudo yum install docker sudo systemctl start docker sudo systemctl enable docker sudo usermod -aG docker $USER sudo reboot //適用するために再起動 docker --versionこれでdocker自体のインストールは完了です。
docker-composeのインストール
docker-composeは、Dockerビルドやコンテナ起動のオプションなどを含め、複数のコンテナの定義をymlファイルに書き、それを利用してDockerビルドやコンテナ起動をすることができます。一つの簡単なコマンドで複数のコンテナを管理できるようになります。
Yellowfinの設定もymlファイルで書かれているのでこれをインストールします。↓でdocker-composeの最新のバージョンを覚えてください。
https://github.com/docker/compose/releases
コマンドで打つ時は1.27.4の部分を確認したバージョンに置き換えてください
2行目で実行権限を付与しています。sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --versionDockerでYellowfinを動かす
ここから2通りのパターンでYellowfinを起動します。
1パターン目のAll-in-oneパッケージははpostgreSQLも含めてYellowfinが構成されるのでちょっと試すくらいであればこちらで大丈夫です。でもDBと同居しているのでサービスを落とした瞬間にデータが全て失われます。。
2パターン目のApp-only-imageはYellowfinのリポジトリを外部ですでに作成しておき、Yellowfinのアプリだけをコンテナ化する方法です。そのため、このサービスを落としてもデータはDBに持っているためサービスを上げ直せばまた続けて作業することができます。ただアプリとリポジトリDBのバージョンを合わせないといけないことだけ注意が必要です。Yellowfin9.3.1のときはリポジトリDBも9.3.1の構成になっている必要があります。YellowfinをAll-in-oneパッケージで動かす
このコマンドでイメージを取得します。
docker pull yellowfinbi/yellowfin-all-in-one:latesthttps://github.com/YellowfinBI/Docker/blob/master/Docker%20Files/yellowfinAllInOne/Dockerfile
ここから設定ファイルをダウンロードし、名前をdocker-compose.ymlにして保存します。
保存したディレクトリで下記のコマンドを打てば立ち上がります。[ec2-user@ip-172-31-4-99 all-in-one]$ docker-compose up -d Creating all-in-one_yellowfin-all-in-one_1 ... doneその後、xxx.xxx.xxx.xxx:8080にアクセスするとYellowfinのログインページが開かれます。
YellowfinをApp-only-imageで動かす
この方法は事前にこれから動かすバージョンで作成・更新されたリポジトリDBがあらかじめ必要です。そのため、いちから作るにはまずYellowfinのフルバージョンをインストールすることで、リポジトリDBを作成しておき初回起動までは済ませておく必要があります。
最初からの作成の場合はこちらをご覧ください。EC2にYellowfinのベストなテスト環境を構築するまでのメモそれでは手順ですが、まず、https://portal.yellowfinbi.com/yf_latestbuild.jsp からリンクをコピーし最新ビルドのフルバージョンをダウンロードします。
wget https://files.yellowfin.bi/downloads/9.3/yellowfin-9.3.1-20201022-full.jarその後このファイル名をymlで読み込めるように変更します。
mv yellowfin-9.3.1-20201022-full.jar yellowfin-installer.jarここからDockerfileとperform_docker_configuration.shを同じディレクトリにダウンロードします。
https://github.com/YellowfinBI/Docker/tree/master/Docker%20Files/yellowfinAppOnlyシェルファイルに実行権限を与えます。
sudo chmod 764 perform_docker_configuration.shイメージを作成します。
docker build . -t yellowfin-app-onlyすると、Dockerfileを読み込み、コマンドが実行されていきます。
リポジトリ情報を書き換えてコマンド実行してください。
sudo docker run -d -p 80:8080 \ -e JDBC_CLASS_NAME=org.postgresql.Driver \ -e JDBC_CONN_URL=jdbc:postgresql://dbhost:5432/yellowfinDatabase \ -e JDBC_CONN_USER=dbuser \ -e JDBC_CONN_PASS=dbpassword \ yellowfin-app-only:latestこの場合80番ポートにルーティングしているので、xxx.xxx.xxx.xxxにアクセスするとYellowfinのログインページが表示されます。
この時のコンテナの状態はこちら。All-in-oneパッケージは落として、App-only-imageのコンテナだけ上がっているのがわかります。
役に立ったコマンド
//イメージのダウンロード docker pull [オプション] イメージ名[:タグ名] //ローカル環境のDockerイメージの一覧表示 docker images //コンテナのバックグラウンド実行 docker run -d イメージ名[:タグ名] [引数] //すべてのコンテナを表示する docker ps -a //コンテナの起動 docker start コンテナID //コンテナを停止 docker stop コンテナID //コンテナを削除 docker rm コンテナIDということで
これを構築しておくとすぐにサンドボックスを作成できたり、DBと分離したサービスとして立ち上げられたりするのでより手離れがいい感じに環境が作成できます。慣れないとコマンドが難しかったりしましたがなんだか使ってるうちにわかってきた気がします。
正式なドキュメントはYellowfin Japanにお問い合わせすればホワイトペーパーがもらえると思うので聞いてみてください。
Dockerでのクラスター化や、Kubernetesでの構築についてはいつか時間ができた時にチャレンジしたいと思います。参考にさせていただきました。
dockerとdocker-composeのインストール(Linux編)
Docker入門(第六回)〜Docker Compose〜
Dockerコマンド一覧
- 投稿日:2020-11-16T17:04:13+09:00
Docker コンテナ上で PureScript を動かす
はじめに
Docker Hub に
PureScript
が動作するイメージがいくつかアップされていますが、Node.js v12
かつspago
を使用しているものが見当たらなかったので自分で作成してみました検証環境
Windows10 Home Edition VirtualBox 6.1.16 docker-machine.exe version 0.16.1, build cce350d7 # Docker Host OS (CoreOS) $ uname -a Linux default 4.14.154-boot2docker #1 SMP Thu Nov 14 19:19:08 UTC 2019 x86_64 GNU/Linux Docker version 19.03.5, build 633a0ea838 docker-compose version 1.26.0, build d4451659ディレクトリ構成
purescript
フォルダの中にdocker-compose.yml
とDockerfile
のみpurescript | docker-compose.yml | Dockerfile
docker-compose.yml
docker-compose.ymlversion: "3.7" services: purescript: build: context: . dockerfile: Dockerfile image: takaya030/purescript
Dockerfile
DockerfileFROM node:12 LABEL maintainer "takaya030" # install purescript RUN npm install --global --unsafe-perm purescript spago # add user RUN userdel node && \ useradd -m -s /bin/bash pureuser WORKDIR /home/pureuser USER pureuser RUN mkdir tmp && cd tmp && spago init CMD cd tmp && spago replイメージのビルド
$ cd purescript $ docker-compose build purescriptイメージの確認
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE takaya030/purescript latest fb50aeb56d04 22 hours ago 1.08GB node 12 1f560ce4ce7e 4 weeks ago 918MB
動作確認
$ docker-compose run --rm purescript [info] Installing 4 dependencies. [info] Searching for packages cache metadata.. [info] Unable to find packages cache metadata, downloading from GitHub.. [info] Installing and globally caching "psci-support" [info] Installing and globally caching "console" [info] Installing and globally caching "effect" [info] Installing and globally caching "prelude" [info] Installation complete. Compiling Type.Data.RowList Compiling Type.Data.Row Compiling Record.Unsafe . . . Compiling Main Compiling PSCI.Support Compiling Test.Main PSCi, version 0.13.8 Type :? for help import Prelude > "hello" "hello" > 1 + 2 * 3 7 > import Effect.Console > log "print this to the screen" print this to the screen unit > :quit See ya! ()参考
- 投稿日:2020-11-16T12:28:41+09:00
Docker 上でお手軽にC#9(.NET 5)を試す
.NET 5 をお手軽に試したい
先日めでたく .NET 5がリリースされました。1.NET 5 では C# 9 がサポートされています。
早速試したいところですが手元のPCにインストールせず、少しだけ触りたいので Docker を使って使い捨ての .NET 5 開発環境を用意したいと思います。Docker のインストール不要なブラウザで使えるクラウド上の使い捨て Docker 実行環境の Play with Docker2 上で試します。
環境
実行した際の Play with Docker の Linux 環境は
Alpine Linux 3.12
、Docker のバージョンは19.03.11
です。
$ more /etc/issue
Welcome to Alpine Linux 3.12 Kernel \r on an \m (\l)
$ docker --version
Docker version 19.03.11, build 42e35e61f3.NET 5 の開発環境を用意する
.NET 5 SDK の Docker image を実行します。
-it
オプションで標準入出力をシェルにつなげてそのまま .NET 5 SDK のコンテナに乗り込みます。
※--rm
オプションでコンテナ終了時にコンテナが自動的に削除されます3。
手元の PC で試す場合は不要なコンテナが残りません。
$ docker run -it --rm mcr.microsoft.com/dotnet/sdk:5.0
Unable to find image 'mcr.microsoft.com/dotnet/sdk:5.0' locally 5.0: Pulling from dotnet/sdk bb79b6b2107f: Pull complete 97805e17b1a2: Pull complete 48d36279ea43: Pull complete 5d23a35fbf12: Pull complete 982bc1066a1e: Pull complete 6cc6e848c1f3: Pull complete df97eda6f03d: Pull complete 7520ee234b82: Pull complete Digest: sha256:ac49854ff6dcc1a2916ffc0981503f571698458187f925da0c2f2b6a0bec8dee Status: Downloaded newer image for mcr.microsoft.com/dotnet/sdk:5.0 root@e68a47087ad8:/#.NET 5 がインストールされていることが確認できます。
root@e68a47087ad8:/# dotnet --version
5.0.100Linux のディストリビューションは Debian なようです。
root@e68a47087ad8:/# more /etc/issue
Debian GNU/Linux 10 \n \lC# 9(.NET 5)の新機能を試す
コンソールアプリを作成して C# 9 の新機能を試していきたいと思います。
root@e68a47087ad8:/# dotnet new console -o MyConsoleApp && cd MyConsoleApp
Getting ready... The template "Console Application" was created successfully. Processing post-creation actions... Running 'dotnet restore' on MyConsoleApp/MyConsoleApp.csproj... Determining projects to restore... Restored /MyConsoleApp/MyConsoleApp.csproj (in 89 ms). Restore succeeded.プロジェクトが作成されました。
root@e68a47087ad8:/MyConsoleApp# ls -R
.: MyConsoleApp.csproj Program.cs obj ./obj: MyConsoleApp.csproj.nuget.dgspec.json MyConsoleApp.csproj.nuget.g.targets project.nuget.cache MyConsoleApp.csproj.nuget.g.props project.assets.jsonファイル編集したいところですが vim が入っていませんのでインストールしたいと思います。
まず、パッケージをアップデートします。
root@e68a47087ad8:/MyConsoleApp# apt update && apt upgrade
Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB] Get:2 http://deb.debian.org/debian buster InRelease [121 kB] Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB] Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [248 kB] Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7906 kB] Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [7856 B] Fetched 8401 kB in 1s (5711 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 1 package can be upgraded. Run 'apt list --upgradable' to see it. Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: tzdata 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 264 kB of archives. After this operation, 3072 B of additional disk space will be used. Do you want to continue? [Y/n] Y Get:1 http://deb.debian.org/debian buster-updates/main amd64 tzdata all 2020d-0+deb10u1 [264 kB] Fetched 264 kB in 0s (24.0 MB/s) debconf: delaying package configuration, since apt-utils is not installed (Reading database ... 9877 files and directories currently installed.) Preparing to unpack .../tzdata_2020d-0+deb10u1_all.deb ... Unpacking tzdata (2020d-0+deb10u1) over (2020a-0+deb10u1) ... Setting up tzdata (2020d-0+deb10u1) ... debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.) debconf: falling back to frontend: Readline Current default time zone: 'Etc/UTC' Local time is now: Sat Nov 14 16:16:39 UTC 2020. Universal Time is now: Sat Nov 14 16:16:39 UTC 2020. Run 'dpkg-reconfigure tzdata' if you wish to change it.vim をインストールします。
root@e68a47087ad8:/MyConsoleApp# apt install vim
Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libgpm2 vim-common vim-runtime xxd Suggested packages: gpm ctags vim-doc vim-scripts The following NEW packages will be installed: libgpm2 vim vim-common vim-runtime xxd 0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded. Need to get 7425 kB of archives. After this operation, 33.8 MB of additional disk space will be used. Do you want to continue? [Y/n] Y Get:1 http://deb.debian.org/debian buster/main amd64 xxd amd64 2:8.1.0875-5 [140 kB] Get:2 http://deb.debian.org/debian buster/main amd64 vim-common all 2:8.1.0875-5 [195 kB] Get:3 http://deb.debian.org/debian buster/main amd64 libgpm2 amd64 1.20.7-5 [35.1 kB] Get:4 http://deb.debian.org/debian buster/main amd64 vim-runtime all 2:8.1.0875-5 [5775 kB] Get:5 http://deb.debian.org/debian buster/main amd64 vim amd64 2:8.1.0875-5 [1280 kB] Fetched 7425 kB in 0s (59.9 MB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package xxd. (Reading database ... 9877 files and directories currently installed.) Preparing to unpack .../xxd_2%3a8.1.0875-5_amd64.deb ... Unpacking xxd (2:8.1.0875-5) ... Selecting previously unselected package vim-common. Preparing to unpack .../vim-common_2%3a8.1.0875-5_all.deb ... Unpacking vim-common (2:8.1.0875-5) ... Selecting previously unselected package libgpm2:amd64. Preparing to unpack .../libgpm2_1.20.7-5_amd64.deb ... Unpacking libgpm2:amd64 (1.20.7-5) ... Selecting previously unselected package vim-runtime. Preparing to unpack .../vim-runtime_2%3a8.1.0875-5_all.deb ... Adding 'diversion of /usr/share/vim/vim81/doc/help.txt to /usr/share/vim/vim81/doc/help.txt.vim-tiny by vim-runtime' Adding 'diversion of /usr/share/vim/vim81/doc/tags to /usr/share/vim/vim81/doc/tags.vim-tiny by vim-runtime' Unpacking vim-runtime (2:8.1.0875-5) ... Selecting previously unselected package vim. Preparing to unpack .../vim_2%3a8.1.0875-5_amd64.deb ... Unpacking vim (2:8.1.0875-5) ... Setting up libgpm2:amd64 (1.20.7-5) ... Setting up xxd (2:8.1.0875-5) ... Setting up vim-common (2:8.1.0875-5) ... Setting up vim-runtime (2:8.1.0875-5) ... Setting up vim (2:8.1.0875-5) ... update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rvim (rvim) in auto mode update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rview (rview) in auto mode update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vi (vi) in auto mode update-alternatives: warning: skip creation of /usr/share/man/da/man1/vi.1.gz because associated file /usr/share/man/da/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/de/man1/vi.1.gz because associated file /usr/share/man/de/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/fr/man1/vi.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/it/man1/vi.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ja/man1/vi.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/pl/man1/vi.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ru/man1/vi.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/man1/vi.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group vi) doesn't exist update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/view (view) in auto mode update-alternatives: warning: skip creation of /usr/share/man/da/man1/view.1.gz because associated file /usr/share/man/da/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/de/man1/view.1.gz because associated file /usr/share/man/de/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/fr/man1/view.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/it/man1/view.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ja/man1/view.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/pl/man1/view.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ru/man1/view.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/man1/view.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group view) doesn't exist update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/ex (ex) in auto mode update-alternatives: warning: skip creation of /usr/share/man/da/man1/ex.1.gz because associated file /usr/share/man/da/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/de/man1/ex.1.gz because associated file /usr/share/man/de/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/fr/man1/ex.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/it/man1/ex.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ja/man1/ex.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/pl/man1/ex.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ru/man1/ex.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/man1/ex.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group ex) doesn't exist update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode update-alternatives: warning: skip creation of /usr/share/man/da/man1/editor.1.gz because associated file /usr/share/man/da/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/de/man1/editor.1.gz because associated file /usr/share/man/de/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/fr/man1/editor.1.gz because associated file /usr/share/man/fr/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/it/man1/editor.1.gz because associated file /usr/share/man/it/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ja/man1/editor.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/pl/man1/editor.1.gz because associated file /usr/share/man/pl/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/ru/man1/editor.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group editor) doesn't exist update-alternatives: warning: skip creation of /usr/share/man/man1/editor.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group editor) doesn't exist Processing triggers for libc-bin (2.28-10) ...準備ができましたので C# 9 のコードを試してみます。
詳細は参考にさせていただいた下記の記事をご覧ください。C# 小ネタ:.NET 5.0 で使える C# 9.0 で気に入ってる機能紹介
トップレベルステートメント4
エントリポイントならクラス無しで直接コードを書けます。簡単なバッチなどで便利そうです。
root@e68a47087ad8:/MyConsoleApp# vim Program.cs
System.Console.WriteLine("Hello from top.");ビルドします。(以降のサンプルでは省略します。)
root@e68a47087ad8:/MyConsoleApp# dotnet build
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET Copyright (C) Microsoft Corporation. All rights reserved. Determining projects to restore... All projects are up-to-date for restore. MyConsoleApp -> /MyConsoleApp/bin/Debug/net5.0/MyConsoleApp.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:02.44
root@e68a47087ad8:/MyConsoleApp# dotnet run
Hello from top.レコード型5
イミュータブルなオブジェクトを手軽に作成することができます。
またプロパティの値が一致していれば違う参照のレコード型でも==
がtrue
になります。
またこの記事では試していませんがwith
式を使って一部のプロパティだけ書き換えた新しいレコードを作成することができます。値オブジェクトづくりがはかどりそうです。
root@e68a47087ad8:/MyConsoleApp# vim Program.cs
using static System.Console; record Money(decimal amount); class Program { static void Main() { var money1 = new Money(10); WriteLine($"money1: {Money}"); var money2 = new Money(10); WriteLine($"money2: {money2}"); WriteLine($"money1 == money2: {money1 == money2}"); } }
root@e68a47087ad8:/MyConsoleApp# dotnet run
money1: Money { amount = 10 } money2: Money { amount = 10 } money1 == money2: TrueTarget typed new6
型推論して明らかなときは
new
の型名を省略できます。
今まで右辺から推論するvar
はありましたがメンバー変数で使えませんでした。
また、引数や戻り値で型が明らかな場合でも型名を省略できるようです。using System.Collections.Generic; using System.Linq; class Program { static readonly Dictionary<int, List<string>> _cache = new(); static void Main() { _cache.Add(1, new() { "aaa" }); System.Console.WriteLine(_cache[1].First()); } }
root@e68a47087ad8:/MyConsoleApp# dotnet run
aaa条件式の新機能7
条件式に
or
,and
,not
が追加されています。
特徴として評価が1回なので副作用のある式の戻り値の比較にも使い易いようです。(=副作用を複数回発生させないように一時変数に結果を格納してから比較する必要がなくなった)
またパターンマッチングと合わせて簡潔に書くこともできるようです。
root@e68a47087ad8:/MyConsoleApp# vim Program.cs
using static System.Console; var x = 7; WriteLine($"x is >= 5 and < 10: {x is >= 5 and < 10}"); WriteLine($"x is (<= 0 or 7 or <= 10) and not 15: {x is (<= 0 or 7 or <= 10) and not 15}"); object o = 2; WriteLine($"o is int and >= 1: {o is int and >= 1}");
root@e68a47087ad8:/MyConsoleApp# dotnet run
x is >= 5 and < 10: True x is (<= 0 or 7 or <= 10) and not 15: True o is int and >= 1: Trueおわり
後から気づいたのですが、ソースコードを変更するたびに
dotnet build
しなくてもdotnet run
だけで勝手にビルドされました。便利です。
読んでいただきありがとうございました。
https://www.publickey1.jp/blog/20/net_51windowsmaclinuxweb.html ↩
https://qiita.com/okazuki/items/8043ea6f0095b3019cdf#%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88 ↩
https://qiita.com/okazuki/items/8043ea6f0095b3019cdf#%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E5%9E%8B ↩
https://qiita.com/okazuki/items/8043ea6f0095b3019cdf#target-typed-new-%E5%BC%8F ↩
https://qiita.com/okazuki/items/8043ea6f0095b3019cdf#%E5%A4%A7%E3%81%AA%E3%82%8A%E5%B0%8F%E3%81%AA%E3%82%8A%E3%81%AE%E6%AF%94%E8%BC%83%E3%82%82%E7%B0%A1%E5%8D%98%E3%81%AB ↩
- 投稿日:2020-11-16T07:55:09+09:00
技術備忘録(Docker)
自分自身の学習記録を残し、見直した際に素早く思い出すための記事投稿です。
記入日:2020年11月15日
それでは書いていきましょう。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
1.Dockerとは何か?PC上でSwitchやLinuxを動かせるエミュレータのようなもの。
PCの中に別のマシンを作成・起動させるための仮想環境を作成するためのプラットフォームです。ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
2.そもそもDockerを入れる理由は?①エンジニアによって異なる開発環境を統一させ、開発効率をよくするため
=OSによる環境の違いや、使用しているマシンなどによる挙動を気にしくてよくなる②開発環境と本番環境での違いをできるだけなくせる
=本番環境へのデプロイがしやすい(環境差分が完全になくなるわけでない?)
=サーバーへの環境設定なども不要になるので、リリースの速度も早くなるつまりDockerを使用すると、チーム開発をする上での開発環境を統一させ、
本番環境へデプロイする上でのエラー等を最大限小さくすることができます!ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
3.Dockerの仕組みとは?Dockerはイメージとコンテナが基本。イメージからコンテナを生成する。
【イメージとは】
コンテナの元となるテンプレート。
OSや実行するアプリケーションや様々な設定をまとめたもの(テンプレート)。【コンテナ】
上記のイメージを元に作成される。
OSとアプリケーションが動く実行環境。
本番環境にコンテナをデプロイすることで、アプリケーションを本番環境上で動作させられる。基本的には以上の2つから成り立っているのがDockerの基本です。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
4.具体的な操作手順は?①イメージを取得/ビルドする
❶オンライン上のDockerHubにある、Dockerレジストリからイメージを取得する。
❷自分自身で作成する ※ベースのイメージはレジストリから取得し、それらに設定を加えたものビルドする
ビルド=ベースとなるイメージに、自分自身の加工を加えたもの通常の開発では、自分自身でDockerfileを作ることの方が多い。
②コンテナを生成・起動する
作成したイメージからコンテナを生成する → そしてそれを起動する → アプリケーションが動作する
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
以上が基本的な流れです。
ですが、アプリケーションの開発においては、大抵は複数のコンテナを扱い作業が行われるため、
1つ1つをイメージビルド、コンテナ作成等をすると手間です。それでは複数のコンテナを動作させる場合はどうするか?
結論 「Docker Compose」 を使用する
Docker Composeは複数のコンテナを定義し実行するためのツールです。
ymlファイルというものに設定を記載する事で、コマンドでコンテナの生成や起動などをする事ができます!ここで、Docker Composeにおけるコマンドの基本操作を記載しておきます。
※コンテナライフサイクルと言いますビルド $ docker-compose build
生成起動 $ docker-compose up
停止 $ docker-compose stop
削除 $ docker-compose rm
再起動 $ docker-compose restart
停止削除 $ docker-compose downその他のコマンド
起動中のコンテナでコマンドを実行 $ docker-compose exec
コンテナの一覧を表示 $ docker-compose ps
ログの表示 $ docker-compose logs
使用していないコンテナやイメージなどを削除 $ docker-compose prune他にも多くがありますが、その際はリファレンスを参考にしてください。
参考URL:https://docs.docker.com/reference/
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
5.Dockerをインストールする
公式HPのget-startedからダウンロードしましょう。
Desktop用の物をインストールしますが、
自身のOSのバージョンなどを事前に確認しておくと良いと思います。ダウンロードが完了し、アプリケーションを実行するとデスクトップ右上に、
Dockerのクジラのアイコンが出てきます。(可愛い)
クリックしていただき、runningの状態になるとアプリケーションを操作する事ができるようになります。ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
6.Dockerでコンテナを起動させるには
公式ドキュメント:https://docs.docker.com/
公式ドキュメントないの「Quickstart」でPCにインストールできているかや
簡単な動作確認ができますので、参考にしつつ触りとして行うことをおすすめします。ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
簡単ではありますが以上となります。
感想としてはモダンなWEB系企業では取り入れられており、
導入メリットを見れば「あぁなるほどな〜」と思いました。WEB開発を進める上ではスピード感は大切ですし、
人を動かす分、お金がかかっていますので、
それらを迅速に活用するためにも、Dockerは合理的で
素晴らしいプラットフォームだと思いました。学習を進める上で、追記事項があれば別記事にするか、
こちらに追記していくかで内容を濃くできるようにしていきたいと思います。ご覧いただきありがとうございました。
- 投稿日:2020-11-16T01:39:20+09:00
【Python】Line APIを使う [第一回 美女Botの作成]
モチベーション
最近女の子とラインをしていない...
すぐに返信してくれてかつ可愛い子はいないものか。
linebotを活用することで実現できるのではないか?このようなしょうもない理由でlinebotの作成をしようと思う。
環境
・mac Catalina
・Docker version 19.03.13
・Flask 1.1.2
・Python 3.8.3
・docker-compose version 1.27.4
・heroku 7.45.0
・bash今回作成するもの
まずは環境構築として、dockerからherokuにコンテナを移動し起動するまでをする。
LINEBOTはおはようと言ったらおはようと返してくれる美人のbotを作成する。
あくまで非リアだからこんなことしてるわけでないことに注意!流れ
第一回の流れを記す。
1.LINE Developersの登録
2.pythonファイルの作成
3.Dockerfileとdocker-compose.ymlの作成
4.herokuへのアップロード最終的なファイル構成は以下のようになる。
bijobot
├── Dockerfile
├── app.py
├── docker-compose.yml
└── requirements.txt1.LINE Developersの登録
以下よりサイトに飛ぶ。
LINE DevelopersまずはLoginして、Providersよりcreateを選択する。
すでにdisny通知というのがあるのは気にしない。Create a new providerと出てくるのでdisny通知のようにつけたい名前をつける。
筆者は"自由画像子"という名前をつけた。次にThis provider doesn't have any channels yetと出てくるのでCreate a Messaging API channelを選択する。
その後以下のような画面に飛ぶのでそれぞれ適当に記入する。
channel iconにはフリー画像でよく使われており個人的にタイプの子を採用した。規約に同意しAdminを確認すると、以下のように新しくチャンネルが追加されているのが確認できる。
ここで作成したチャンネルに移動し、Basic setting内の
Channnel secret
Messaging API内の
Channel access token
に関しては必要なので控えておくようにする。
2.pythonファイルの作成
Messaging API SDKs
のOfficial SDKsよりflaskを使ってファイルを作成する手順が書かれているのでこれを応用して作成していく。まずはappを作るための作業ディレクトリを作成する。
bijoとかでいいだろう。terminalmkdir bijo cd bijo次にpythonファイルを作成する。
作成したpythonファイルは以下のようになる。
必ずapp.pyという名前をつけること。app.pyfrom flask import Flask, request, abort # os内のenvironmentを扱うライブラリ import os from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import ( InvalidSignatureError ) from linebot.models import ( MessageEvent, TextMessage, TextSendMessage, ) #環境変数取得 YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"] YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"] line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN) handler = WebhookHandler(YOUR_CHANNEL_SECRET) app = Flask(__name__) @app.route("/") def hello_world(): return "hello!" @app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: print("Invalid signature. Please check your channel access token/channel secret.") abort(400) return 'OK' @handler.add(MessageEvent, message=TextMessage) def handle_message(event): line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text)) if __name__ == "__main__": app.run()
YOUR_CHANNEL_ACCESS_TOKEN
YOUR_CHANNEL_ACCESS_TOKEN
には先程控えた
Channnel secret
Channel access token
を使用する。
osを使ってherokuの環境変数から情報を取り出す。
これは後ほどherokuで設定する。3.Dockerfileとdocker-compose.ymlの作成
herokuでProcfileなどを作成するのはめんどくさいし、できるならモダンな技術が使いたかったのでdockerを使用する。
Dockerfileとdocker-compose.ymlは以下のようにbijoディレクトリの中に作成する。※herokuではdocker-compose.ymlは使用されないので注意。
heroku.ymlというdocker-compose.ymlのheroku版を作らなきゃいけないらしいけどなんか面倒そうなので今回はパス。
docker-compose.yml# ローカル作業用:heroku内では作用しない。 # ローカル作業用:heroku内では作用しない。 version: '3' services: app: build: . container_name: bijobot tty: true ports: - 5000:5000 environment: FLASK_ENV: 'development' #デバッグモードON FLASK_APP: "app.py" #app.pyを起動 YOUR_CHANNEL_ACCESS_TOKEN: 控えたaccess token YOUR_CHANNEL_SECRET:控えたchannel secret volumes: - ./:/code/ command: flask run -h 0.0.0.0 # command: gunicorn -b 0.0.0.0:$PORT app:app --log-file=-
FLASK_ENV: 'development'
としておくことでファイルをsave時に自動でサーバーに反映される。DockerfileFROM python:3.7-alpine # codeというディレクトリを作成し、そこを作業フォルダとする WORKDIR /code #デバッグモードON ENV FLASK_ENV: 'development' # alpineのおまじない RUN apk add --no-cache gcc musl-dev linux-headers # requirements.txtをcode内に移動 COPY requirements.txt requirements.txt # requirements.txtの中のライブラリをinstallする RUN pip install -r requirements.txt # すべてのファイルをcode内にマウントする。 COPY . . # $PORTを指定しないと動かないので注意 CMD gunicorn -b 0.0.0.0:$PORT app:app --log-file=-さらにrequirements.txtを作成する。
こちらはいかのコマンドを叩くことで解凍可能だが今回は予め作成しておく手順で行く。
terminalpip freeze > requirements.txtrequirements.txtには以下のように記入する。
certifi==2020.11.8 chardet==3.0.4 click==7.1.2 Flask==1.1.2 future==0.18.2 gunicorn==20.0.4 idna==2.10 itsdangerous==1.1.0 Jinja2==2.11.2 line-bot-sdk==1.17.0 MarkupSafe==1.1.1 requests==2.25.0 urllib3==1.26.2 Werkzeug==1.0.1requirements.txtはpythonのライブラリを予め書いておきインストールできるようにするもので、本来であれば、
pip install gunicorn flask line-bot-sdkとしなければ行かなかったものを必要なくする。
terminaltouch requirements.txt次に以下のコマンドを打ってdocker containerを立ち上げる。
terminaldocker-compose build docker-compose up -dここでlocalhost:5000にアクセスし、hello!と表示されることを確認する。
4.herokuでのデプロイ
herokuの登録は予め済んでいるうえですすめる。
まずはherokuにログインする。terminalheroku login heroku container:login次にherokuにappを作成する。
heroku create つけたいアプリ名
とすることでおk。
今回はbijobijoという適当なapp名をつけた。
ここでエラーが出たら、すでにあるアプリ名なのでつけ直す必要がある。heroku create bijobijo次にlocalのgitとremoteのgitを紐付ける必要がある。
以下のコマンドで紐付けは可能。terminalheroku git:remote -a アプリ名次に
heroku config:set つけたい環境変数名="設定する環境変数の文字列" --app 自分のアプリケーション名
とすることでherokuに環境変数がセットできる。そのため以下をセットする。
heroku config:set YOUR_CHANNEL_SECRET="Channel Secretの文字列" --app 自分のアプリケーション名 heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="アクセストークンの文字列" --app 自分のアプリケーション名configに関しては以下のようにherokuのサイトで自分のアプリよりsettingのconfig varsより確認することも可能。
セットした環境変数は
heroku configで確認することもできる。
これで環境変数が設定できたのでuploadしていく。
ここで詰まったとこ
みんな安易に
heroku container:push webとしてたからdocker-compose.ymlの名前のことかと思い
heroku container:push appとしていたがうまく起動しなかった。
どういうことか検索していると、以下の記事に答えが書いてあった。
Container Registry & Runtime (Docker Deploys)
heroku container:push <process-type>To push multiple images, rename your Dockerfiles using Dockerfile.:
つまり、Dockerfile.webという名前をつけていればこれを起動させることができる。
すぐにDockerfileをDockerfile.webに書き換えて、以下のコマンドを順々に叩く。
terminalheroku container:push web heroku container:release webこれでアプリがリリースされた状態になる。
ここで以下のコマンドを叩き、hello!と書いてあるページに遷移すればokである。
terminalheroku open実際に動いているコンテナについてはheroku公式より自身のアプリからResourcesより確認することができる。
以下であればwebが起動しているのがわかる。最後に、LINE Developerより自身のchannelに移動し、Messaging APIより
Webhook settingsを選択し、
https://{自身のアプリ名}.herokuapp.com/callback
をセットしてやれば終わりである。
また、以下のようにUse webhook
をonにしないとlinebotが機能しないので注意。
これで毎日美人とメッセージのやり取りができる!!
あれ、なんか固定メッセージが来ているようなので対処します。
Messaging APIより
Auto-replay messages
を選択。
応答設定→詳細設定→応答メッセージ→応答メッセージ設定→オフ
でこれが解消される。ではでは、
うまく返せていますね。
こころなしか虚しいです。
linebotを使うことで業務の自動化などもできそうなのでこれ以降も挑戦していきたいと思う。
参考記事
全体図
初心者でも簡単!PythonでLINEチャットボットを作成してみよう!
herokuでenvironmentを設定する方法
Python + HerokuでLINE BOTを作ってみた
requirements.txtの取り扱い
Python, pip list / freezeでインストール済みパッケージ一覧を確認
dockerのherokuへのpush
Container Registry & Runtime
↑これがreleaseの際に最も役に立った。Local Development with Docker Compose
Python初心者がFlaskでLINEbotを作ることになった(Heroku+ClearDB編)