20210116のdockerに関する記事は22件です。

docker-ce導入(CentOS7.9)

はじめに

よくインストールすることが多いのでメモ。
あと忘れがちなので...

名称 説明
docker-ce コミュニティエディション (無償版)
docker-ee エンタープライズエディション (有償版)

docker-ceインストール

  • MacBookAirで実行してるVagrant+VirtualBox+CentOS7.9で実施してます。
  • vagrantユーザで実施しています。

1. 不要なパッケージを削除する。

$ sudo yum remove docker \
                  docker-common \
                  docker-selinux \
                  docker-engine

2. 必要なパッケージをインストールする。

$ sudo yum install -y yum-utils \
                      device-mapper-persistent-data \
                      lvm2

3. リポジトリを追加する。

$ sudo yum-config-manager --add-repo \
       https://download.docker.com/linux/centos/docker-ce.repo

4. docker-ceのインストール

$ sudo yum install docker-ce

5. dockerグループにユーザ追加

※ユーザ追加するとsudo無しで実行可能となるため影響ないかは注意する。

$ sudo usermod -aG docker $USER

※dockerグループがない場合は追加する。

$ cat /etc/group | grep docker
$ sudo groupadd docker

6. docker起動、自動起動有効化

$ sudo systemctl enable docker
$ sudo systemctl start docker

7. 完了

ターミナルからexitして再ログインするとグループ反映される。


参照

Docker v17.03がリリース。今月からバージョン番号制度が変更になり、毎月リリース体制に

Docker CE の入手(CentOS 向け)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-compose.ymlの書き方についてまとめてみた

はじめに

Docker-compose.ymlについて理解できた部分が少し増えてきたので、アウトプットかつ備忘録としてこの記事を書きました。この記事を読む際は、前提知識としてリンク先の内容(①~⑥)は理解しておいた方が良いと思います。私もお世話になりました。
- Docker超入門①〜Dockerってなに?〜【初心者向け】

広く浅く知りたいという方向け(主に私のような初学者)に導入記事として書いたものなので、この記事を読み深く知りたくなった箇所は各自公式ドキュメントなどを読んでインプットしてください!

間違っている箇所があればご指摘のほどよろしくお願い致します。

説明するdocker-compose.yml  

docker-compose.yml
version: “3”

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    ports:
      - “8000:80"
    volumes:
      - ./src:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:8.0.21
    ports:
      - "53306:3306"
    volumes:
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/mysql_data:/var/lib/mysql
    env_file:
      - ./docker/db/db-variables.env

app:の詳細な設定はDockerfileに記述していますがその説明は省きます。
では!1つずつ見ていきましょう!

version

docker-composeで使用するバージョンを定義しています。
このバージョンによって、ComposeFileの書き方が異なるので、注意が必要です。
特にこだわりがなければ最新のものを記述するようにしましょう。

services

「サービス」は、起動するコンテナの設定の定義です。

Docker-Composeでは、アプリケーションを動かすための各要素をServiceとしています。

サービス定義には、そのサービスのために起動された各コンテナに適用される設定が含まれていて、それぞれのServicesの内容をネストさせて記述していきます。

app:,db:と書かれている箇所は、アプリケーションを動かすために使っている各要素の名前を書きます。ちなみに、app:やdb:のように定義した名前はdockerのログに表示されるので、誰が見てもわかりやすい名前にした方が良いと思います。

image

コンテナを起動するimageをDockerHubから指定します。リポジトリ/タグまたは部分的なimageIDを指定します。

書き方としては、以下のように書く。

MySQL(最新版)を使う場合 バージョンを指定する場合
mysql:latest mysql:5.7

build

ビルド時に適用される設定オプション。
ComposeFileを実行し、ビルドされるときのpathです。
build は、ビルドコンテキストへのパスを含む文字列として指定することができます。

context

Dockerfile を含むディレクトリへのパス。

与えられた値が相対パスの場合は、Composefileの場所からの相対パスとして解釈されます。

dockerfile

代替のDockerfileです。

Composeは代替ファイルを使ってビルドします。ビルドパスも指定する必要があります。ここで元となるdockerfileを指定する。

ports

ホスト側の値がキーであり、コンテナ側の値はバリューとなります。
ホスト側のポートとコンテナ側のポート[HOST:CONTAINER]するか、コンテナ側のポートのみ指定します。※この際、ホスト側のポートはランダムに選ばれます

書き方としては

xx形式
xx:yy形式
xx:yy:zz形式 があります。

portsはホスト側のポートとコンテナ側のポートをマッピングするためのセクションですが、書き方の違いによって下記の通り異なった挙動をとります。

xx形式はコンテナ側のポート番号のみを指定する書式であり、指定されたコンテナ側ポートがホスト側のランダムなポートとマッピングされます。

xx:yy形式はホスト側のポートとコンテナ側のポートを指定する書式です。xxがホスト側ポート、yyがコンテナ側ポートとなり、ホスト側のxx番ポートとコンテナ側のyy番ポートがマッピングされます。

xx:yy:zz形式は、xxが ホスト側のポートへの接続を許可する接続元IP、yyがホスト側のポート、zzがコンテナ側のポートとなります。ホスト側のyy番ポートへのアクセスはIPxxからの接続時のみ許可され、コンテナ側のzz番ポートとマッピングされます。

注意
HOST:CONTAINER形式でポートをマッピングする場合、60よりも低いコンテナポートを使うと、YAMLはxx:yy形式の数値をベース60の値として解析するため、誤った結果を出すかもしれません。この理由から、ポートマッピングを常に明示的に文字列として指定することをお勧めします。

とりあえず"8000:80”のように文字列で書きましょう。

volumes

データの永続化を目的とした機能であり、コンテナが削除されても volume が明示的に破棄されない限り、volume 中のデータは保持され続けます。

ホスト側のディレクトリをキー、コンテナ側のディレクトリをバリューとして記述します。

depends_on

サービス同士の依存関係を設定することができ、コンテナの起動タイミングを変更することができます。

上記の例では、app:のdepends_onでdbを指定している為、dbがappよりも先に起動するようになる。
この記述に従ってdocker-compose upは、依存関係順にサービスを起動します。

注意
depends_onはappを起動する前にdbが "準備ができた "状態になるのを待たず、それらが起動されるまで待つだけです。サービスの準備が整うのを待つ必要がある場合、https://docs.docker.com/compose/startup-order/ を参照してください。

env_file

.envファイルから環境変数を追加します。

docker-compose -f FILE で Composeファイルを指定している場合、env_file のパスはファイルがあるディレクトリからの相対パスになります。
今回は、.envファイルに環境変数を設定しています。(env_fileは自分で手を動かして環境変数を設定しないと理解しにくいと思うので流し読みしてください)

終わりに

分からないことは基本的に公式ドキュメントを読めば答えが出てくるので、この記事を読み理解できない箇所や気になった箇所があれば公式ドキュメントを読んでみてください。

少しでもお役に立てれば幸いです。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-compose.ymlでよく見るワードについてまとめてみた

はじめに

Docker-compose.ymlについて理解できた部分が少し増えてきたので、アウトプットかつ備忘録としてこの記事を書きました。この記事を読む際は、前提知識としてリンク先の内容(①~⑥)は理解しておいた方が良いと思います。私もお世話になりました。
- Docker超入門①〜Dockerってなに?〜【初心者向け】

広く浅く知りたいという方向け(主に私のような初学者)に導入記事として書いたものなので、この記事を読み深く知りたくなった箇所は各自公式ドキュメントなどを読んでインプットしてください!

間違っている箇所があればご指摘のほどよろしくお願い致します。

説明するdocker-compose.yml  

docker-compose.yml
version: “3”

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    ports:
      - “8000:80"
    volumes:
      - ./src:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:8.0.21
    ports:
      - "53306:3306"
    volumes:
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/mysql_data:/var/lib/mysql
    env_file:
      - ./docker/db/db-variables.env

app:の詳細な設定はDockerfileに記述していますがその説明は省きます。
では!1つずつ見ていきましょう!

version

docker-composeで使用するバージョンを定義しています。
このバージョンによって、ComposeFileの書き方が異なるので、注意が必要です。
特にこだわりがなければ最新のものを記述するようにしましょう。

services

「サービス」は、起動するコンテナの設定の定義です。

Docker-Composeでは、アプリケーションを動かすための各要素をServiceとしています。

サービス定義には、そのサービスのために起動された各コンテナに適用される設定が含まれていて、それぞれのServicesの内容をネストさせて記述していきます。

app:,db:と書かれている箇所は、アプリケーションを動かすために使っている各要素の名前を書きます。ちなみに、app:やdb:のように定義した名前はdockerのログに表示されるので、誰が見てもわかりやすい名前にした方が良いと思います。

image

コンテナを起動するimageをDockerHubから指定します。リポジトリ/タグまたは部分的なimageIDを指定します。

書き方としては、以下のように書く。

MySQL(最新版)の場合 バージョンを指定する場合
mysql:latest mysql:5.7

build

ビルド時に適用される設定オプション。
ComposeFileを実行し、ビルドされるときのpathです。
build は、ビルドコンテキストへのパスを含む文字列として指定することができます。

context

Dockerfile を含むディレクトリへのパス。

与えられた値が相対パスの場合は、Composefileの場所からの相対パスとして解釈されます。

dockerfile

代替のDockerfileです。

Composeは代替ファイルを使ってビルドします。ビルドパスも指定する必要があります。ここで元となるdockerfileを指定する。

ports

ホスト側の値がキーであり、コンテナ側の値はバリューとなります。
ホスト側のポートとコンテナ側のポート[HOST:CONTAINER]するか、コンテナ側のポートのみ指定します。※この際、ホスト側のポートはランダムに選ばれます

書き方としては

xx形式
xx:yy形式
xx:yy:zz形式 があります。

portsはホスト側のポートとコンテナ側のポートをマッピングするためのセクションですが、書き方の違いによって下記の通り異なった挙動をとります。

xx形式はコンテナ側のポート番号のみを指定する書式であり、指定されたコンテナ側ポートがホスト側のランダムなポートとマッピングされます。

xx:yy形式はホスト側のポートとコンテナ側のポートを指定する書式です。xxがホスト側ポート、yyがコンテナ側ポートとなり、ホスト側のxx番ポートとコンテナ側のyy番ポートがマッピングされます。

xx:yy:zz形式は、xxが ホスト側のポートへの接続を許可する接続元IP、yyがホスト側のポート、zzがコンテナ側のポートとなります。ホスト側のyy番ポートへのアクセスはIPxxからの接続時のみ許可され、コンテナ側のzz番ポートとマッピングされます。

注意
HOST:CONTAINER形式でポートをマッピングする場合、60よりも低いコンテナポートを使うと、YAMLはxx:yy形式の数値をベース60の値として解析するため、誤った結果を出すかもしれません。この理由から、ポートマッピングを常に明示的に文字列として指定することをお勧めします。

とりあえず"8000:80”のように文字列で書きましょう。

volumes

データの永続化を目的とした機能であり、コンテナが削除されても volume が明示的に破棄されない限り、volume 中のデータは保持され続けます。

ホスト側のディレクトリをキー、コンテナ側のディレクトリをバリューとして記述します。

depends_on

サービス同士の依存関係を設定することができ、コンテナの起動タイミングを変更することができます。

上記の例では、app:のdepends_onでdbを指定している為、dbがappよりも先に起動するようになる。
この記述に従ってdocker-compose upは、依存関係順にサービスを起動します。

注意
depends_onはappを起動する前にdbが "準備ができた "状態になるのを待たず、それらが起動されるまで待つだけです。サービスの準備が整うのを待つ必要がある場合、https://docs.docker.com/compose/startup-order/ を参照してください。

env_file

.envファイルから環境変数を追加します。

docker-compose -f FILE で Composeファイルを指定している場合、env_file のパスはファイルがあるディレクトリからの相対パスになります。
今回は、.envファイルに環境変数を設定しています。(env_fileは自分で手を動かして環境変数を設定しないと理解しにくいと思うので流し読みしてください)

終わりに

分からないことは基本的に公式ドキュメントを読めば答えが出てくるので、この記事を読み理解できない箇所や気になった箇所があれば公式ドキュメントを読んでみてください。

少しでもお役に立てれば幸いです。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerとは

◯Dockerとは?

 コンテナという技術を使いコンテナの中に環境構築し、コンテナの中で開発をするこの一連の流れを簡単に実装できるもの。

◯Dockerに関するコマンド

①docker login

 Dockerにログインするときに使用するコマンド

②docker pull [image]

 docker-imageをHostにpullするときに使用コマンド

③docker images

 Hostにあるdoker-imageの一覧を表示させるときに使用するコマンド

④docker run [image]

 Hostにあるdocker-imageからコンテナを作成するときに使用するコマンド

⑤docker ps -a

 コンテナの一覧を表示させるときに使用するコマンド
 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【CircleCI2.0】JavaScript に対応するように設定

はじめに

CircleCI で JavaScript を扱えるように設定しました。
今まで問題なく動作していた CircleCI のテストでしたが、あることをしてから通らなくなったので対処方法を記していきます。

今までの設定ファイルはこちらです。

目次

  • 環境

  • 問題

  • 原因

    • RSpecでjs: trueを使用
    • 今回 ローカル環境CircleCI環境 をあわせるために行った変更
  • 解決策

    • spec/support/capybara.rb
      • 変更前
      • 変更後
    • spec/rails_helper.rb
    • Dockerfile
    • .circleci/config.yml
    • .circleci/config.yml 全体
    • config/database.yml.ci
  • まとめ

  • おわりに

  • 参考文献

環境

  • Ruby: 2.6.6
  • Bundler: 2.0.2
  • MySQL: 8.0
  • CircleCI: 2.0
  • yarnでjQuery( JavaScript )を使用。( ※ gemとyarnでの使用方法の違いでテストの結果に影響でることが考えられるため。 )

問題

SocketError: 
Failed to open TCP connection to chrome:4444 
(getaddrinfo: No address associated with hostname)
# chrome:4444へのTCP接続のオープンに失敗
SocketError: getaddrinfo: No address associated with hostname
# ホスト名に関連付けられたアドレスはありません

原因

RSpecでjs: trueを使用

RSpecで JavaScriptのテストを実装 したところローカル環境で通っていたテストがCircleCIの自動テストでは通りませんでした。
結論として、ローカル環境とCircleCIの環境の差異が原因かと思います。
ローカルではchromeコンテナを立ち上げて System Spec を通していましたが、 CircleCI の設定ファイル でも設定が必要なのでエラーが起きていました。

今回ローカル環境とCircleCI環境をあわせるために行った変更

  • chromeコンテナ から Dockerfileで chrome を追加するようにしたこと
  • Chrome使用時のURLを指定していたので削除したこと
  • CircleCI の設定ファイルChrome の追加background で使用するようにしたこと

解決策

spec/support/capybara.rb

大幅に変更したように見えますが、url を指定していないというのがポイントです。

変更前
require 'capybara/rspec'
require 'selenium-webdriver'

module CapybaraSupport
  Capybara.javascript_driver = :selenium_chrome_headless
  Capybara.default_driver    = :selenium_chrome_headless
  Capybara.register_driver :selenium_chrome_headless do |app|
    url = 'http://chrome:4444/wd/hub'
    caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
      'goog:chromeOptions' => {
        'args' => [
          'no-sandbox',
          'headless',
          'disable-gpu',
          'window-size=1680,1050'
        ]
      }
    )
    Capybara::Selenium::Driver.new(app, browser: :chrome, url: url, desired_capabilities: caps)
  end
変更後
require 'capybara/rspec'
require 'selenium-webdriver'

Capybara.register_driver :selenium_chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1400,1400')

  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :selenium_chrome_headless

spec/rails_helper.rb

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :selenium_chrome_headless
  end
end

Dockerfile

ローカル環境のテストで Chrome を使用したいので DockerfileChromeの追加 をしています。
この記述を RUN mkdir /myapp の前に書きました。

RUN apt-get update && apt-get install -y unzip && \
    CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
    wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ && \
    unzip ~/chromedriver_linux64.zip -d ~/ && \
    rm ~/chromedriver_linux64.zip && \
    chown root:root ~/chromedriver && \
    chmod 755 ~/chromedriver && \
    mv ~/chromedriver /usr/bin/chromedriver && \
    sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \
    sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \
    apt-get update && apt-get install -y google-chrome-stable

# ルート直下にmyappという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ)
RUN mkdir /myapp
WORKDIR /myapp

.circleci/config.yml

CircleCIの設定ファイル。Chromeを追加 することで ローカル環境との差異 をなくすようにしました。

    steps:
      - run:
          name: Chrome Driver Install
          command: |
            curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
            echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
            sudo apt-get update && sudo apt-get install -y unzip
            wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/
            unzip ~/chromedriver_linux64.zip -d ~/
            rm ~/chromedriver_linux64.zip
            sudo chown root:root ~/chromedriver
            sudo chmod 755 ~/chromedriver
            sudo mv ~/chromedriver /usr/bin/chromedriver
            sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -'
            sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
            sudo apt-get update && sudo apt-get install -y google-chrome-stable
          background: true

.circleci/config.yml 全体

RSpecを動かすところで no_output_timeout: 15m と記述しています。
こちらはなくともテストには直接関係ないので削除しても大丈夫です。

なにも設定しなければ標準で10分の制限時間があり、それを過ぎるとタイムアウトエラーになってしまうので念の為付けております。テストの数とかにもよると思いますが、実際にはほんの数分で終わるので不要です。

version: 2

jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.6-node-browsers
        environment:
          - BUNDLER_VERSION: 2.0.2
          - RAILS_ENV: 'test'
      - image: circleci/mysql:8.0
        command: [--default-authentication-plugin=mysql_native_password]
        environment:
          - MYSQL_USER: root
          - MYSQL_DB: ci_test
          - MYSQL_ROOT_HOST: "127.0.0.1"

    working_directory: ~/myapp

    steps:
      - run:
          name: Chrome Driver Install
          command: |
            curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
            echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
            sudo apt-get update && sudo apt-get install -y unzip
            wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/
            unzip ~/chromedriver_linux64.zip -d ~/
            rm ~/chromedriver_linux64.zip
            sudo chown root:root ~/chromedriver
            sudo chmod 755 ~/chromedriver
            sudo mv ~/chromedriver /usr/bin/chromedriver
            sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -'
            sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
            sudo apt-get update && sudo apt-get install -y google-chrome-stable
          background: true

      - checkout

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            gem install bundler -v 2.0.2
            bundle install --jobs=4 --retry=3 --path vendor/bundle

      - save_cache:
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - ./vendor/bundle

      - run: mv config/database.yml.ci config/database.yml
      - run: yarn install
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load

      - run:
          name: run tests
          command: |
            mkdir /tmp/test-results
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES
          no_output_timeout: 15m

      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

config/database.yml.ci

test:
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: 'root'
  port: 3306
  host: '127.0.0.1'
  database: ci_test

まとめ

  • DockerfileCircleCIの設定ファイルChromeを追加
  • ローカルで通用してもCircleCI上で失敗することがある。
  • ありがたいことに記事(情報)がたくさんあるので、その中で自分がどの問題に直面しているのかを理解することが大事。

おわりに

前回の記事に変更前の CircleCIの設定ファイル があります。(厳密に言えば少しリファクタなどしています)
JavaScript適用前 ですが、 CircleCI についてまとめていますのでよろしければご覧ください。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Dockerfile】tzdataの設定について

目的

Docker上のubuntuにjupyterlabをインストールするため、docker imageを作成しようとした。

詰まった問題

Dockerfileからdocker imageを作成するため、下記のファイル(dockerfile)をコマンドで実行しようとする…

dockerfile
FROM ubuntu

RUN apt-get update
RUN apt-get install -y sudo
RUN sudo apt install -y python3-pip
RUN sudo apt install -y language-pack-ja
RUN sudo update-locale LANG=ja_JP.UTF-8
RUN sudo apt install -y nodejs npm
RUN pip3 install jupyterlab
RUN pip3 install pandas
RUN pip3 install matplotlib
RUN pip3 install sklearn

コマンドは以下の通り。

docker build -t jupyterlab:latest ./

しかし、実行途中に以下のように表示されてしまう

Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.

  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
  2. America     5. Arctic     8. Europe    11. SystemV
  3. Antarctica  6. Asia       9. Indian    12. US
Geographic area:

このとき、6と入力しEnterを押すも反応せず…
どうやらタイムゾーンを選択すると解決するようだ。

解決法

上記のdockerfileにタイムゾーンを設定する文を追加することにより解決した。(追加した文)

FROM ubuntu

RUN apt-get update
RUN apt-get install -y sudo
RUN sudo apt install -y python3-pip
RUN sudo apt install -y language-pack-ja
RUN sudo update-locale LANG=ja_JP.UTF-8
#追加した文↓
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Moscow
RUN apt-get install -y tzdata

RUN sudo apt install -y nodejs npm
RUN pip3 install jupyterlab
RUN pip3 install pandas
RUN pip3 install matplotlib
RUN pip3 install sklearn
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

テーブルが存在するのに、Table doesn't existと言われた話

はじめに

先日、PCの電源を閉じた後、再度dockerを起動し、docker-compose run wen rails sと入力すると、以下のようなエラーが出てしまいました。

Mysql2::Error: Table 'share_read_development.books' doesn't exist

現在でも、主原因は解明できておりません。
本記事では、僕が解決に向けて試したことを記載していきます。

エラーが起きた主原因は不明でしたが、エラーの解決は済んでおり開発自体は進んでおります。
もし同じようなエラーに苦しんでいる方は、参考にしてみてください。

また原因がわかる方がいらっしゃいましたら、コメントで教えていただけると幸いです。

開発環境

Ruby 2.72
Rails 6.0.2.3
MySQL 5.7
Docker/docker-compose

発生したエラー

冒頭でも簡単に記載しましたが、以下のようなエラーが出ました。
booksテーブルがないと言われています。

rails aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'share_read_development.books' doesn't exist
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:201:in `block (2 levels) in execute'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'

# 中略

Caused by:
Mysql2::Error: Table 'share_read_development.books' doesn't exist
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt'
/usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query'

# 中略

/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:schema:dump
(See full trace by running task with --trace)

試したこと

マイグレーションの実行状況の確認
まず、マイグレーションの実行状況を確認しました。

$ docker-compose run web rails db:migrate:status

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201207135139  Create users
   up     20201213135207  Create reviews
   up     20201218052640  Create books
   up     20201218075413  Add bookgenreid to books
   up     20201220063200  Add book to reviews
   up     20201222080803  Create relationships
   up     20201222131717  Create favorites
   up     20201222233733  Create comments
   up     20201224140712  Create bookcases
   up     20201225105949  Create notifications
   up     20201226102230  Add status to review
   up     20201230042031  Add caption to books

全てのマイグレーションファイルが実行されていることがわかりました。

データベースの確認
次にmysqlに接続し、デーベースのテーブルを確認しました。

$ docker-compose run web rails db
> show tables;

そうすると、以下のように表示されました。
booksテーブルは存在している?

+----------------------------------+
| Tables_in_share_read_development |
+----------------------------------+
| ar_internal_metadata             |
| bookcases                        |
| books                            |
| comments                         |
| favorites                        |
| notifications                    |
| relationships                    |
| reviews                          |
| schema_migrations                |
| users                            |
+----------------------------------+

しかし、以下のコマンドでは、booksテーブルがないと言われてしまいます。

> select * from books;

他のテーブルのデータは取得できます。

> select * from bookcases;
+----+------+---------------+---------+----------------------------+----------------------------+
| id | read | book_id       | user_id | created_at                 | updated_at                 |
+----+------+---------------+---------+----------------------------+----------------------------+
|  1 |    0 | 9784296108008 |       1 | 2020-12-28 01:18:40.540283 | 2020-12-28 01:18:40.540283 |
|  3 |    0 | 9784478820094 |       3 | 2020-12-28 12:39:00.697316 | 2020-12-28 12:39:00.697316 |
| 37 |    0 | 9784478820094 |       1 | 2020-12-29 08:16:25.944979 | 2020-12-29 08:16:25.944979 |
| 39 |    0 | 9784804614151 |       1 | 2020-12-29 08:26:56.615557 | 2020-12-29 08:26:56.615557 |
| 41 |    0 | 9784907095536 |       1 | 2020-12-29 08:27:01.301378 | 2020-12-29 08:27:01.301378 |
| 42 |    0 | 9784908925658 |       1 | 2020-12-29 08:39:11.191829 | 2020-12-29 08:39:11.191829 |
| 45 |    0 | 9784284204705 |       1 | 2020-12-30 04:10:08.090943 | 2020-12-30 04:10:08.090943 |
+----+------+---------------+---------+----------------------------+----------------------------+

公式ドキュメントを調べても、自身で試したことしか記載していませんでした。

エラー Table 'xxx' doesn't exist または Can't find file: 'xxx' (errno: 2) が発生する場合、xxx という名前のカレントデータベースにテーブルがないことを示しています。
SHOW TABLES を使用して、カレントデータベースにあるテーブルを確認できます。

【URL】
http://download.nust.na/pub6/mysql/doc/refman/4.1/ja/cannot-find-table.html

データベースの作り直し
あまり気が進みませんでしたが、データベースを作り直すことにしました。

$ docker-compose run web rails db:reset
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

これでエラーが解消することができました!
個人開発なので、データベースを削除するという方法で済みましたが、実際の現場ではこの方法は推奨されないと思います。
もし、今回のエラーの原因等がわかる方がいらっしゃいましたらコメントにて教えていただけると幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【図解付き】開発用オレオレ認証局SSL通信(+dockerコンテナ対応) : 2021

はじめに

オレオレ証明書使ってますか?無料でssl通信ができて便利ですよね。

ssl-1.png

便利にオレオレしてたのですが、開発用 vm 内に docker コンテナを2つ起動してコンテナ間で https 通信させようとしたら 「怪しい証明局が署名した証明書やろ」 って怒られたので対処方法を記載しておきます。

error.log
# 怪しい証明局が署名したやろエラー
x509: certificate signed by unknown authority

怪しくないオレオレ証明書発行

手順は以下となります。
- オレオレ証明局を作成
- 作成した「オレオレ証明局」を開発用 vm に「信頼できる証明局」として登録
- 「オレオレ証明局」が署名した「オレオレ証明書」を発行

若干めんどくさそうに見えますが、mkcert を利用すると非常に簡単です。
mkcert

ssl-2.png

mkcert インストール

install.sh
# https://github.com/FiloSottile/mkcert/releases より最新版をダウンロードして実行権限追加
# ubntu の場合
wget https://github.com/FiloSottile/mkcert/releases/mkcert-v1.4.3-darwin-amd64
mv mkcert-v1.4.3-darwin-amd64 mkcert
chmod +x mkcert

オレオレ証明局を作成 + 「信頼できる証明局」として登録

mkcert -install

「オレオレ証明局」が署名した「オレオレ証明書」を発行

mkcert -key-file key.pem -cert-file cert.pem {domain}

コンテナ起動時に自己証明局をマウント

この状態で dockerコンテナ間で https 通信を行うと、オレオレ証明局が「信頼できる証明局」として認識されていない状態になり、「怪しい証明局が署名した証明書やろ」 エラーとなります。

これを回避するために、VM の「信頼できる認証局」をコンテナにマウントします。

ssl-3.png

本番環境ではSSL証明書発行業者によって署名されたSSL証明書を利用するため、この処理は不要となります。
通常のdocker-compose.yaml ではなく、docker-compose.override.yaml に記載しておき、本番環境には docker-compose.override.yaml をコピーしない様にします。

{docker-compose folder}/
 │ docker-compose.yaml
 └ docker-compose.override.yaml # 追加
docker-compose.override.yaml
  # mount 設定を追加
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
docker-run.sh
docker run .... -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt

おわりに

昔は大変面倒だったことが、簡単にできるようになってきました。
プロジェクトのスリム化が進むと共にフロントエンジニアやインフラエンジニアの境界が曖昧になってきていますので、なるべく簡単に色々な作業をこなせるようにしてより多くの要件を満たせるようにしたいものです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【図解付き】開発用オレオレSSL通信(+dockerコンテナ対応)

はじめに

オレオレ証明書使ってますか?無料でssl通信ができて便利ですよね。

ssl-1.png

便利にオレオレしてたのですが、開発用 vm 内に docker コンテナを2つ起動してコンテナ間で https 通信させようとしたら 「怪しい証明局が署名した証明書やろ」 って怒られたので対処方法を記載しておきます。

error.log
# 怪しいやつが発行したやろエラー
x509: certificate signed by unknown authority

怪しくないオレオレ証明書発行

手順は以下となります。
- オレオレ証明局を作成
- 作成した「オレオレ証明局」を開発用 vm に「信頼できる証明局」として登録
- 「オレオレ証明局」が署名した「オレオレ証明書」を発行

若干めんどくさそうに見えますが、mkcert を利用すると非常に簡単です。
mkcert

ssl-2.png

mkcert インストール

install.sh
# https://github.com/FiloSottile/mkcert/releases より最新版をダウンロードして実行権限追加
# ubntu の場合
wget https://github.com/FiloSottile/mkcert/releases/mkcert-v1.4.3-darwin-amd64
mv mkcert-v1.4.3-darwin-amd64 mkcert
chmod +x mkcert

オレオレ証明局を作成 + 「信頼できる証明局」として登録

mkcert -install

「オレオレ証明局」が署名した「オレオレ証明書」を発行

mkcert -key-file key.pem -cert-file cert.pem {domain}

コンテナ起動時に自己証明局をマウント

この状態で dockerコンテナ間で https 通信を行うと、オレオレ証明局が「信頼できる証明局」として認識されていない状態になり、「怪しい証明局が署名した証明書やろ」 エラーとなります。

これを回避するために、VM の「信頼できる認証局」をコンテナにマウントします。

ssl-3.png

本番環境ではSSL証明書発行業者によって署名されたSSL証明書を利用するため、この処理は不要となります。
通常のdocker-compose.yaml ではなく、docker-compose.override.yaml に記載しておき、本番環境には docker-compose.override.yaml をコピーしない様にします。

docker-compose.override.yaml
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
docker-run.sh
docker run .... -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt

おわりに

昔は大変面倒だったことが、簡単にできるようになってきました。
プロジェクトのスリム化が進むと共にフロントエンジニアやインフラエンジニアの境界が曖昧になってきていますので、なるべく簡単に色々な作業をこなせるようにしてより多くの要件を満たせるようにしたいものです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【図解付き】開発用オレオレSSL通信(+dockerコンテナ対応) : 2021

はじめに

オレオレ証明書使ってますか?無料でssl通信ができて便利ですよね。

ssl-1.png

便利にオレオレしてたのですが、開発用 vm 内に docker コンテナを2つ起動してコンテナ間で https 通信させようとしたら 「怪しい証明局が署名した証明書やろ」 って怒られたので対処方法を記載しておきます。

error.log
# 怪しい証明局が署名したやろエラー
x509: certificate signed by unknown authority

怪しくないオレオレ証明書発行

手順は以下となります。
- オレオレ証明局を作成
- 作成した「オレオレ証明局」を開発用 vm に「信頼できる証明局」として登録
- 「オレオレ証明局」が署名した「オレオレ証明書」を発行

若干めんどくさそうに見えますが、mkcert を利用すると非常に簡単です。
mkcert

ssl-2.png

mkcert インストール

install.sh
# https://github.com/FiloSottile/mkcert/releases より最新版をダウンロードして実行権限追加
# ubntu の場合
wget https://github.com/FiloSottile/mkcert/releases/mkcert-v1.4.3-darwin-amd64
mv mkcert-v1.4.3-darwin-amd64 mkcert
chmod +x mkcert

オレオレ証明局を作成 + 「信頼できる証明局」として登録

mkcert -install

「オレオレ証明局」が署名した「オレオレ証明書」を発行

mkcert -key-file key.pem -cert-file cert.pem {domain}

コンテナ起動時に自己証明局をマウント

この状態で dockerコンテナ間で https 通信を行うと、オレオレ証明局が「信頼できる証明局」として認識されていない状態になり、「怪しい証明局が署名した証明書やろ」 エラーとなります。

これを回避するために、VM の「信頼できる認証局」をコンテナにマウントします。

ssl-3.png

本番環境ではSSL証明書発行業者によって署名されたSSL証明書を利用するため、この処理は不要となります。
通常のdocker-compose.yaml ではなく、docker-compose.override.yaml に記載しておき、本番環境には docker-compose.override.yaml をコピーしない様にします。

{docker-compose folder}/
 │ docker-compose.yaml
 └ docker-compose.override.yaml # 追加
docker-compose.override.yaml
  # mount 設定を追加
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
docker-run.sh
docker run .... -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt

おわりに

昔は大変面倒だったことが、簡単にできるようになってきました。
プロジェクトのスリム化が進むと共にフロントエンジニアやインフラエンジニアの境界が曖昧になってきていますので、なるべく簡単に色々な作業をこなせるようにしてより多くの要件を満たせるようにしたいものです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Raspberry Pi 3のDockerにカンバンを入れる

はじめに

本当は、業務でカンバンを使いたい。
ただ、出向している身だし、何かやろうとすること自体がNGっぽいので、いつか使う時のために自分でまず試してみようと思います。

最初はwekanを利用しようと考えて試してみたのですが、Raspberry Pi 3にmongoがpullできず、代わりにbitnami/mongodbをpullしてみましたが、wekanがうまく立ち上がりませんでした。

  • mongoがpullできない
$ docker pull mongo
Using default tag: latest
latest: Pulling from library/mongo
no matching manifest for linux/arm/v7 in the manifest list entries
  • STATUSがRestartのまま
$ docker ps -a
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS                          PORTS                    NAMES
e72db467f990   mquandalle/wekan         "node /build/main.js"    27 seconds ago   Restarting (1) 1 second ago                              wekan
e9671f4502be   bitnami/mongodb:latest   "/opt/bitnami/script…"   19 minutes ago   Restarting (1) 21 seconds ago                            wekandb
  • うまくいかなかったdocker-compose.yml
docker-compose.yml
version: '2'
services:
  wekan:
    container_name: wekan
    image: mquandalle/wekan
    restart: always
    ports:
      - 8080:8080
    environment:
      - MONGO_URL=mongodb://wekandb/wekan
      - ROOT_URL=http://111.111.111.111:8080
    links: 
      - wekandb

  wekandb:
    container_name: wekandb
    image: bitnami/mongodb:latest
    volumes:
      - /home/johndoe/wekan/data:/data/db
    restart: always

Kanboardを入れてみる

参考にした資料は以下の通りです。
公式ドキュメントもあります。

作成したdocker-compose.ymlはこちら。
hypriot/rpi-mysqlを使用している経緯は、Raspberry Pi 3のDockerでRedmineを立ち上げましたを参照してください。

docker-compose.yml
version: '2'
services:
  kanboard:
    container_name: kanboard
    image: kanboard/kanboard:latest
    restart: always
    ports:
      - 10080:80
      - 10443:443
    volumes:
      - kanboard_data:/var/www/app/data
      - kanboard_plugins:/var/www/app/plugins
      - kanboard_ssl:/etc/nginx/ssl
    environment:
      KANBOARD_DB_MYSQL: kanboard-db
      KANBOARD_DB_PASSWORD: kanboard
  kanboard-db:
    container_name: kanboard-db
    image: hypriot/rpi-mysql:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: kanboard
      MYSQL_DATABASE: kanboard
volumes:
  kanboard_data:
    driver: local
  kanboard_plugins:
    driver: local
  kanboard_ssl:
    driver: local

問題なく、docker-composeがうまくいきました。

$ docker-compose up -d
Creating network "docker-kanboard_default" with the default driver
Creating volume "docker-kanboard_kanboard_data" with local driver
Creating volume "docker-kanboard_kanboard_plugins" with local driver
Creating volume "docker-kanboard_kanboard_ssl" with local driver
Creating kanboard    ... done
Creating kanboard-db ... done

http://hogehoge:10080/ で開きます。(hogehogeの部分にIPアドレスか、ホスト名を入れる)
デフォルトはadmin/adminで開きます。

20210116_IMG_1533.jpg

まとめ

今回はあまり躓くこともなく、すんなりといきました。
カンバンの有効的な使い方を学びます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker × Laravel ローカル環境でHTTPS(SSL)通信する

ローカル環境でもHTTPS通信したいという要望があり、ちょうど最近仕事でやる機会があったのでQiitaにもまとめたいと思います。

Laravel環境構築

$ git clone git@github.com:ucan-lab/docker-laravel.git
$ cd docker-laravel
$ make create-project

http://localhost

ScreenShot 2021-01-16 15.24.23.png

認証局、鍵の準備

mkcert, nssのインストール

$ brew install mkcert nss

ローカル認証局(CA: Certification Authority)の作成

$ mkcert -install

ChromeのSSL警告をlocalhostの時だけ表示しないようにする。
chrome://flags/#allow-insecure-localhost アドレスバーに入力する。

ScreenShot 2021-01-16 14.56.07.png

DISABLED => ENABLED に変更してブラウザを再起動する。

秘密鍵、公開鍵の作成

コマンドの実行は docker-laravel ディレクトリルートで行ってください。

$ mkcert -cert-file ./infra/docker/nginx/localhost.pem -key-file ./infra/docker/nginx/localhost-key.pem localhost

Dockerのコード書き換え

docker-compose.yml

公開ポートを80から443へ変更する。
HTTPSは、ウェルノウンポート番号として443が使われるのが一般的です。

docker-compose.yml
services:
  web:
    ports:
      - ${WEB_PORT:-443}:443

infra/docker/nginx/default.conf

下記のコードを追記する。

infra/docker/nginx/default.conf
server {
    # listen 80;
    listen 443 ssl;
    server_name localhost;
    ssl_certificate /etc/nginx/conf.d/localhost.pem;
    ssl_certificate_key /etc/nginx/conf.d/localhost-key.pem;

    # ... 省略
}

infra/docker/nginx/Dockerfile

下記のコードを追記する。

infra/docker/nginx/Dockerfile
COPY ./*.pem /etc/nginx/conf.d/
  • 秘密鍵、公開鍵をコピーしてます。

Dockerイメージの作成、コンテナ再生成

コマンドの実行は docker-laravel ディレクトリルートで行ってください。

$ docker-compose build web
$ make restart

https://localhost

ScreenShot 2021-01-16 14.54.27.png

ScreenShot 2021-01-16 14.54.39.png

このようにSSL証明書が有効化されていればokです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker 復習 イメージ作成~コンテナ起動

初めに

最近 python や Vue.js の勉強ばかりで EC2 や docker を使っていなかったのでイメージ作成からコンテナ起動までの復習をしてみた。

EC2インスタンス起動

イメージは Amazon Linux2 を使用。

image.png

image.png

docker コマンドをインストール

公式ドキュメントをそのままコピペしてインストール。

$ sudo yum update -y
$ sudo amazon-linux-extras install docker
$ sudo service docker start
$ sudo usermod -a -G docker ec2-user

ビルド~コンテナ起動

EC2インスタンスログイン後、~/my_dir で Dockerfile まで作成。

$ mkdir my_dir
$ cd my_dir
$ vi enigma.py
$ vi test.sh
$ vi Dockerfile
  • enigma.py

image.png

  • test.sh

image.png

  • Dockerfile

image.png

ビルドする。

$ docker build -t original_image .

image.png

マウント用に ディレクトリ mnt_dir を作成し、ファイルを移動する。

mkdir mnt_dir
$ ls
Dockerfile  enigma.py  mnt_dir  test.sh
$ mv `ls | grep -v 'Docker' | grep -v 'mnt'` ./mnt_dir/
$ ls ./mnt_dir/
enigma.py  test.sh

docker 起動。

$ docker run -it -v `pwd`/mnt_dir:/mnt original_image /bin/bash

マウントできていることを確認。

root@67ac0dab37f2:/# ls /mnt/
enigma.py  test.sh

python ファイル実行。

root@67ac0dab37f2:/# python3 /mnt/enigma.py | tee /mnt/output.txt
FRZXI JFDRX. XV SYXU LV BZEXX. SJXO AG NLDE KEN.
HELLO WORLD. MY NAME IS ALICE. NICE TO MEET YOU.
root@67ac0dab37f2:/# cat /mnt/output.txt
FRZXI JFDRX. XV SYXU LV BZEXX. SJXO AG NLDE KEN.
HELLO WORLD. MY NAME IS ALICE. NICE TO MEET YOU.

Ctrl + P + Q で起動した状態を保ちつつコンテナを抜ける。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
67ac0dab37f2        original_image      "/bin/bash"         3 minutes ago       Up 3 minutes                            recursing_wozniak

python 実行も問題なし。

$ cat ./mnt_dir/output.txt
FRZXI JFDRX. XV SYXU LV BZEXX. SJXO AG NLDE KEN.
HELLO WORLD. MY NAME IS ALICE. NICE TO MEET YOU.

コンテナ実行時にシェル実行

Dockerfile に CMD を追加する。

$ vi ./mnt_dir/test.sh 
$ vi Dockerfile

image.png

image.png

ビルド再実行。その後、何回かコンテナを起動してみる。

$ docker build -t original_image .
$ docker run -v `pwd`/mnt_dir:/mnt original_image
$ docker run -v `pwd`/mnt_dir:/mnt original_image
$ docker run -v `pwd`/mnt_dir:/mnt original_image
$ docker run -v `pwd`/mnt_dir:/mnt original_image

シェルが実行されていることを確認。

$ ls ./mnt_dir/
enigma.py                       mnt_file_20210116-05:25:01.txt  mnt_file_20210116-05:29:38.txt  test.sh
mnt_file_20210116-05:24:47.txt  mnt_file_20210116-05:25:47.txt  output.txt
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECS Fargateを起動時に「CannotPullContainerError」が出てしまう場合の対処法

FargateのタスクでDockerHubからイメージを取得したいときに起きたエラーです。
原因や対処法を紹介していきます。

「CannotPullContainerError」の原因

主な原因としては、サブネット上から外部ネットワークへの通信ができずに、imageのpullに失敗しているからです。

Fargate起動時の「CannotPullContainerError」への対処法

Fargate起動時の「CannotPullContainerError」への対処法を紹介していきます。

1.Fargateに設定されたサブネットが外部と通信できるようになっていない

Fargateに設定されたサブネットから外部への通信ができないと「CannotPullContainerError」のエラーになってしまいます。

サブネットに関連付けられているルートテーブルからインターネットゲートウェイまたはNATゲートウェイへの通信が許可されていないといけません。

更にそれらのインターネットゲートウェイまたはNATゲートウェイを通して、外部への通信を許可できる設定になっていないと上記のエラーが起きてしまいます。

インターネットゲートウェイの場合の設定

インターネットゲートウェイの場合は以下のように設定することで外部との通信ができるような設定にできます。
image.png

2.ネットワークACLのアウトバウンドが許可になっていない

ネットワークACLはデフォルトでは以下のように外部との接続は許可されていますが、設定で通信を許可されていない場合は外部との通信ができません。

上手く行かない場合は以下のように一度すべての通信を許可して試してみてください。

image.png

まとめ

「CannotPullContainerError」は外部との通信ができずに起きるエラーでした。AWSは正しく設定できていないと外部との通信ができないので気をつけましょう。

おかしなところや分からない所があったら指摘頂けると助かります。

参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-pull-container-error/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.jsでhelloworld

ゴール

Node.jsを使用して、コンソールにhelloworldを表示させる

前提

Visual Studio Code(以下 VSCode)使用
DockerでNode.jsのコンテナを使用

Node.jsとは

  • 本来クライアント側の言語であるjavascriptを、サーバー側でも使えるようにした仕組み(※1)
  • webサイトやwebアプリ、スマートフォンサイト、ゲームなど様々なものをつくることができる =>paypalやuverなどもNode.jsでつくられているそう!
  • 大量のデータ処理が得意で、処理スピードも早いのが特徴

※1 progate「Node.jsとは」より引用 https://prog-8.com/nodejs/study/1/1#/2
参考:https://udemy.benesse.co.jp/development/system/node-js.html

DockerにNode.jsをダウンロードする

VScodeの拡張機能のDockerをあらかじめインストールしておく。(※2)

docker-compose.ymlファイルの作成

Nodejs-sample-app(任意のフォルダ名でよい)フォルダを作成。
その下にdocker-compose.ymlファイルを作成。
こちらはdockerにコンテナをダウンロードする時のお決まりのファイルとなるので、ファイル名は固定。ymlファイルは、YAMLという書き方に沿って記載されたテキストファイルで、データの受け渡しなどに使用される。
今回は以下のように記載した。

docker-compose.yml
version: "3"
services:
    node:
        image: node:14.15
        volumes:
            - .:/project
        tty: true
        working_dir: /project
        command: bash

それぞれの項目の意味

※2 詳しくはこちらのページがおすすめです
@Teach 「VSCodeでDocker入門」 https://qiita.com/Teach/items/ca09b8882f519dca600c

docekerにイメージをダウンロード

VSCodeのターミナル機能を使い、Nodejs-sample-appフォルダの中に入り、以下のコマンドを打つと、docerにNode.jsがダウンロードされる。

docker-compose up -d

イメージ
スクリーンショット_2021-01-16_10_53_46.jpg

dockerを開いて、このような表示になった成功です!
 スクリーンショット_2021-01-16_10_54_20.jpg

コンテナの中に入るためにはAttach shellを選択します(写真参照)
スクリーンショット_2021-01-16_12_33_56.jpg

ローカル内のターミナルとコンテナ内のターミナルはこちらで切り替えができます
スクリーンショット_2021-01-16_12_38_45.jpg

app.jsファイルの作成

docker-compose.ymlと同階層にapp.jsファイルを作成。
今回は以下のように記載

app.js
console.log("Hello nodejs");

コンテナ内のターミナルで
$ node app.js
とコマンドを打ち、以下のように表示されたら、Node.jsの環境構築は完了です!

スクリーンショット_2021-01-16_12_47_28.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker ComposeでRails環境を構築

初学者の方向けに発信されているきよとのプログラミング大学のチャンネルで、Docker Composeを使ったRails環境構築の動画を見つけ、これが非常に分かりやすかったので、備忘録として記事にまとめたいと思います。

DockerでRails環境をつくりたいという方はこの動画を見ればOKだと思います。
https://youtu.be/ltDdZAJli8c

Docker Composeとは

複数のアプリケーションをまとめて操作できるツール。例えばRailsでアプリケーションを開発する際、最低限Webサーバーとデータベースサーバーが必要になるが、通常それぞれのサーバーを構築し、接続するなどの操作が必要となる。docker-composeではコマンド一発でそれらを立ち上げて接続することができるため、非常に楽に開発環境を構築することができる。

全体の流れ

  • Docker関連のファイルを用意
  • 初期設定
  • 起動
  • よく使うコマンド

Docker関連のファイルを用意

① Dockerfile

ここにrailsのイメージを作成する記述を行う。

Dockerfile
# ベースイメージを指定
FROM ruby:2.7

# nodejsとyarnをインストールするため、JavaScript関連のライブラリをインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  # nodejsとyarnをインストール
  && apt-get update -qq \
  && apt-get install -y nodejs yarn
# 作業ディレクトリを指定
WORKDIR /app
COPY ./src /app
# Ruby関連のライブラリ(gem)のインストール
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

※ APIモードで開発をする場合、nodejsとyarnは不要

② Gemfile

次にGemfileを用意します。

Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 6.1.0'

上記のように、railsのライブラリが入った状態でrails newを実行すると、railsのファイルの雛形を一斉に作ることができる。その際、Gemfileが新しく作成され、それと置き換わる形となる。

③ docker-compose.yml

最後にdocker-compose.ymlを用意します。

docker-compose.yml
ersion: '3'
services:
  db:
    image: mysql:8.0
    # mysql8.0から認証形式が変更になっていて、それを5系の認証形式に戻す設定。これをしないとエラーになる
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql-data:/var/lib/mysql
    # 環境変数の設定
    # MySQLはパスワードを設定しないとエラーになる
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    # 標準入出力を有効にする設定
    # これをしないとデバックができない
    tty: true
    stdin_open: true
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./src:/app
      # gemを入れた際に、buildし直さなくても良くする設定
      - bundle:/usr/local/bundle
    ports:
      - "3000:3000"
    # railsからMySQLへ接続する際、接続情報としてdbサービスのIPアドレスを指定する必要がある。その接続先のIPアドレスをdbで接続できるようにする設定
    depends_on:
      - db
volumes:
  bundle:
    driver: local

開発をしていると、A server is already running. Check /app/tmp/pids/server.pid.のエラーでハマることがある。これは、サーバーが実行中か否かをserver.pidの有無で判断しており、何らかの理由でサーバーが実行していないがserver.pidファイルが残った状態となったときに起こる。これを防ぐため、起動時にはserver.pidの削除を行う。

command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

初期設定

ファイルが用意できたらrails newコマンドを実行する。

$ docker-compose run web rails new . --force --database=mysql

Gemfileが変更されたため、イメージの再ビルド

$ docker-compose build

config/database.ymlを参照し、データベースへの接続先情報を修正する。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  # docker-compose.ymlで設定したパスワードを入力
  password: password
  # docker-compose.ymlのdepends_onで設定した値を入力
  host: db
  # 以下略

起動

$ docker-compose run --rm web rails db:create
$ docker-compose up -d

ブラウザでlocalhost:3000へアクセスし、下画面が表示されれば成功!
image.png

よく使うコマンド

  • イメージのビルド
$ docker-compose build
  • コンテナの作成と起動
$ docker-compose up -d
  • コンテナを停止、削除
$ docker-compose down
  • コンテナの一覧を表示
$ docker-compose ps
  • ログを表示
docker-compose logs
  • コンテナを作成してコマンドを実行
$ docker-compose run <サービス> <コマンド>
  • 起動中のコンテナにコマンド実行
$ docker-compose exec <サービス> <コマンド>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

超簡単!サクッとDockerにPython + Flask環境

週末ハッカソン
WEBサイトを作ろうと思いDockerにPython + Flask環境を構築した

ダウンロード・インストール
Get Docker for Macからダウンロード
https://docs.docker.com/docker-for-mac/install/
ダウンロードしたDocker.dmgを展開してインストール完了
インストール後にチュートリアル開始
NEXT STEP を押していき動作確認

Python + Flask環境

Dockerfile

FROM python:3.7.4

WORKDIR /app
ADD . /app

RUN apt-get update && apt-get clean;

RUN pip install -r requirements.txt

ENV TZ = "Asia/Tokyo"
ENV FLASK_APP /app/app.py
ENV PYTHONPATH $PYTHONPATH:/app

ENV PORT 8080
EXPOSE 8080

CMD ["python", "app.py"]

サンプル用アプリ

コードの中身が知りたい方はDocumentを参照してください。

weekend-hackathon/  
|-- app  
|   |-- views  
|   |    `-- sample.py  
|   `-- __init__.py  
|-- app.py  
|-- Dockerfile  
`-- requirements.txt  

weekend-hackathon/requirements.txt

Flask==1.1.2

weekend-hackathon/app/views/sample.py

from flask import Blueprint

sample = Blueprint("sample", __name__)


@sample.route("/")
def index():
    print("sample.index")
    return "sample.index"

weekend-hackathon/app/__init__.py

from flask import Flask
from app.views.sample import sample


def get_app():
    app = Flask(__name__)
    _register_blueprint(app)
    return app


def _register_blueprint(app):
    app.register_blueprint(sample)

weekend-hackathon/app.py

import app

app = app.get_app()

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080, debug=True)

Docker ビルド

$ docker build -t weekend-hackathon .

Flask起動

$ docker run --name weekend-hackathon -p 8080:8080 -v ~/Sites/weekend-hackathon/:/app -it --rm weekend-hackathon

http://localhost:8080/にアクセス

sample.index が表示される。

参考コマンド

  1. イメージ確認 : docker images
  2. コンテナ確認 : docker ps
  3. コンテナ確認(停止) : docker ps -a
  4. コンテナ起動 : docker start xxxxx
  5. コンテナ接続 : docker exec -it xxxxx /bin/bash
  6. コンテナ停止 : docker stop xxxxx
  7. コンテナ削除 : docker rm xxxxx
  8. イメージ削除 : docker rmi xxxxx
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

リモート先の Mac で Docker login できない(Error saving credentials)

リモート先(ssh 接続先)の macOS で docker login するとエラーが出ます。

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: keinos
Password: 
Error saving credentials: error storing credentials - err: exit status 1, out: `error storing credentials - err: exit status 1, out: `User interaction is not allowed.``

「mac docker login できない」でググってもドンピシャの記事が出てこなかったので、自分のググラビリティとして。

TS; DR

「キーチェーンアクセス」にロック(アクセス制限)がかかってます。

画面共有でリモート先を確認するか、以下のコマンドでロックを解除します。

キーチェーンアクセスの解除コマンド(要パスワード)
security unlock-keychain

TL; DR

macOS には「キーチェーンアクセス」と呼ばれる、パスワード・公開鍵・秘密鍵などの情報を一元管理する標準アプリがあります。iCloud 同期されるので、同じ Apple ID であれば別の環境でも保存されたパスワードが同期されます。

1password のような便利さがある反面、セキュリティのため色々と動作にシビアな面があります。

そのうちの 1 つに、キーチェーンアクセスの許可が必要な OS やアプリのアップデートが行われるとユーザが承認するまでリモート操作の一部が制限されることがあります。

特に docker login などの、パスワード情報をキーチェーンアクセスに保存して利用するタイプのセキュリティ重視のアプリがリモート先で何かしらのポップアップを表示している場合です。

$ # ロックがかかっているパターン
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: keinos
Password: ******
Error saving credentials: error storing credentials - err: exit status 1, out: `error storing credentials - err: exit status 1, out: `User interaction is not allowed.``

$ # ロック解除
$ security unlock-keychain
password to unlock default: ******

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: keinos
Password: ******
Login Succeeded

私の場合、リモート先の macOS が HighSierra (OSX 10.13.6) であったため、Docker の最新バージョンがあるものの「使えないよ」と叱られていました。このポップアップが表示された状態でも、security unlock-keychain を実行すれば先に進めました。

Docker_OSX_10.13_is_not_supported.png

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSLで良くあるトラブル

1.この記事の内容

WSL(Windows Subsystem for Linux)を使っていて良くあるトラブルとその対処方法を紹介します.
新たなトラブルが生じた際は,随時,追記していきたいと思います.

1-1.使用環境

  • Windows 10
  • Windows Subsystem for Linux 2
    • Ubuntu 18.04.5 LTS

2.良くあるトラブルと対策

2-1.PowerShellからWSLへログインできない/突如WSLが落ちる

PowerShellからWSLを起動後,エラーメッセージ等が表示されることなくログインできなかったり,突如強制ログアウトされたりする現象が生じることがあります.
原因は不明ですが,下記の手順でLxssManagerを起動することで,問題を解消できています.

  1. PowerShellを管理者権限で起動
  2. 下記コマンドを実行して, LxssManagerを起動
    > net start LxssManager
    
    ※LxssManagerが落ちていない場合もあるようで,その場合はLxssManagerをstop後にstartする
    > net stop LxssManager
    > net start LxssManager
    

2-2.WSLからnvidia-dockerが起動できない(GPUに接続できない)

WSLからnvidia-dockerのrunコマンド実行時に下記のようなメッセージが表示され,Dockerコンテナを起動できないことがあります.
※エラーメッセージ全文は控えられず,一部のみです.

docker: Error response from daemon: OCI runtime create failed: container_linux.go ~

WSLからnvidia-dockerでGPU接続する場合には,標準のドライバではなく,CUDA on Windows Subsystem for Linux (WSL) - Public Previewのインストールが必要ですが,ドライバの自動アップデートで,WSL非対応のドライバに更新されてしまう場合があるようです.

CUDA on Windows Subsystem for Linux (WSL) - Public Previewからドライバのダウンロード及びアップデートを行うことで,問題を解消できています.

3.さいごに

DeepLearning環境としてWSLを活用する中で遭遇するトラブルと対策をまとめてきました.
Insider PreviewはWindowsのアップデートが頻繁に生じる為,新たなトラブルも生じる可能性ありますが,これまで活用してきた中では思っていたほどトラブルは少ない印象です.

4.関連リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSLで良くあるトラブルと対処方法

1.この記事の内容

WSL(Windows Subsystem for Linux)を使っていて良くあるトラブルとその対処方法を紹介します.
新たなトラブルが生じた際は,随時,追記していきたいと思います.

1-1.使用環境

  • Windows 10
  • Windows Subsystem for Linux 2
    • Ubuntu 18.04.5 LTS

2.良くあるトラブルと対策

2-1.PowerShellからWSLへログインできない/突如WSLが落ちる

PowerShellからWSLを起動後,エラーメッセージ等が表示されることなくログインできなかったり,突如強制ログアウトされたりする現象が生じることがあります.
原因は不明ですが,下記の手順でLxssManagerを起動することで,問題を解消できています.

  1. PowerShellを管理者権限で起動
  2. 下記コマンドを実行して, LxssManagerを起動
    > net start LxssManager
    
    ※LxssManagerが落ちていない場合もあるようで,その場合はLxssManagerをstop後にstartする
    > net stop LxssManager
    > net start LxssManager
    

2-2.WSLからnvidia-dockerが起動できない(GPUに接続できない)

WSLからnvidia-dockerのrunコマンド実行時に下記のようなメッセージが表示され,Dockerコンテナを起動できないことがあります.
※エラーメッセージ全文は控えられず,一部のみです.

docker: Error response from daemon: OCI runtime create failed: container_linux.go ~

WSLからnvidia-dockerでGPU接続する場合には,標準のドライバではなく,CUDA on Windows Subsystem for Linux (WSL) - Public Previewのインストールが必要ですが,ドライバの自動アップデートで,WSL非対応のドライバに更新されてしまう場合があるようです.

CUDA on Windows Subsystem for Linux (WSL) - Public Previewからドライバのダウンロード及びアップデートを行うことで,問題を解消できています.

3.さいごに

DeepLearning環境としてWSLを活用する中で遭遇するトラブルと対策をまとめてきました.
Insider PreviewはWindowsのアップデートが頻繁に生じる為,新たなトラブルも生じる可能性ありますが,これまで活用してきた中では思っていたほどトラブルは少ない印象です.

4.関連リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerのVolumeを全て削除する

docker volume ls | awk '{print $2}' | xargs docker volume rm
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Edge TPUコンパイラを使用するためのDocker作成

はじめに

Edge TPUはラズパイ以外にもMacやWindowsでも使えますが、コンパイルはDebianベースのLinuxしかでかできないようなので、MacやWindowsでもコンパイルできるようにDockerを用いてコンパイルできるようにしました。

Dockerfileの作成

Dockerfileとして以下を作成

FROM debian:buster-slim

RUN export DEBIAN_FRONTEND=noninteractive \
 && apt-get update \
 && apt-get install --no-install-recommends -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
 && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \
 && echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list \
 && apt-get update \
 && apt-get install edgetpu-compiler \

WORKDIR /home/edgetpu-compiler

ENTRYPOINT ["edgetpu_compiler"]

Docker build

作成したDockerfileを以下のコマンドでビルド

docker image build -t edgetpu-compiler .

量子化モデルの準備

dockerfileと同じディレクトリにディレクトリを作成

mkdir model

modelディレクトリにINT8で量子化済のtfliteを格納。

EdgeTPUコンパイル

以下のコマンドでINT8で量子化済のtfliteモデルをEdegTPU用のモデルにコンパイル

docker run --rm -it -v $(pwd):/home/edgetpu-compiler edgetpu-compiler model/{MODEL}

{MODEL}の部分には先ほど準備したINT8で量子化されたtfliteを指定。{MODEL}_edgetpu.logと{MODEL}_edgetpu.tfliteの様なファイルが作成されていれば、コンパイルが成功していると思います。

最後に

Linux環境がなくても、MacやWindowsでも簡単にEdgeTPU用のモデルにコンパイル、EdgeTPUで推論することができます。

参考

この記事は以下の情報を参考にして執筆しました。
- Dockerコンテナ上でEdge TPUコンパイラを使う

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む