20210417のdockerに関する記事は7件です。

WARNING:apt does not have..を消す

変数をAptに渡すだけでWARNING:は消えます。 ### Please set in your using shell. # Variable ## POSIX DEBIAN_FRONTEND=noninteractive ## Fish DEBIAN_FRONTEND noninteractive # Example to use ## Uses `env` env DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends superiorvirus 覚えられないし、調べてもなかなか出てこないので。。。。 manではapt-getが推奨ですが、アレルギーなので使えません。 というか、/dev/nullにリダイレクトしてるのをちらほら見受けたんだけど、なんも見えなくていいのかな、、? Dockerや炒め物(shellscript)、チャーハン(CI)などに
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

厚生労働省オープンデータからCOVID-19 PCR検査陽性者数をツィートするDockerコンテナを作ってみた

この記事の目的 厚生労働省が公開しているオープンデータをフェッチして、今日のPCR PCR検査陽性者数をTwitterにツィートするDockerコンテナを作成します。 開発・実行環境 Windows ホストPC エディション:Windows 10 Home バージョン:20H2 OS ビルド:19042.867 エクスペリエンス:Windows Feature Experience Pack 120.2212.551.0 Docker Desktop 3.2.2 Docker 20.10.5 build 55c4c88 厚生労働省のオープンデータをフェッチする データをフェッチするスクリプトを開発する 厚生労働省のオープンデータの保存場所を調査します。このページを眺めるとオープンデータは"https://www.mhlw.go.jp/content/"にcsv形式で保存されていることがわかります。 Pythonのrequestsモジュールを使ってオープンデータをフェッチしましょう。今回はこんなコードを書きました。 mhlw/uri_list.py # coding: UTF-8 uri_list = [ 'pcr_positive_daily.csv', 'pcr_tested_daily.csv', 'cases_total.csv' ] if __name__ == '__main__': from sys import stdout for uri in uri_list: stdout.write(f'{uri}\n') オープンデータはもっとあるのですが、今回はuri_listで格納した3ファイルをフェッチします。実際に使うのはpcr_positive_daily.csvだけです。 mhlw/fetch.py # coding: UTF-8 if __name__ == '__main__': from sys import argv, path from urllib.parse import urljoin path.append('http') import http_client endpoint_url = argv[1] uri_list = argv[2:] for uri in uri_list: url = urljoin(endpoint_url, uri) http = http_client.HttpClient(url) res = http.sync_get() with open(uri, 'w') as f: f.write(res) http/http_client.py # coding: UTF-8 class HttpClient: def __init__(self, url): self._url = url def sync_get(self): import requests self._res = requests.get(self._url) body = None if self._res.status_code == 200: body = self._res.text else: raise RuntimeError('The http request is failed.') return body 次のように実行しました。lsコマンドを実行すると3つのcsvファイルがフェッチできていることがわかります。 (base) root@251c769e696d:/mnt/docker/anaconda3/covid-19_mhlw_open_data# python mhlw/uri_list.py | xargs python mhlw/fetch.py "https://www.mhlw.go.jp/content/" (base) root@251c769e696d:/mnt/docker/anaconda3/covid-19_mhlw_open_data# ls http mhlw pcr_positive_daily.csv pcr_tested_daily.csv もともとのcsvの文字コードがutf-8ではないため(たぶんShift-JISかな)、ヘッダの日本語が文字化けしちゃいました。今回は気にせずこのまま進めます。 実行するDockerfileを作成する 次に開発したスクリプトを動作させるDockerコンテナを作ります。 Dockerfile FROM python:3.9.4-slim-buster ENV WORKDIR_NAME "/app" ENV DIR_HTTP "http" ENV DIR_MHLW "mhlw" ENV ENDPOINT_URL "https://www.mhlw.go.jp/content/" WORKDIR $WORKDIR_NAME RUN mkdir $DIR_HTTP RUN mkdir $DIR_MHLW COPY ./${DIR_HTTP}/*.py ${WORKDIR_NAME}/${DIR_HTTP}/ COPY ./${DIR_MHLW}/*.py ${WORKDIR_NAME}/${DIR_MHLW}/ RUN pip install requests CMD python ${DIR_MHLW}/uri_list.py | xargs python ${DIR_MHLW}/fetch.py ${EHLW_ENDPOINT_URL} ビルドして実行します。今回は期待値が得られているか確認したいので、次のコマンドでイメージのビルド、コンテナの作成・実行を行います。 PS > docker build --tag=covid19 . PS > docker run covid19 残念ながらこのままだとPythonスクリプトは期待通りに動作しません。なぜならDockerコンテナからエンドポイントのドメイン mhlw.go.jp の名前解決ができないからです。この辺はDockerコンテナ・ネットワークを解説しないとうまく説明できないので別記事で解説しようと思いますが、一言で説明するとDockerコンテナが属しているネットワーク・サブネットとホストPCが属しているネットワーク・サブネットが異なります。なのでコンテナが属しているネットワークからインターネットに直接アクセスできません。 余談ですが、デバッグしたい場合はコンテナにインタラクティブモードで接続するのがおススメです。 PS > docker run --interactive --tty covid19 bash コンテナからホスト経由でインターネットにアクセスする 真面目に対応するのであれば、ホストPCのNATの設定を変更したりするのでしょうが(すみません、ちゃんと調査していません)、今回は開発環境兼実行環境のWindowsホストPCで実行するので、Dockerコンテナをhostネットワークに紐づけて実行します。 こんな感じで実行しました。 PS > docker run --net host covid19 cases_total.csv fetch.py pcr_positive_daily.csv pcr_tested_daily.csv uri_list.py PS > hostネットワークって何ぞや、ということですが、簡単に説明しますとdockerをインストールするとデフォルトで3つの仮想ネットワークを作成します。そのうちの1つがhostネットワークでDockerエンジンが動作しているホストPCと同じサブネットの仮想ネットワークにコンテナが接続されます。Dockerの仮想ネットワークはdocker network lsコマンドで確認できます。 PS > docker network ls NETWORK ID NAME DRIVER SCOPE e9f868af4a34 bridge bridge local 4b2fd62d429a host host local b475f904ff07 none null local 詳しくは公式ページをご覧ください。僕もそのうち解説します。(3年くらいにすごくまじめに調べた記憶があるのですが、今はうるおぼえ故に。すみません。) 補足 オープンデータのフェッチのためにPythonスクリプト書いたけれども、curlでもよかったなぁ。 今日のPCR検査陽性者数を求める PCR検査陽性者数を分析するスクリプトを開発する まずは分析のスタートポイントを実装します。 mhlw/analysis.py # coding: UTF-8 scripts = { 'pcr_positive_daily.csv': 'analysis_pcr_positive_daily.py', 'pcr_tested_daily.csv' : None, 'cases_total.csv' : None } if __name__ == '__main__': from sys import argv, path from os.path import dirname, join from subprocess import Popen, PIPE import binascii file_name = argv[1] script = scripts.get(file_name) if script != None: data = None with open(argv[1], 'rb') as input: script = join(dirname(argv[0]), script) with Popen(['python', script], stdin=input, stdout=PIPE) as pipe: data = pipe.stdout.read() res = data.decode(encoding='utf-8') print(f'\"{res}\"') 次にpcr_positive_daily.csvを解析して、本日のPCR検査陽性者数を分析するスクリプトを作成します。Pandaを使えば簡単に詳細な解析できると思いますが、今回は割愛します。(Pandaはちょっと触ったぐらいなので今後調査したいです。) analysis_pcr_positive_daily.py # coding: UTF-8 if __name__ == '__main__': from sys import argv, path from sys import stdin, stdout from csv import reader from datetime import datetime data = list(reader(stdin)) header = data[:1][0] body = data[1:] now = datetime.now() key = f'{now.year}/{now.month}/{now.day}' item = [ item for item in body if item[0] == key ] stdout.write(f'As of {key}, the number of positive PCR tests in Japan is {item[0][1]}.') 開発環境で実行します。こんな感じです。 (base) root@251c769e696d:/mnt/docker/anaconda3/covid-19_mhlw_open_data# ls -1 *.csv | xargs -l python mhlw/analysis.py "As of 2021/4/15, the number of positive PCR tests in Japan is 4570." (base) root@251c769e696d:/mnt/docker/anaconda3/covid-19_mhlw_open_data# Dockerfileを更新する 開発環境で動作したのでDockerfileを更新して動作確認をします。 FROM python:3.9.4-slim-buster ENV WORKDIR_NAME "/app" ENV DIR_HTTP "http" ENV DIR_MHLW "mhlw" ENV ENDPOINT_URL "https://www.mhlw.go.jp/content/" WORKDIR $WORKDIR_NAME RUN mkdir $DIR_HTTP RUN mkdir $DIR_MHLW COPY ./${DIR_HTTP}/*.py ${WORKDIR_NAME}/${DIR_HTTP}/ COPY ./${DIR_MHLW}/*.py ${WORKDIR_NAME}/${DIR_MHLW}/ RUN pip install requests CMD python ${DIR_MHLW}/uri_list.py | xargs python ${DIR_MHLW}/fetch.py ${EHLW_ENDPOINT_URL} && ls *.csv | xargs -l python ${DIR_MHLW}/analysis.py CMDが長くなってきましたね。シェルスクリプトにまとめたほうが良いかもしれません。イメージからコンテナを作成して実行します。 PS > docker build --tag=covid19 . PS > docker run --net host covid19 "As of 2021/4/15, the number of positive PCR tests in Japan is 4570." PS > ツィートする 本日の陽性者数が分析できたので最後にツィートします。Python Twitter Toolsを使います。 pipでインストールできるようです。 # pip install twitter 今回はこんなコードを書きました。 twitter/twitter_client.py # coding: UTF-8 if __name__ == '__main__': from sys import argv, path from datetime import datetime from requests_oauthlib import OAuth1Session from twitter import * path.append('.') import runtime_env tweet = (argv[1]).replace('"', '') endpoint_url = runtime_env.twitter_endpoint_url() token = runtime_env.twitter_access_token() token_secret = runtime_env.twitter_access_token_secret() consumer_key = runtime_env.twitter_api_key() consumer_secret = runtime_env.twitter_api_secret_key() t = Twitter(auth=OAuth(token, token_secret, consumer_key, consumer_secret)) t.statuses.update(status=tweet) Twitterにツィートするにはアカウントのトークンが必要になりますが、スクリプトにコーディングするのは危険なので環境変数から読み込むようにしています。環境変数を読みだすスクリプトを記述しました。 runtime_env.py # coding: UTF-8 def twitter_endpoint_url(): import os return os.environ['TWITTER_POST_ENDPOINT_URL'] def twitter_access_token(): import os return os.environ['TWITTER_ACCESS_TOKEN'] def twitter_access_token_secret(): import os return os.environ['TWITTER_TOKEN_SECRET'] def twitter_api_key(): import os return os.environ['TWITTER_API_KEY'] def twitter_api_secret_key(): import os return os.environ['TWITTER_API_SECRET_KEY'] Dockerfileを更新します。こんな感じで記述しました。 FROM python:3.9.4-slim-buster ENV WORKDIR_NAME "/app" ENV DIR_HTTP "http" ENV DIR_MHLW "mhlw" ENV DIR_TWITTER "twitter" ENV EHLW_ENDPOINT_URL "https://www.mhlw.go.jp/content/" ENV TWITTER_POST_ENDPOINT_URL "https://api.twitter.com/1.1/statuses/update.json" ENV TWITTER_ACCESS_TOKEN "<アクセストークン>" ENV TWITTER_TOKEN_SECRET "<アクセストークン・シークレット>" ENV TWITTER_API_KEY "<APIキー>" ENV TWITTER_API_SECRET_KEY "<APIキー・シークレット>" WORKDIR $WORKDIR_NAME RUN mkdir $DIR_HTTP RUN mkdir $DIR_MHLW RUN mkdir $DIR_TWITTER COPY ./*.py ${WORKDIR_NAME}/ COPY ./${DIR_HTTP}/*.py ${WORKDIR_NAME}/${DIR_HTTP}/ COPY ./${DIR_MHLW}/*.py ${WORKDIR_NAME}/${DIR_MHLW}/ COPY ./${DIR_TWITTER}/*.py ${WORKDIR_NAME}/${DIR_TWITTER}/ RUN pip install requests RUN pip install twitter RUN pip install requests-oauthlib CMD python ${DIR_MHLW}/uri_list.py | xargs python ${DIR_MHLW}/fetch.py ${EHLW_ENDPOINT_URL} && ls *.csv | xargs -l python ${DIR_MHLW}/analysis.py | xargs -0 python ${DIR_TWITTER}/twitter_client.py イマージからコンテナを作成して実行します。こんな感じです。 PS > docker build --tag=covid19 . PS > docker run --net host covid19 PS > Twitterのタイムラインを見るとツィートできていました。 まとめ 結構おおらかなスクリプトになってしまったので真面目に作るならもうちょいちゃんとしなきゃな、と思います。Dockerfile の CMD 行が長くなってしまったのでシェルスクリプトかPythonスクリプト化してもよいかもですね。 やっぱり厚生労働省の csv ファイルは curl 使えばよかったと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel dockerでnpmを使う時

phpのDockerfileに # nodejs install RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - RUN apt-get install -y nodejs こちらの記述を書くこと 12.xはバージョン 参考 nodeのバージョン
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerをpushしようとしたらdeniedとエラーが出た

課題 docker push を実行すると denied: requested access to the resource is denied と表示されpushを行うことができなかった。 解決策 イメージをローカルで作成後、プッシュをするにはtagを作成する必要がある。 (githubのcommitと同じような感じだな) % docker tag イメージID DockerHubのユーザ名/任意の名前 その後、任意でつけたイメージ名を指定してpushすればいい 例 イメージID:123456789012 DockerHubのユーザ名:hogehoge % docker tag 123456789012 hogehoge/mogemoge を実行後、push % docker push 123456789012 hogehoge/mogemoge
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Elasticsearch-railsのサンプルを触ってみた

環境構築 Rails6/Docker/MySQL + Elasticsearch 環境構築 が完了した時点からのスタート Gem追加 gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git' gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git' bin/bundle install model作成 # コンテナ内に入る docker exec -it railsのコンテナ名 bash bin/rails g model author name:string bin/rails g model publisher name:string bin/rails g model category name:string bon/rails g model manga author:references publisher:references category:references title:string description:text bi/rails db:migrate seedにサンプルデータを投入 seeds.rb # This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). # # Examples: # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) # category ct1 = Category.create(name: 'バトル・アクション') ct2 = Category.create(name: 'ギャグ・コメディ') ct3 = Category.create(name: 'ファンタジー') ct4 = Category.create(name: 'スポーツ') ct5 = Category.create(name: 'ラブコメ') ct6 = Category.create(name: '恋愛') ct7 = Category.create(name: '異世界') ct8 = Category.create(name: '日常系') ct9 = Category.create(name: 'グルメ') ct10 = Category.create(name: 'ミステリー・サスペンス') ct11 = Category.create(name: 'ホラー') ct12 = Category.create(name: 'SF') ct13 = Category.create(name: 'ロボット') ct14 = Category.create(name: '歴史') ct15 = Category.create(name: '少女漫画') ct16 = Category.create(name: '戦争') ct17 = Category.create(name: '職業・ビジネス') ct18 = Category.create(name: 'お色気') ct19 = Category.create(name: '学園もの') # 出版社 pb1 = Publisher.create(name: '集英社') pb2 = Publisher.create(name: '講談社') pb3 = Publisher.create(name: '小学館') pb4 = Publisher.create(name: '芳文社') pb5 = Publisher.create(name: '双葉社') # 作者 at1 = Author.create(name: '原泰久') at2 = Author.create(name: '堀越耕平') at3 = Author.create(name: '清水茜') at4 = Author.create(name: '井上雄彦') at5 = Author.create(name: '吉田秋生') at6 = Author.create(name: '野田サトル') at7 = Author.create(name: 'あfろ') at8 = Author.create(name: '神尾葉子') at9 = Author.create(name: '冨樫義博') at10 = Author.create(name: '川上秦樹') at11 = Author.create(name: 'こうの史代') at12 = Author.create(name: '古舘春一') at13 = Author.create(name: '三田紀房') at14 = Author.create(name: '藤沢とおる') # 漫画 Manga.create(title: "キングダム", publisher: pb1, author: at1, category: ct14, description: "時は紀元前―。いまだ一度も統一されたことのない中国大陸は、500年の大戦争時代。苛烈な戦乱の世に生きる少年・信は、自らの腕で天下に名を成すことを目指す!!") Manga.create(title: "僕のヒーローアカデミア", publisher: pb1, author: at3, category: ct1, description: "多くの人間が“個性という力を持つ。だが、それは必ずしも正義の為の力ではない。しかし、避けられぬ悪が存在する様に、そこには必ず我らヒーローがいる! ん? 私が誰かって? HA‐HA‐HA‐HA‐HA! さぁ、始まるぞ少年! 君だけの夢に突き進め! “Plus Ultra!!") Manga.create(title: "はたらく細胞", publisher: pb2, author: at3, category: ct1, description: "人間1人あたりの細胞の数、およそ60兆個! そこには細胞の数だけ仕事(ドラマ)がある! ウイルスや細菌が体内に侵入した時、アレルギー反応が起こった時、ケガをした時などなど、白血球と赤血球を中心とした体内細胞の人知れぬ活躍を描いた「細胞擬人化漫画」の話題作、ついに登場!!肺炎球菌! スギ花粉症! インフルエンザ! すり傷! 次々とこの世界(体)を襲う脅威。その時、体の中ではどんな攻防が繰り広げられているのか!? 白血球、赤血球、血小板、B細胞、T細胞...etc.彼らは働く、24時間365日休みなく!") Manga.create(title: "スラムダンク SLAM DUNK 新装再編版", publisher: pb1, author: at4, category: ct4, description: '中学時代、50人の女の子にフラれた桜木花道。そんな男が、進学した湘北高校で赤木晴子に一目惚れ! 「バスケットは…お好きですか?」。この一言が、ワルで名高い花道の高校生活を変えることに!!') Manga.create(title: "BANANA FISH バナナフィッシュ 復刻版全巻BOX", publisher: pb3, author: at5, category: ct15, description: 'フラワーコミックスの黄色いカバーを完全再現!!吉田秋生の不朽の名作が復刻版BOXとなって登場しました。フラワーコミックスの黄色いカバーを完全再現したコミックスと、特典ポストカードをセットにした完全保存版。ポストカードはファン垂涎の、アッシュ・英二のイラストをセレクトしたここでしか手に入らないオリジナルです。') Manga.create(title: "ゴールデンカムイ", publisher: pb1, author: at6, category: ct1, description: '『不死身の杉元』日露戦争での鬼神の如き武功から、そう謳われた兵士は、ある目的の為に大金を欲し、かつてゴールドラッシュに沸いた北海道へ足を踏み入れる。そこにはアイヌが隠した莫大な埋蔵金への手掛かりが!? 立ち塞がる圧倒的な大自然と凶悪な死刑囚。そして、アイヌの少女、エゾ狼との出逢い。『黄金を巡る生存競争』開幕ッ!!!!') Manga.create(title: "ゆるキャン△", publisher: pb4, author: at7, category: ct8, description: '富士山が見える湖畔で、一人キャンプをする女の子、リン。一人自転車に乗り、富士山を見にきた女の子、なでしこ。二人でカップラーメンを食べて見た景色は…。読めばキャンプに行きたくなる。行かなくても行った気分になる。そんな新感覚キャンプマンガの登場です!') Manga.create(title: "花のち晴れ〜花男 Next Season〜", publisher: pb1, author: at8, category: ct6, description: '英徳学園からF4が卒業して2年…。F4のリーダー・道明寺司に憧れる神楽木晴は、「コレクト5」を結成し、学園の品格を保つため“庶民狩りを始めた!! 隠れ庶民として学園に通う江戸川音はバイト中に晴と遭遇し!?') Manga.create(title: "HUNTER×HUNTER ハンター×ハンター", publisher: pb1, author: at9, category: ct1, description: '父と同じハンターになるため、そして父に会うため、ゴンの旅が始まった。同じようにハンターになるため試験を受ける、レオリオ・クラピカ・キルアと共に、次々と難関を突破していくが…!?') Manga.create(title: "転生したらスライムだった件", publisher: pb2, author: at10, category: ct7, description: '通り魔に刺されて死んだと思ったら、異世界でスライムに転生しちゃってた!?相手の能力を奪う「捕食者」と世界の理を知る「大賢者」、2つのユニークスキルを武器に、スライムの大冒険が今始まる!異世界転生モノの名作を、原作者完全監修でコミカライズ!') Manga.create(title: "この世界の片隅に", publisher: pb5, author: at11, category: ct16, description: '平成の名作・ロングセラー「夕凪の街 桜の国」の第2弾ともいうべき本作。戦中の広島県の軍都、呉を舞台にした家族ドラマ。主人公、すずは広島市から呉へ嫁ぎ、新しい家族、新しい街、新しい世界に戸惑う。しかし、一日一日を確かに健気に生きていく…。') Manga.create(title: "スラムダンク SLAM DUNK", publisher: pb1, author: at4, category: ct4, description: '中学3年間で50人もの女性にフラれた高校1年の不良少年・桜木花道は背の高さと身体能力からバスケットボール部の主将の妹、赤木晴子にバスケット部への入部を薦められる。彼女に一目惚れした「初心者」花道は彼女目当てに入部するも、練習・試合を通じて徐々にバスケットの面白さに目覚めていき、才能を開花させながら、全国制覇を目指していくのであったが……。') Manga.create(title: "ハイキュー!!", publisher: pb1, author: at12, category: ct4, description: 'おれは飛べる!! バレーボールに魅せられ、中学最初で最後の公式戦に臨んだ日向翔陽。だが、「コート上の王様」と異名を取る天才選手・影山に惨敗してしまう。リベンジを誓い烏野高校バレー部の門を叩く日向だが!?') Manga.create(title: "インベスターZ", publisher: pb2, author: at13, category: ct17, description: '創立130年の超進学校・道塾学園に、トップで合格した財前孝史。入学式翌日に、財前に明かされた学園の秘密。各学年成績トップ6人のみが参加する「投資部」が存在するのだ。彼らの使命は3000億を運用し、年8%以上の利回りを生み出すこと。それゆえ日本最高基準の教育設備を誇る道塾学園は学費が無料だった!「この世で一番エキサイティングなゲーム、人間の血が最も沸き返る究極の勝負……それは金……投資だよ!」') Manga.create(title: "GTO", publisher: pb2, author: at14, category: ct19, description: "かつて最強の不良「鬼爆」の一人として湘南に君臨した鬼塚英吉は、辻堂高校を中退後、優羅志亜(ユーラシア)大学に替え玉試験で入学した。彼は持ち前の体力と度胸、純粋な一途さと若干の不純な動機で、教師を目指した。無茶苦茶だが、目先の理屈よりも「ものの道理」を通そうとする鬼塚の行為に東京吉祥学苑理事長の桜井良子が目を付け、ある事情を隠して中等部の教員として採用する。学園内に蔓延する不正義や生徒内に淀むイジメの問題、そして何より体面や体裁に振り回され、臭いものに蓋をして見て見ぬ振りをしてしまう大人たち、それを信じられなくなって屈折してしまった子どもたち。この学園には様々な問題が山積していたのである。桜井は、鬼塚が問題に真っ向からぶつかり、豪快な力技で解決してくれることに一縷の望みを託すようになる。") bin/rails db:seed Controller, View, Routing を追加 bin/rails g controller Mangas index app/controllers/mangas_controller.rb class MangasController < ApplicationController def index @mangas = Manga.all end end config/route.rb Rails.application.routes.draw do root 'mangas#index' resources :mangas, only: %i(index) end app/views/mangas/index.html.erb <h1>Mangas</h1> <table> <thead> <tr> <th>Aauthor</th> <th>Publisher</th> <th>Category</th> <th>Author</th> <th>Title</th> <th>Description</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @mangas.each do |manga| %> <tr> <td><%= manga.author.name %></td> <td><%= manga.publisher.name %></td> <td><%= manga.category.name %></td> <td><%= manga.author.name %></td> <td><%= manga.title %></td> <td><%= manga.description %></td> </tr> <% end %> </tbody> </table> この時点でページを確認しようと、dockerを再度upしたところ、Gemfileが変更されていることによって?、railsのコンテナが起動しなかったため、buildしなおした。 docker-compose build もしくは、bundle install するなら、 docker-compose run web bundle install ここで一旦ページにseedで登録した内容が表示されているか確認しましょう ここからelasticsearchの部分に入っていきます configの設定 config/initializers/elasticsearch.rb # 「elasticsearch」はdocker-composeのservicesに設定した名前に合わせる config = { host: ENV['ELASTICSEARCH_HOST'] || "elasticsearch:9200/", } Elasticsearch::Model.client = Elasticsearch::Client.new(config) concernsの設定 app/models/manga.rb class Manga < ApplicationRecord include MangaSearchable belongs_to :author belongs_to :publisher belongs_to :category end app/models/concerns/manga_searchable.rb module MangaSearchable extend ActiveSupport::Concern included do include Elasticsearch::Model # Callbacksを指定すると、テーブルの更新時にelasticsearchも更新される include Elasticsearch::Model::Callbacks # ①index名 index_name "es_manga_#{Rails.env}" # ②マッピング情報 settings do mappings dynamic: 'false' do indexes :id, type: 'integer' indexes :publisher, type: 'keyword' indexes :author, type: 'keyword' indexes :category, type: 'text', analyzer: 'kuromoji' indexes :title, type: 'text', analyzer: 'kuromoji' indexes :description, type: 'text', analyzer: 'kuromoji' end end # ③mappingの定義に合わせてindexするドキュメントの情報を生成する def as_indexed_json(*) attributes .symbolize_keys .slice(:id, :title, :description) .merge(publisher: publisher_name, author: author_name, category: category_name) end end def publisher_name publisher.name end def author_name author.name end def category_name category.name end class_methods do # ④indexを作成するメソッド def create_index! client = __elasticsearch__.client # すでにindexを作成済みの場合は削除する client.indices.delete index: self.index_name rescue nil # indexを作成する client.indices.create(index: self.index_name, body: { settings: self.settings.to_hash, mappings: self.mappings.to_hash }) end end end このファイル内の動きはこの後説明(自身もまず動くものを確認したいので後ほど) 動作確認 bin/rails c elasticsearchの接続確認 pry(main)> Manga.__elasticsearch__.client.cluster.health => {"cluster_name"=>"docker-cluster", "status"=>"green", "timed_out"=>false, "number_of_nodes"=>1, "number_of_data_nodes"=>1, "active_primary_shards"=>0, "active_shards"=>0, "relocating_shards"=>0, "initializing_shards"=>0, "unassigned_shards"=>0, "delayed_unassigned_shards"=>0, "number_of_pending_tasks"=>0, "number_of_in_flight_fetch"=>0, "task_max_waiting_in_queue_millis"=>0, "active_shards_percent_as_number"=>100.0} indexの作成 pry(main)> Manga.create_index! => {"acknowledged"=>true, "shards_acknowledged"=>true, "index"=>"es_manga_development"} データの登録 Manga.__elasticsearch__.import (1.8ms) SET NAMES utf8mb4, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 Manga Load (1.0ms) SELECT `mangas`.* FROM `mangas` ORDER BY `mangas`.`id` ASC LIMIT 1000 Publisher Load (1.4ms) SELECT `publishers`.* FROM `publishers` WHERE `publishers`.`id` = 1 LIMIT 1 . . 検索機能の追加 ここで自分は詰まったのだが、integer型のidを含めると、数字は検索可能なのだが、テキストはエラーになる。(型の違いによるエラー) multi_match type: 'cross_fields'を指定することで複数typeも検索可能だと思っていたのだが、上手く動作しなかったため、今回idは削除。 config/initializers/elasticsearch.rb class_methods do # ... # indexes :id, type: 'integer' # ... def es_search(query) __elasticsearch__.search({ query: { multi_match: { fields: %w(publisher author category title description), type: 'cross_fields', query: query, operator: 'and' # 検索fieldsによって重み付けしたい時(例:titleでヒットした場合は2倍) # fields: ["title^2", "descritption"] } } }) end end end Controller修正 app/controllers/mangas_controller.rb class MangasController < ApplicationController def index @mangas = if search_word.present? Manga.es_search(search_word).records else Manga.all end end private def search_word @search_word ||= params[:search_word] end end Viewの修正 app/views/mangas/index.html.erb // ... // 検索フォームを追加 <div> <%= form_tag(mangas_path, method: :get) do %> <div> <%= text_field_tag :search_word, @search_word, placeholder: "漫画を検索する" %> </div> <div> <%= submit_tag "検索" %> </div> <% end %> </div> <div> <table> // ... 動作確認 ここまでで一旦動作します。 自分の場合は、なかなか動かず時間がかかりました。 参考記事 RailsとElasticsearchで検索機能をつくり色々試してみる - その1:サンプルアプリケーションの作成 Rails6でElasticsearchのキーワード検索実装ハンズオン elastisearch-railsを使ってRailsでElasticsearchを動かす【初心者向け】 Elastic SearchでString型のカラムが取り込めないエラー Query DSL
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JetsonXavierでdocker-composeを使用する。apt不使用、pip使用

Jetson上でのdocker-composeの入れ方です。 公式のcurlを使用したもので入れることができなかったため、pipで入れました。 以下のとおりです。 インストール手順 $ sudo apt update $ sudo apt install python3-pip $ sudo apt install build-essential libssl-dev libffi-dev python3-dev $ sudo pip3 install docker-compose
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JetsonXavierでYOLOv5+DeepSortを動かす。Docker使用

元イメージ 元イメージには、nvidiaが用意しているイメージを使用します。 https://ngc.nvidia.com/catalog/containers/nvidia:l4t-pytorch FROM nvcr.io/nvidia/l4t-pytorch:r32.5.0-pth1.7-py3 apt install 必要なパッケージをインストールします。 xtermは、docker上の表示をローカルに表示するために必要です。 yoloの場合、Docker上の推論結果の画面をローカルで表示するために使います。 FROM nvcr.io/nvidia/l4t-pytorch:r32.5.0-pth1.7-py3 RUN apt update \ && apt install -y \ sudo \ vim \ xterm pip install Yoloで必要なパッケージをインストールします。 ここで注意が必要で、yoloのrequirement.txtをそのままインストールすると、torchやtorchvisionのバージョンが崩れてしまいます。Nvidaiのイメージにこれらはすでに含まれているため、txtから抜きました。 また、pipをアップグレードする必要があります。 FROM nvcr.io/nvidia/l4t-pytorch:r32.5.0-pth1.7-py3 RUN apt update \ && apt install -y \ sudo \ vim \ xterm RUN pip3 install -U pip RUN git clone https://github.com/kyasby/jetson-yolo.git requirements WORKDIR requirements RUN pip3 install -r requirements.txt おわりに さんざん苦労しましたが、以上のみで動きます。 https://github.com/kyasby/jetson-yolo.git 必要であれば、レポジトリそのままお使いもいただけます。 注意 --runtime nvidiaと指定しないと、import torchでエラーが出ます。 dockerの起動コマンドが長いため、docker-composeを使用しました。 install方法はこちら。 https://qiita.com/ryryry/items/b1d4b8604c71f638fe06
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む