20201009のdockerに関する記事は13件です。

WSL2でDockerを爆速化

ウチのWin10もようやくこの前のWindowsUpdateでWSL2が有効になりました。

早速、公式の手順に従ってDockerをWSL2に対応させて行きましょう
https://docs.docker.com/docker-for-windows/wsl/

その前に、What's WSL2

WSLはWindowsSubsystemForLinuxの略称
WindowsのコマンドラインでLinuxのコマンドが使えるよー的なものだとおもって貰えば良いでしょう。

WSL2はWSLのバージョン2になります。ただし、WSL1の完全上位互換ではなくメリットとデメリットがあります。
https://docs.microsoft.com/ja-jp/windows/wsl/compare-versions

まずは前提確認

  1. Docker、バージョンは2.3.0.2以上
  2. Windows10、バージョン 2004、ビルド 19041 以上

WSL2をインストールする

まずは、MicrosoftストアからUbuntuを入手

WSLにつかうLinuxOSは汎用性を考えてUbuntuにしました。
ファイルサイズが大きいですが、WSL用には一番オススメできるかと思います。
https://www.microsoft.com/ja-jp/p/ubuntu/9nblggh4msv6?activetab=pivot:overviewtab

WSL2にアップデート

そのままだと、WSL1でインストールされるので、WSL2にアップデートしましょう。

# インストールされているWSLとバージョンを確認
wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         1

*がついているのがデフォルトのWSLです。WSLに複数のLinuxを入れているとたくさん出ます。
通常は、デフォルトのWSLがDockerと統合されます。

# WSLをバージョンアップ
wsl --set-version Ubuntu 2

# インストールされているWSLとバージョンを再確認
wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2

UbuntuのVersionが2になっていれば成功です。

早速 Docker For WindowsでWSL2を有効に

  1. Settings > Generalと進んで、Use WSL 2 based engineにチェックしてApply & Restart
    image.png

  2. Settings > Resources > WSL Integration デフォルトのWSLで統合機能が有効になっています。
    image.png

これで、いままでHyper-V上の仮想マシンで動いていたDockerが、WSL2で動くようになりました。

が、落とし穴

WSL2は完全なLinuxになったもののWindowsのファイル共有でパフォーマンスが落ちてしまうデメリットがあります。
そのため、volumesでWindowsのローカルフォルダをコンテナに共有していた場合、体感的にかなり遅くなってしまいました。

Linuxのファイルシステムにソースコードを配置することで解決

wslのWindowsとの共有領域である/mnt/c/配下をvolumesで共有すると遅くなってしまうので、
プログラムのコードはそれ以外の場所に置きましょう。
公式のベストプラクティスにもそう書いてあります。
https://docs.docker.com/docker-for-windows/wsl/#best-practices

WSL2のDockerでVSCodeのDevContainer開発

https://docs.docker.com/docker-for-windows/wsl/#develop-with-docker-and-wsl-2

WSL内でcodeコマンドを実行すれば、WindowsのVSCodeがRemote-WSLモードで開く!!!

code ~/hoge_workspace/

あとは、WSL内のフォルダにdevcontainer.jsonを用意していつもの手順でReopen in Container
image.png
image.png

DevContainer関連

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

CircleCIのシステムスペックをselenium dockerを利用する

今回が初投稿ですので、ミスや分かりにくいなどは多めに見てください

環境

・Ruby 2.7.1
・Rails 6.0.2.1

やりたいこと

・CircleCIでselnium dockerを利用してシステムテストを実行
・system js: trueをCircleCIでも利用できるようにする

docker-compose.yml

システムスペックで利用するseleniumのイメージを取得し、depens_onで連携とportの指定も忘れずに

docker-compose.yml
version: "3"
services:
  web:
    build: .
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
    depends_on:
      - db
      - chrome
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABE: db
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
  chrome:
    image: selenium/standalone-chrome-debug:latest
    ports:
      - "4444:4444"
volumes:
  mysql-data:
    driver: local

database.ymlを修正

このままではデータベースがdbコンテナが利用されないのでdatabase.ymlを修正します。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myappp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
$ docker-compose build
$ docker-compose up
$ docker-compose run web rake db:create

spec/rails_helper

テストに必要なGemを追加

Gemfile
group :test do
  gem 'capybara'
  gem 'selenium-webdriver'
  gem 'rspec-rails'
end

systemテストはselenium dockerを使うようにrails_specを変更する

rails_spec.rb
Capybara.register_driver :remote_chrome 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: :remote, url: url, desired_capabilities: caps)
end

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 :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
end

これでローカルのシステムスペックは問題なく動くはずです

.circleci/config.yml

CircleCIの設定です
- run: mv ./config/database.yml.ci ./config/database.ymlでCI環境ではデータベースの設定を変更しています。
name: chromeと設定しておかないと
Errno::EADDRINUSE:Address already in use - bind(2) for "172.27.0.3" port 4444のエラーが発生する

config.yml
version: 2.1
jobs:
  build:
    docker:
      - image: circleci/ruby:2.7.1-node-browsers
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
      - image: mysql:8.0
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: "true"
          MYSQL_ROOT_HOST: "127.0.0.1"
          MYSQL_DATABE: db
        command: --default-authentication-plugin=mysql_native_password
      - image: selenium/standalone-chrome-debug:latest
        name: chrome
    working_directory: ~/coffee
    steps:
      - checkout
      - run:
          name: bundleをインストール
          command: bundle check || bundle install --jobs=4
      - run:
          name: yarnを追加
          command: yarn install
      - run:
          name: webpackを追加
          command: bundle exec bin/webpack
      - run:
          name: rubocop
          command: bundle exec rubocop
      - run: mv ./config/database.yml.ci ./config/database.yml
      - run:
          name: データベースを作成
          command: bundle exec rails db:create || bundle exec rails db:migrate
      - run:
          name: rspec test
          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
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

これでCircleCIでのrspec systemテストが正常に動くはずです

参考

Rails on DockerでRSpecのSystem testをSelenium Dockerを使ってやってみた。
既存のRails6アプリをDocker化しつつCircleCIでシステムスペックも実行できる環境を作る

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

CircleCIでDocker Hubの制限を回避するための設定

問題

Docker Hubは、無料アカウントと認証なしのpullに11月からpull数に制限がかかります。CircleCI上で認証無しで運用しているとIPアドレスベースの制限がかかり、CircleCIのIPアドレスはユーザーと比較して多くないので影響が懸念されます。

CircleCIチームはDocker社と会話してる模様なので、今後もしかしたらユーザーの対応は不要となるかも知れません。しかしCI/CD環境が止まれば影響は大きいので回避策を押さえておきましょう。

解決策

ひとまずDocker Hubのユーザー認証を噛ませれば、IPアドレスでは判断されなくなるので無料アカウントでも200 pulls/6hまでは利用できます。これ以上になるならDocker Hubへの課金が必要ですが、どのみちCircleCI上でユーザー認証を行う必要があるので同様の作業が発生します。

作業手順

以下の作業でCircleCI上でのDocker Hubのユーザー認証を行います。
config.yamlの全体は↓こちら。

CircleCIのContextにDocker Hubのユーザー名とパスワードを設定

Contextへの登録手順はすぐ出てくるので割愛します。
image.png

Dockerを利用するJobにContextを追加

2020/09/15から複数のContextがサポートされた模様! これは嬉しい。

  staging_steps: &staging_steps
    <<: *only_master
    context:
      - serverless_staging
      - docker-hub-credencials
  production_steps: &production_steps
    <<: *only_master
    context:
      - serverless_production
      - docker-hub-credencials

Dockerを利用している箇所に認証を加える

Docker executorや、Machine executor内でDockerをpullしている箇所に設定した認証情報を加えてゆきます。
以下はDocker executorの例。

参照用の項目を作成

references:
  docker_hub_authentication: &docker_hub_authentication
    auth:
      username: $DOCKERHUB_USER
      password: $DOCKERHUB_PASSWORD

imageをpullしている箇所全てに適用

以下はexecutorsにまとめられている箇所に適用している例。

executors:
  python3_6_1:
    working_directory: ~/repo
    docker:
      - image: circleci/python:3.6.1
        <<: *docker_hub_authentication
  test:
    working_directory: ~/repo
    docker:
      - image: circleci/python:3.6.1
        <<: *docker_hub_authentication
      - image: bluszcz/bflocalstack-dynamodb-s3
        <<: *docker_hub_authentication
      - image: alismedia/dynamodb-local
        <<: *docker_hub_authentication
        environment:
          MAX_HEAP_SIZE: 4096m
          HEAP_NEWSIZE: 3072m
      # Docker Hubではないので認証情報不要
      - image: docker.elastic.co/elasticsearch/elasticsearch:6.2.0
        environment:
          discovery.type: single-node

以上の設定を行って、変更前と同じようにビルドできれば完了です。

エラー

Docker Hubではない箇所に誤って認証情報を追加すると以下のようなエラーが出ます。

Error response from daemon: Get https://docker.elastic.co/v2/elasticsearch/elasticsearch/manifests/6.2.0: unauthorized: authentication required

以下は謎のエラー。今回初めて見たもの。

Allocating a remote Docker Engine
Requesting version: 18.09.3

Got error while creating host: failed to create host: rpc error: code = Unknown desc = failed to create VM: Put "https://vm-service.infra.circleci.com/tasks/5f7ffcbaa7b0aa6a8ec29c79-0-build%2F59C7C9D1": EOF
We had an unexpected error preparing a VM for this build, potentially due to our infrastructure or cloud provider.  Please retry the build in a few minutes

指示通りにRerunしたら解決しました。

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

既存のRails,MySQLアプリの開発環境とテスト環境にDockerを導入する

はじめに

タイトルの通り既存のRails,MySQLアプリの開発環境にDockerを導入します。
またrspecによるテストもDocker内で実行できるようにします。
既に同じような記事がたくさんありますが、結構エラー発生したので自分がうまくいった方法をまとめます。
間違いがあれば教えていただけると幸いです。

環境

  • MacOS
  • Ruby 2.6.5
  • Rails 5.2.3
  • MySQL 5.7

Railsのversionが6,MySQLのversionが8だとこの方法ではうまくいきません。

手順

  1. Dockerfile作成
  2. docker-compose.yml作成
  3. 既存のdatabase.ymlを変更
  4. 起動

1. Dockerfile作成

既存のプロジェクトのディレクトリにDockerfileを新規作成します。

ファイル構成
 test_app#既存プロジェクト
    ├──略
    ├── Dockerfile #作成
    ├── docker-compose.yml #作成
    ├── Gemfile
    ├── Gemfile.lock
    ├── .env #使用
    ├── config
         └──database.yml #変更

中身を記述していきます。
以下test_appは各々のアプリ名に合わせてください。

Dockerfile
FROM ruby:2.6.5

RUN apt-get update \
    && apt-get install -y --no-install-recommends nodejs mariadb-client build-essential \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /test_app

COPY Gemfile /test_app/Gemfile
COPY Gemfile.lock /test_app/Gemfile.lock

RUN gem install bundler
RUN bundle install
COPY . /test_app
  • まずFROMでrubyのimageを取得。versionはご自身の環境に合わせます。
  • 次に必要なパッケージをinstallしています。mariadb-clientmysql-clientの記事もありますがエラーになったので注意。mysql-clientはmariadb-clientに統合されたようです。
  • 次は作業ディレクトリを指定。RUN mdirはなくてもWORKDIRで作成されるそうです。
  • 以下はgemfile等をローカルからコンテナ上にコピーしています。COPYADDとされている記事もありますがCOPY推奨らしいです。

2.docker-compose.yml作成

docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    ports: 
      - '3306:3306'
    environment:
      MYSQL_DATABASE: test_app_development
      MYSQL_ROOT_PASSWORD: ${DATABASE_DEV_PASSWORD}
      MYSQL_USER: ${DATABASE_DEV_USER}
      MYSQL_PASSWORD: ${DATABASE_DEV_PASSWORD}

  test-db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    environment:
      MYSQL_DATABASE: test_app_test
      MYSQL_ROOT_PASSWORD: ${DATABASE_DEV_PASSWORD}
      MYSQL_USER: ${DATABASE_DEV_USER}
      MYSQL_PASSWORD: ${DATABASE_DEV_PASSWORD}
    ports:
      - '3307:3306'

  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    tty: true 
    stdin_open: true
    depends_on:
      - db
      - test-db
    ports:
      - "3000:3000" 
    volumes:
      - .:/test_app
      - bundle:/usr/local/bundle

volumes:
  bundle:

ポイントだけ書きます。

  • command行はdatabaseの文字コードをutf8に設定しています。これがないとdb:create時にエラーになりました。
  • enviromentではユーザー名やパスワードを設定しています。もちろん直接書いても動きますがここでは環境変数を展開しています。docker-composeファイルはデフォルトで.envファイルを読み込むようなので下記のように.envファイルに定義します。定義した環境変数は${}で展開できます。.envファイルはコミットしないように.gitignoreファイルに追加します。
.env
DATABASE_DEV_USER = 'hoge'
DATABASE_DEV_PASSWORD = 'password'

3. database.ymlを変更

database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  charset: utf8
  pool: 5
  port: 3306

development:
  <<: *default
  database: test_app_development
  username: <%= ENV['DATABASE_DEV_USER'] %>
  password: <%= ENV['DATABASE_DEV_PASSWORD'] %>
  host : db

test:
  <<: *default
  database: test_app_test
  username: <%= ENV['DATABASE_DEV_USER'] %>
  password: <%= ENV['DATABASE_DEV_PASSWORD'] %>
  host : test-db

production:
  <<: *default
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOSTNAME'] %>
  • usernameとpasswordはdocker-composeと同じものです。
  • hostで作成したdbコンテナに接続するように設定しています。
  • productionは各々の環境に合わせてください
  • 環境変数の管理にはdotenv-railsのgemを利用しています。

4. 起動

最後にdockerを起動できれば成功です。
1. docker-compose buildでimageを作成
2. docker-compose up -dでコンテナを立ち上げる。-dはバックグラウンドで起動するオプションです。
3. docker-compose run web rails db:createでデータベース作成

これでhttp://localhost:3000/ に表示されれば成功です。
あとはdb:migrateやdb:seedをすれば完了です。

参考記事

Dockerを使用して既存のRailsプロジェクト開発環境構築してみた(Rails+Mysql)
既存のRailsアプリをDockerコンテナで動かす方法+sequel proによるDBコンテナ可視化
Rails x Docker環境にテストDBを構築する

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

Docker Compose が docker.credentials.errors.InitializationError のエラー表示で起動しない

TL,DR

Dockerアイコンのメニューの「Troubleshoot」を選択、「Reset to factory defaults」ボタンで初期化すれば直る

エラーの内容

$ docker-compose up -d --build
Building ubuntu
Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 67, in main
  File "compose/cli/main.py", line 126, in perform_command
  File "compose/cli/main.py", line 1070, in up
  File "compose/cli/main.py", line 1066, in up
  File "compose/project.py", line 615, in up
  File "compose/service.py", line 346, in ensure_image_exists
  File "compose/service.py", line 1125, in build
  File "site-packages/docker/api/build.py", line 261, in build
  File "site-packages/docker/api/build.py", line 308, in _set_auth_headers
  File "site-packages/docker/auth.py", line 311, in get_all_credentials
  File "site-packages/docker/auth.py", line 262, in _resolve_authconfig_credstore
  File "site-packages/docker/auth.py", line 287, in _get_store_instance
  File "site-packages/docker/credentials/store.py", line 25, in __init__
docker.credentials.errors.InitializationError: docker-credential-gcloud not installed or not available in PATH
[56567] Failed to execute script docker-compose

手順

ステップ1
pic1.png
ステップ2
pic2.png

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

[Docker] 特定のコンテナに紐づくボリュームのみ削除

特定のvolumeだけ削除したい

$ docker volume prune だと未使用のvolume全て削除してしまうし、 $ docker volume lsを見ても、どのvolumeが消したいコンテナのやつかわからない

削除したいvolumeをもつコンテナ名をセット

$ CONTAINER_NAME=hoge

コンテナ名が分からないとき

$ docker ps
CONTAINER ID        IMAGE           COMMAND                  CREATED             STATUS              PORTS                    NAMES
1fd9075c0f5d       my_project_app   "docker-entrypoint.s…"   59 minutes ago      Up 59 minutes       0.0.0.0:8080->8080/tcp   app

最後列のNAMESの値がコンテナ名

ワンライナー削除コマンド

$ docker inspect $(docker ps -f name=${CONTAINER_NAME} -q) | jq -r '.[].Mounts[] | select(.Type == "volume").Name' | xargs docker volume rm

概要

  • コンテナ名からコンテナIDを取得
  • docker inspectjq の組み合わせでvolume nameを取得
  • docker volume rm {volume name} で削除

jq がない場合は要インストール

もっとシンプルなケース

コンテナの削除と同時にvolumeも削除したいケースなら

docker-compose down -v $CONTAINER_NAME

docker-composeを使ってるとき限定だが、こちらのほうが簡単

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

Docker x Laravel めちゃくちゃ遅い Docker for Windows を爆速化する

@ucan-labさんのDocker x Laravel めちゃくちゃ遅い Docker for Mac を爆速化するの案4をWindows10で検証しました。

案4. ボリュームマウントを使う

vendorやnode_modulesのデータを名前付きボリュームに格納して、ホスト側とコンテナ側と分離して管理する案。
同期処理が発生しないので、その分速くなる。

docker-compose.ymlにボリュームマウントの設定を追加して、composerとnpmのインストールを比較します。この記事ではなぜ早くなるかは触れません。

結果

composer installnpm installの速度をそれぞれ比較しています。

$ time composer install
real    6m26.446s  -> 0m57.445s  # 6.7倍
user    0m9.375s   -> 0m3.035s
sys     0m51.148s  -> 0m1.544s

$ time npm install
real    1m31.764s  -> 0m22.720s  # 4.0倍
user    0m46.022s  -> 0m23.705s
sys     0m32.465s  -> 0m13.917s

Windows10環境では4~7倍速くなりました!
参照元のMacのように20倍とはいきませんでしたが、数行の追加だけで十分早くなって満足です!

環境

ホストOSの環境

  • Windows 10 Home バージョン2004(OSビルド 19041.508)
  • WSL2 (Ubuntu 20.04.1 LTS)
  • Docker version 19.03.13, build 4484c46d9d
  • docker-compose version 1.27.4, build 40524192

環境構築には下の記事が参考になります。
Windows Subsystem for Linux Installation Guide for Windows 10
Windows 10 Home で WSL 2 + Docker を使う | Qiita

コンテナ

Laravel + Nginx + MySQLの開発環境を使って検証します。
詳しくはブログで公開しています。

  • php (php-fpm) 7.4.1
    • composer 1.10.13
    • nodejs v12.18.4
    • npm 6.14.6
    • Laravel 8.8.0
  • mysql 8.0
  • nginx 1.19.2

composerとpackage.jsonは、プロジェクト作成からlaravel/jetstreamのInertiaをインストールしたところまでの状態です。

検証するdocker-compose.yml

コメントadd行の有無で速度を比較しています。

version: '3'

volumes: # add
  vendor-store: # add
  node_modules-store: # add

services:
  php:
    container_name: php
    build: ./docker/php
    volumes:
    - ./web:/var/www
    - vendor-store:/var/www/laravel/vendor # add
    - node_modules-store:/var/www/laravel/node_modules # add
    environment:
      TZ: Asia/Tokyo

  nginx:
    image: nginx
    container_name: nginx
    ports:
    - 80:80
    volumes:
    - ./web:/var/www
    - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
    - php

  db:
    image: mysql:8.0
    container_name: db
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: database
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
    - ./docker/db/data:/var/lib/mysql
    - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
    - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
    - 3306:3306

実行手順は参照元と同等です。パスを読み替えてください。

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

【0からDockerに挑戦】②DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる part1

背景

未経験から自社開発系企業の就職を目指します。
良質なポートフォリオ作成のためDockerを勉強することにしました。

知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。
またDockerを学ぶ上で必要とされるlinuxやネットワーク関連の勉強はほぼしていないです。
同じくらいのレベルでこれからDockerに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。

最終目標

・Dockerを使って0からRuby on Rails環境が構築できるようになること。
※複数回に渡ってdockerの記事を書く予定です。今回はその第2弾「DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる」です。

DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる

今回の環境と条件

・Dockerを使って環境構築を行う。(コンテナ上でサーバーを起動し、localhost:3000でrailsの初期画面を映すまでがゴール)。
・railsのバージョンは6.0.0
・rubyのバージョンは2.6
・データベースはmysql(今回はバージョン指定していない)
・railsとデータベースは別々にコンテナをたてます。
・基本的に他サイトからの無意味なコピペはしない。すべてのコードを理解した上で実装する。

手順

今回は下記手順で実施したいと思います。
 ①ローカルPC上に必要なディレクトリ・ファイルをつくる
 ②そのうちDockerfile、docker-compose.yml、Gemfileに必要な記述を書く
 ③docker-composeをビルド・実行させる
 ④コンテナ上でrails newを実行し必要なファイルを作成する。
 ⑤コンテナ上でデータを作成・起動する

途中でエラーにもたくさん悩まされたので、そのエラーについても説明します。
私と同じように初めてDockerで環境構築しようとしている方にとって少しでも役にたてれば幸いです。それでは早速実施します。

①ローカルPC上に必要なディレクトリ・ファイルをつくる

今回はデスクトップ上にディレクトリをつくりました。構成は下記になります。

Desktop/
├ test-product/
    └ Dockerfile
    ├ docker-compose.yml
    ├ Gemfile
    ├ Gemfile.lock

ファイルの説明をします。DockerfileとはDockerコンテナの定義や何をするかを記述します。Dockerfileがコンテナの中身を決めるものだとすると、docker-compose.ymlはコンテナを外側から見たときの挙動や複数コンテナがある場合はコンテナ同士の関係性なども記述します。Gemfileはrailsをやっている方ならわかるかと思いますが、ライブラリを管理するパッケージです。なぜGemfileだけあらかじめ作っておくかというと、railsのバージョンを指定するためです。DockerfileのFROMにはrubyのイメージを指定していますが、Railsのバージョンはありません。そのためあらかじめGemfileにRailsのバージョンを指定することで、Dockerfileでbundle installをしたときにrailsのバージョンに合わせたライブラリがインストールされます。基本的にはDockerfileでのイメージは言語を使用し、同じディレクトリ内にフレームワーク用のパッケージを用意するやり方が主流だといわれています。 Gemfile.lockはGemfileと合わせて必要なファイルなので用意したと捉えてください。

②そのうちDockerfile、docker-compose.yml、Gemfileに必要な記述を書く

Gemfile.lockは空のままで大丈夫です。それ以外の3つは下記のように編集しましょう。
※実は実行した際たくさんのエラーに出会っています。下記に記すのは最終的に問題のなかったコードです。

■コードの説明

Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.0.0'

こちらはrails勉強した人なら問題ないと思います。今回はrails6.0.0を使います。

Dockerfile
FROM ruby:2.6
RUN apt-get update && apt-get install -y \
      build-essential \
      libpq-dev \
      nodejs \
      mariadb-client &&\
      curl -o- -L https://yarnpkg.com/install.sh | bash
WORKDIR /test-product
COPY Gemfile Gemfile.lock /test-product/
RUN bundle install

上から順に簡単に説明します。
- FROMでrubyのイメージを取得しています。使う予定のRailsのバージョンにも気をつけてrubyのバージョンも指定してください。
- RUNで必要なライブラリをインストールしています。ちなみにapt-getはubuntuで使われるコマンドです。installの前にupdateするのは、古いバージョンをインストールする可能性があるためです。また、インストールする内容は言語によって異なりますが、rubyの場合は基本上記で大丈夫です。
- WORLDIRでコンテナ内の作業場所を移します。今回の場合/test-productはコンテナ内にないため新たに作成されます
- COPYでローカルのGemfileとGemfileをコンテナの/test-productにコピーします。
- 最後にRUNでbundle installを実行します。これで/test-productにあるGemfileが反映されるようになります。

docker-compose.yml
version: '3'

volumes:
    db-data:

services:
  web:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/test-product'
    environment: 
      - 'DATABASE_PASSWORD=mysql'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: mariadb
    volumes:
      - 'db-data:/var/lib/mysql/data'
    environment: 
      MYSQL_DATABASE: root
      MYSQL_ROOT_PASSWORD: mysql

こちらも上から順に説明します。
- versionはdocker-composeのバージョンです。基本3で問題ありません
- volumesはコンテナ内のデータをローカルに保存するための記述です。コンテナは削除されるとデータもまるごと消えてしまします。そのためvolumesを書くことでローカル内の見えないところでコンテナのデータを保存してくれます。
- serviceが具体的なコンテナの挙動を指定します。serviceはweb(railsのコンテナ)とdb(mysqlのコンテナ)に分かれています。
- buildはローカルでDockerfileがある場所を指定しています。今回はカレントディレクトリです。
- portはlocalhost:3000に問い合わせたら、コンテナの3000番が対応するという結びつけです。
- enviromentで環境変数を埋め込みます。今回はデータベースのパスワードをコンテナ内に埋め込みます。(rails newをしたらdatabase.ymlの変更の必要あり)
- ttyとstdin_opnをtrueにするとコンテナ内に入って操作ができるようになります。
- depend onとlinkでwebコンテナとdbコンテナを結びつけます。
- db:imageでデータベースのイメージを取得しています。
- volumesでコンテナのデータをローカルに保存する場所を指定します。データーベース種類によって決まりがあります。mysqlの際はこれで大丈夫です。

■エラーポイント

エラーが発生し困ったポイントです。Dockerfileやdocker-compose.ymlはエラー起こりやすいので気をつけましょう。

Dockerfile
(省略)
RUN apt-get update && apt-get install -y \
    ・
    ・
      mariadb-client &&\
      curl -o- -L https://yarnpkg.com/install.sh | bash
    ・
    ・
(省略)

上記は2点あります。まずmariadb-clientの箇所です。mysqlを使うのにmariadbを指定しています。これはコンテナ内で「rails s」をしたところ、「mysql-clientはありません」とエラーがでました。調べてみると「mariadb]と記載するとそのエラーが解消されるようです。
2つめはyarnに関してです。rails6.0以降はwebpackerのインストールが必須なのですが、その際にyarnをインストールする必要があります。「apt-get install yarn」でもyarnのインストールはできるのですが、webpackerをインストールするにはyarnが最新のバージョンでないといけないためエラーが起こります。そのため「curl・・・・」でyarnの最新バージョンをインストールしています。

[参考]
docker-compose buildするときにbundle installやmysql-clientでコケた話 @aseanchild1400
yarn公式ーーインストール

docker-compose.yml
db:
    image: mariadb
    volumes:
      - 'db-data:/var/lib/mysql/data'
    environment: 
      MYSQL_DATABASE: root
      MYSQL_ROOT_PASSWORD: mysql

こちらに関しては「docker-compose up」を実行してもコンテナが起動しない場合があります。その場合ターミナルで「docker-compose logs」を入力してみましょう!そうすると原因がわかるのですが、今回はmysqlのnameとpasswordがないとエラーがでたので、enviroment以下追加しました。(※こちらのやり方関しては最後煮汁してあるudemyのDocker講座の方を参照しています)。
またこちらのimageもmysqlだとエラーが起こるのでmariadbにしています。




長くなってしまったのでここで一旦切ります。③以降は次回の記事に書いていきます。

まとめ

railsだとyarnとwebpackerあたりがエラー起きやすいです。あとはmysqlなどdb関連もエラー起きやすいので注意が必要です。
実際に探り探り環境構築していくと、docker実行時にたくさんエラーが起きますが、1個1個調べていけば解決できるでしょう。
dockerもまだまだ奥深いですが、だんだん面白くなってきたので頑張りたいです!

参考になった教材

「米国AI開発者がゼロから教えるDocker講座」 
https://www.udemy.com/course/aidocker/
→初心者がDockerを学ぶならこれ!!!めちゃくちゃわかりやすい!!!linuxの基礎からDockerでの環境構築を網羅しています。
今回の環境構築もこの教材をベースにしています(もちろんrailsのバージョンとかdbなど自分なりに変えているので同じではないです)
もしDocker全然わかないという人はこの講座をぜひ買ってみてください。

「いまさらだけどDockerに入門したので分かりやすくまとめてみた」 
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
→すごく細かく網羅しているのでとてもわからなくなったらよく見ています。リファラル的によくみさせていただいてます。

「Docker/Kubernetes 実践コンテナ開発入門 --著 山田 明憲」 
→実践的な書籍、あまりにも初学者だと少しむずかしいかも。 → 基礎覚え得たあとに見返したら非常に良かったです!

「たった1日で基本が身に付く! Docker/Kubernetes超入門 --著」
→初学者が書籍で学びたい場合はこれがとっかかりやすい。

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

【0からDockerに挑戦】②DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる (part1)

背景

未経験から自社開発系企業の就職を目指します。
良質なポートフォリオ作成のためDockerを勉強することにしました。

知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。
またDockerを学ぶ上で必要とされるlinuxやネットワーク関連の勉強はほぼしていないです。
同じくらいのレベルでこれからDockerに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。

最終目標

・Dockerを使って0からRuby on Rails環境が構築できるようになること。
※複数回に渡ってdockerの記事を書く予定です。今回はその第2弾「DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる」です。

DockerとDocker-composeを使ってRuby on Rails・MYSQLの開発環境をつくる

今回の環境と条件

・Dockerを使って環境構築を行う。(コンテナ上でサーバーを起動し、localhost:3000でrailsの初期画面を映すまでがゴール)。
・railsのバージョンは6.0.0
・rubyのバージョンは2.6
・データベースはmysql(今回はバージョン指定していない)
・railsとデータベースは別々にコンテナをたてます。
・基本的に他サイトからの無意味なコピペはしない。すべてのコードを理解した上で実装する。

手順

今回は下記手順で実施したいと思います。
 ①ローカルPC上に必要なディレクトリ・ファイルをつくる
 ②そのうちDockerfile、docker-compose.yml、Gemfileに必要な記述を書く
 ③docker-composeをビルド・実行させる
 ④コンテナ上でrails newを実行し必要なファイルを作成する。
 ⑤コンテナ上でデータを作成・起動する

途中でエラーにもたくさん悩まされたので、そのエラーについても説明します。
私と同じように初めてDockerで環境構築しようとしている方にとって少しでも役にたてれば幸いです。それでは早速実施します。

①ローカルPC上に必要なディレクトリ・ファイルをつくる

今回はデスクトップ上にディレクトリをつくりました。構成は下記になります。

Desktop/
├ test-product/
    └ Dockerfile
    ├ docker-compose.yml
    ├ Gemfile
    ├ Gemfile.lock

ファイルの説明をします。DockerfileとはDockerコンテナの定義や何をするかを記述します。Dockerfileがコンテナの中身を決めるものだとすると、docker-compose.ymlはコンテナを外側から見たときの挙動や複数コンテナがある場合はコンテナ同士の関係性なども記述します。Gemfileはrailsをやっている方ならわかるかと思いますが、ライブラリを管理するパッケージです。なぜGemfileだけあらかじめ作っておくかというと、railsのバージョンを指定するためです。DockerfileのFROMにはrubyのイメージを指定していますが、Railsのバージョンはありません。そのためあらかじめGemfileにRailsのバージョンを指定することで、Dockerfileでbundle installをしたときにrailsのバージョンに合わせたライブラリがインストールされます。基本的にはDockerfileでのイメージは言語を使用し、同じディレクトリ内にフレームワーク用のパッケージを用意するやり方が主流だといわれています。 Gemfile.lockはGemfileと合わせて必要なファイルなので用意したと捉えてください。

②そのうちDockerfile、docker-compose.yml、Gemfileに必要な記述を書く

Gemfile.lockは空のままで大丈夫です。それ以外の3つは下記のように編集しましょう。
※実は実行した際たくさんのエラーに出会っています。下記に記すのは最終的に問題のなかったコードです。

■コードの説明

Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.0.0'

こちらはrails勉強した人なら問題ないと思います。今回はrails6.0.0を使います。

Dockerfile
FROM ruby:2.6
RUN apt-get update && apt-get install -y \
      build-essential \
      libpq-dev \
      nodejs \
      mariadb-client &&\
      curl -o- -L https://yarnpkg.com/install.sh | bash
WORKDIR /test-product
COPY Gemfile Gemfile.lock /test-product/
RUN bundle install

上から順に簡単に説明します。
- FROMでrubyのイメージを取得しています。使う予定のRailsのバージョンにも気をつけてrubyのバージョンも指定してください。
- RUNで必要なライブラリをインストールしています。ちなみにapt-getはubuntuで使われるコマンドです。installの前にupdateするのは、古いバージョンをインストールする可能性があるためです。また、インストールする内容は言語によって異なりますが、rubyの場合は基本上記で大丈夫です。
- WORLDIRでコンテナ内の作業場所を移します。今回の場合/test-productはコンテナ内にないため新たに作成されます
- COPYでローカルのGemfileとGemfileをコンテナの/test-productにコピーします。
- 最後にRUNでbundle installを実行します。これで/test-productにあるGemfileが反映されるようになります。

docker-compose.yml
version: '3'

volumes:
    db-data:

services:
  web:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/test-product'
    environment: 
      - 'DATABASE_PASSWORD=mysql'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: mariadb
    volumes:
      - 'db-data:/var/lib/mysql/data'
    environment: 
      MYSQL_DATABASE: root
      MYSQL_ROOT_PASSWORD: mysql

こちらも上から順に説明します。
- versionはdocker-composeのバージョンです。基本3で問題ありません
- volumesはコンテナ内のデータをローカルに保存するための記述です。コンテナは削除されるとデータもまるごと消えてしまします。そのためvolumesを書くことでローカル内の見えないところでコンテナのデータを保存してくれます。
- serviceが具体的なコンテナの挙動を指定します。serviceはweb(railsのコンテナ)とdb(mysqlのコンテナ)に分かれています。
- buildはローカルでDockerfileがある場所を指定しています。今回はカレントディレクトリです。
- portはlocalhost:3000に問い合わせたら、コンテナの3000番が対応するという結びつけです。
- enviromentで環境変数を埋め込みます。今回はデータベースのパスワードをコンテナ内に埋め込みます。(rails newをしたらdatabase.ymlの変更の必要あり)
- ttyとstdin_opnをtrueにするとコンテナ内に入って操作ができるようになります。
- depend onとlinkでwebコンテナとdbコンテナを結びつけます。
- db:imageでデータベースのイメージを取得しています。
- volumesでコンテナのデータをローカルに保存する場所を指定します。データーベース種類によって決まりがあります。mysqlの際はこれで大丈夫です。

■エラーポイント

エラーが発生し困ったポイントです。Dockerfileやdocker-compose.ymlはエラー起こりやすいので気をつけましょう。

Dockerfile
(省略)
RUN apt-get update && apt-get install -y \
    ・
    ・
      mariadb-client &&\
      curl -o- -L https://yarnpkg.com/install.sh | bash
    ・
    ・
(省略)

上記は2点あります。まずmariadb-clientの箇所です。mysqlを使うのにmariadbを指定しています。これはコンテナ内で「rails s」をしたところ、「mysql-clientはありません」とエラーがでました。調べてみると「mariadb]と記載するとそのエラーが解消されるようです。
2つめはyarnに関してです。rails6.0以降はwebpackerのインストールが必須なのですが、その際にyarnをインストールする必要があります。「apt-get install yarn」でもyarnのインストールはできるのですが、webpackerをインストールするにはyarnが最新のバージョンでないといけないためエラーが起こります。そのため「curl・・・・」でyarnの最新バージョンをインストールしています。

[参考]
「docker-compose buildするときにbundle installやmysql-clientでコケた話 @aseanchild1400」
「yarn公式ーーインストール」

docker-compose.yml
db:
    image: mariadb
    volumes:
      - 'db-data:/var/lib/mysql/data'
    environment: 
      MYSQL_DATABASE: root
      MYSQL_ROOT_PASSWORD: mysql

こちらに関しては「docker-compose up」を実行してもコンテナが起動しない場合があります。その場合ターミナルで「docker-compose logs」を入力してみましょう!そうすると原因がわかるのですが、今回はmysqlのnameとpasswordがないとエラーがでたので、enviroment以下追加しました。(※こちらのやり方関しては最後煮汁してあるudemyのDocker講座の方を参照しています)。
またこちらのimageもmysqlだとエラーが起こるのでmariadbにしています。




長くなってしまったのでここで一旦切ります。③以降は次回の記事に書いていきます。

まとめ

railsだとyarnとwebpackerあたりがエラー起きやすいです。あとはmysqlなどdb関連もエラー起きやすいので注意が必要です。実際に探り探り環境構築していくと、docker実行時にたくさんエラーが起きますが、1個1個調べていけば解決できるでしょう。
dockerもまだまだ奥深いですが、だんだん面白くなってきたので頑張りたいです!

参考になった教材

「米国AI開発者がゼロから教えるDocker講座」 
https://www.udemy.com/course/aidocker/
→初心者がDockerを学ぶならこれ!!!めちゃくちゃわかりやすい!!!linuxの基礎からDockerでの環境構築を網羅しています。
今回の環境構築もこの教材をベースにしています(もちろんrailsのバージョンとかdbなど自分なりに変えているので同じではないです)
もしDocker全然わかないという人はこの講座をぜひ買ってみてください。

「いまさらだけどDockerに入門したので分かりやすくまとめてみた」 
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
→すごく細かく網羅しているのでとてもわからなくなったらよく見ています。リファラル的によくみさせていただいてます。

「Docker/Kubernetes 実践コンテナ開発入門 --著 山田 明憲」 
→実践的な書籍、あまりにも初学者だと少しむずかしいかも。 → 基礎覚え得たあとに見返したら非常に良かったです!

「たった1日で基本が身に付く! Docker/Kubernetes超入門 --著」
→初学者が書籍で学びたい場合はこれがとっかかりやすい。

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

vscodeのRemote-Containersでnginxを使おうとした時に困ったメモ

やろうとしたこと

ワイ「vscodeのRemote-ContainersDockerでアプリ開発してみよ。まずはnginxからや。Remote-ContainersもDockerもnginxも全然知らんけどなんとかなるやろ」

起きたこと

以下のymlを用意し、docker-compose up -dすると、localhost:8080で別に用意したindex.htmlが表示されることを確認。

docker-compose.yml
version: '3.8'
services:
  web:
    image: nginx
    volumes:
      - .:/usr/share/nginx/html
    ports:
      - "8080:80"

が、同じものをvscodeのRemote-Containersで開いた場合、localhost:8080にアクセスしてもindex.htmlが表示されない。

Remote-Containers実行時に自動で作成される./.devcontainer/docker-compose.ymlcommand: /bin/sh -c "while sleep 1000; do :; done"行がデフォルトで記述されているのだが、この行があるとindex.htmlが表示されなくなる模様。

Remote-Containers実行後のディレクトリ構造
.devcontainer/          # Remote-Containers実行で自動生成
  devcontainer.json
  docker-compose.yml    # こいつにcommand行がある
docker-compose.yml
index.html

command: (以下略)./docker-compose.ymlに書かれていた場合もindex.htmlが表示されなくなる。

なんで?

わからん...。

command: /bin/sh -c "while sleep 1000; do :; done"無しのdocker-compose.ymlでnginxコンテナを起動し、アタッチして同じsleepコマンドを叩くとちゃんと実行される(以下ログ)ので、コンテナ内でcommand:のコマンドでエラーが出ているわけではなさそう。

root@hoge:/workspace# /bin/sh -c "while sleep 1000; do :; done"
^C
root@hoge:/workspace# 

なんか怪しいやついた

docker ps --no-truncをやってみたところ、手動でdocker-compose up -dやった時のCOMMAND/docker-entrypoint.sh nginx -g 'daemon off;'とのこと。これが/bin/sh -c "while sleep 1000; do :; done"によって上書きされるからか?

web_tmp > docker-compose up -d
Creating web_tmp_web_1 ... done
web_tmp >
web_tmp > docker ps --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND
 CREATED             STATUS              PORTS                  NAMES
8f7c7a3300bd7e9894f387b39cc904776858893e337f849ecee5dd69e6ad9291   nginx               "/docker-entrypoint.sh nginx -g 'daemon off;'"  
 2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   web_tmp_web_1
web_tmp > 

ビンゴ

docker-compose.ymlcommand: /docker-entrypoint.sh nginx -g 'daemon off;'にしたらindex.htmlが表示された。原因これだ!

デフォルトで暗黙的に実行されているdocker-entrypoint.shを別コマンドで上書きしてしまった結果、nginxのdaemonが起動しなくなったものと思われる。ひとまず解決した!やったー!!

まとめ

  • 事象 : nginxのdocker-compose.ymlcommand: /bin/sh -c "while sleep 1000; do :; done"があるとindex.htmlが表示されなくなる
  • 原因 : nginxコンテナを起動する時のCOMMANDが、デフォルト(= /docker-entrypoint.sh nginx -g 'daemon off;')から/bin/sh -c "while sleep 1000; do :; done"に上書きされてしまうため
  • 対処 : すべてのdocker-compose.ymlから command:をコメントアウトする。(あるいは、command: /docker-entrypoint.sh nginx -g 'daemon off;'にする。普通そんなことしないけど。)

参考

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

【Django】PyCharmでDjangoのコンテナ(Docker)開発環境をサクっと構築する

はじめに

普段業務でPyCharmを愛用しているのですが、Djangoコンテナ開発環境の構築について調べるのに少し時間がかかったので、最小構成で構築する手順を投稿します。

※この記事はPyCharm Professional(有料 無料期間30日有り)専用機能の紹介です。
無料でやりたい方は別記事でVSCodeを使ったコンテナ開発環境構築を紹介していますのでそちらをご覧ください。VSCodeには強力な拡張機能が多くあるのでDjangoの開発にも十分使えます。

事前準備

1.Djangoプロジェクトの作成

※既に開発中のソースがある方はそれを使ってもOKです
今回はPythonインストール済みの環境で以下コマンドから作成したシンプルなDjangoアプリを使用します。

> pip install django
> django-admin startproject sampleApp
> cd sampleApp
sampleApp> python manage.py migrate

2.Dockerfileの作成

Djangoアプリを作成したフォルダに以下内容のDockerfileを作成します。

FROM python:3.8

# 必要なパッケージがある場合インストール
# RUN apt install ~~~

RUN pip intall django

3.docker-compose.ymlの作成

同じくDjangoアプリを作成したフォルダに以下内容で作成します。

docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - './:/app/sampleApp'
    working_dir: '/app/sampleApp'
    container_name: sampleApp
    privileged: true
    tty: true

準備は以上です。
ここまでのディレクトリ構成は以下の通りです。

Django-docker-sample-pycharm #今回のワークスペースフォルダ
|   docker-compose.yml
|   Dockerfile
|
\---sampleApp
    |   db.sqlite3
    |   manage.py
    |
    \---sampleApp
        |   asgi.py
        |   settings.py
        |   urls.py
        |   wsgi.py
        |   __init__.py

リモートインタープリタの設定

ワークスペースフォルダをPyCharmで開きます。
続いて[File]→[Settings]から[Python Interpreter]を選択し、インタープリタの追加画面を開きます。
image.png

Docker Composeを選択し、[Server]新規作成画面を開きます。
image.png

特に何も変更せずOKで作成します。
image.png

続いて[Service]のプルダウンから[app]を選択し、OKで設定を完了します。
image.png

インタープリタの設定画面でリモートインタープリタが表示されていればOKです。
Dockerfileで「pip install django」を実行していたのでパッケージの一覧にDjangoが表示されていますね。
OKで設定を完了させましょう。
image.png

これで「このプロジェクトではワークスペースフォルダ直下にあるdocker-compose.ymlから作成されたコンテナのインタープリタを使用する」という設定が完了しました:cat2:

いざ実行!

ここからはいつもの手順でrunserverしていきましょう。

[File]→[Settings]からDjangoの設定
image.png

[Add Configurations]
image.png

[+]→[Django Server]
image.png

[Name](任意)と[Host](0.0.0.0)を設定してOK
image.png

実行!隣の虫マークのボタンからデバッグも可能です。
image.png

ブラウザからhttp://localhost:8000にアクセスしてDjangoテストページが表示されればOK!
image.png

コンソールを見るとsampleAppコンテナ内で実行されていることがわかります。
image.png

デバッグモードではもちろんブレークポイントも使えます!
image.png

こんなに簡単にリモートインタープリタが使えるなんてさすが有料機能ですね。
これでコンテナを使った開発も捗りそうです:cat2:

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

Github ActionsでGithub Container RegistryにDocker imageをpushする最小Workflow

公式ではstarter-workflowsとしてDocker imageをbuildをしてGithub Container RegistryにpushするまでのWorkflowが用意されていますが、アクションを使っておらず泥臭くやっているので本記事でアクションを使ったWorkflow構成を記載します。

前提

今回取り扱うリポジトリのファイル構成はルート直下にDockerfileが存在するものとします。

-- 
|-- Dockerfile
|-- README.md
|-- .github
    |-- workflows
        |-- actions.yml
...

.github/workflows/action.yml
name: Build and Publish Docker

on:
  push:
    branches:
      - master

jobs:
  build_and_push:
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: sample-app
    steps:
      - name: checkout
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.CR_PAT }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: |
            ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest
            ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:1.0.0

ワークフロー解説

本ワークフローではbuild_and_pushというジョブを定義しています。
以降はそのジョブ内の各ステップが何をしているか軽く解説します。

checkout

ソースコードをcheckoutします。
actions/checkout@v2アクションを利用しています。

Set up Docker Buildx

docker/build-push-action@v2アクションでdocker buildのための必要なセットアップをここで行っています。
docker/setup-buildx-action@v1アクションを利用しています。

Login to GitHub Container Registry

GitHub Container Registryにdocker imageをpushするためにここでdocker loginを行います。
docker/login-action@v1アクションを利用します。
withで必要なパラメータを定義します。

パラメータ
registry Dockerレジストリを指定する
今回はGithub Container Registryにpushするのでghcr.ioを指定
未指定の場合はDocker Hubになる
username Dockerレジストリにpushするユーザを指定する
今回はリポジトリオーナー名を環境変数から指定※1
password DockerレジストリにpushするパスワードもしくはPersonal Access Tokenを指定する
今回はsecretsにCF_PATという名前で格納したPersonal Access Tokenを指定※2

※1: Github Actionsではデフォルトでいくつかの環境変数が用意されており、今回はその中から取得しました。
参考:Environment variables - GitHub Docs

※2: シークレットの設定方法はこちらを参照。
Encrypted secrets - GitHub Docs

Build and push

docker builddocker pushを行います。
docker/build-push-action@v2アクションを利用しています。
withで必要なパラメータを定義します。

パラメータ
context docker buildする際のパスもしくはURLを指定
actions/checkoutアクションを使った場合にパスの指定が可能
今回はcheckoutしたルート配下を指定
未指定の場合はGit contextとなる
push Dockerレジストリにpushする場合はtrueを指定
tags buildするimageにつけるタグを指定
タグは複数指定可能
今回はlatestと1.0.0のタグを付与
file 参照するDockerfileパスを指定
未指定の場合は./Dockerfileとなる
今回はこのパラメータは使用していないがルート直下以外のDockerfileを参照する場合は使用する

参考

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

【k8s】pod間通信をやってみた!

はじめに

現在、様々なサービスのマイクロサービス化が進んでいる。その際、重要になってくるの部分の一つとして、サービス間の通信が挙げられる。
また、マイクロサービスを導入していく場合、kubernetesを用いた開発がよく採用されている。

そこで、今回は、サービス間の通信の一手法として、kuberntesの最小リソースであるpod間の通信方法についてみてみる。

サービス間の通信方法については、pod間通信の他にも,
gRPCなどの通信方法がある。

今回作るもの

今回はすごく簡易的なものとして、k8sのdeploymentで作成されたhttpd サーバーのpodとnginxのpodを通信してみる

httpd

httpd_deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
spec:
  selector:
    app: httpd
  ports:
  - port: 8090
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2-alpine
        ports:
        - containerPort: 80

nginx

nginx_deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - port: 8080
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18-alpine
        ports:
        - containerPort: 80

とりあえず、通信してみる

  • 上でつくったdeploymentたちを起動
$ kubectl apply -f httd_deployment.yml -f nginx_deployment.yml 
  • ちゃんと立ち上がったか確認
$ kubectl get po 

NAME                    READY   STATUS    RESTARTS   AGE
httpd-7f8bd9884-jptwt   1/1     Running   0          4m26s
nginx-d69ddfd76-r4lhq   1/1     Running   0          4m26s

statusが両方ともRunningになっていればok

httpd→nginx

  • httpdのpodに入る
$ kubectl exec -it httpd-7f8bd9884-jptwt sh
/ # 
  • httpdのpod内からnginxのpodにアクセスしてみる
/ # curl http://nginx-svc:8080

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

nginx→httpd

  • nginxのpodにはいる
$ kubectl exec -it nginx-d69ddfd76-r4lhq sh
  • nginxのpod内からhttpdのpodにアクセスしてみる
/ # curl http://httpd-svc:8090
<html><body><h1>It works!</h1></body></html>

アクセスできたのが確認できた。

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