20200712のdockerに関する記事は12件です。

[Github Actions]Dockerfileのビルドからリポジトリプッシュまで自動化

Qiitaにも書いたVSCodeエクステンション作りの上で Node.js 環境をDockerで立てたのですが、

  • エクステンション作りのセッティングが汎用なので、パブリックにバラまいても良いネタで
  • Docker Hubへの docker push デビューしたくて
  • Github Actions オートプッシュもやっちゃいたいな

と、何本かモチベーションが重なったので、VSCodeエクステンション環境の Dockerfile をGithub管理して、master ブランチへの修正をトリガーに docker push する、割とオーソドックスなActionを作りました。

リポジトリ

リポジトリの中身

.github
    |__ workflows
        |__ docker-image.yml
Dockerfile
README.md
  • .github/workflows
    • Github Actions で行う処理を書く
  • Dockerfile
    • 今回 docker build して push する対象
  • README.md
    • りーどみー

オート docker push までの道

Docker Hubのアカウントと docker push 先のリポジトリは作っているものとして書きます。

1. Docker Hubの認証情報を Secrets に登録

Github Actions 内だけでコール出来る特殊な環境変数と言う具合で用いることが出来るツールです。
Jenkinsで言うと、Jenkins全体で用いるユーザー・パスワードを環境変数として入れておくと思うのですが、それのリポジトリ単位バージョンと思ってもらえれば良いと思います。

リポジトリ上部メニュー Settings タブから

image.png

左サイドメニュー Secrets へ。

image.png

New Secret ボタンを押下すると、リポジトリから隠蔽したいセンシティブな情報をkey-valueで登録出来ます。

image.png

ここで、Docker Hubへログインするためのユーザー・パスワードを登録しておきましょう。
私は DOCKER_HUB_USERDOCKER_HUB_PASS で入れておきました。

2. Actionとして行われる定義を書く

Github ActionsYAML ファイルで定義されます。STEP分割の具合は Jenkinsfile っぽさがありますが、Groovy スクリプトの後者よりはとっつきやすい具合で書けるかなーと思います。

docker-images.yml
name: Docker Image CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Build the Docker image
      run: docker build . --file Dockerfile --tag prswatch/vscode-extension-env:latest
    - name: Login Docker Hub
      run: echo ${{ secrets.DOCKER_HUB_PASS }} | docker login -u ${{ secrets.DOCKER_HUB_USER }} --password-stdin
    - name: Push Docker Image
      run: docker push prswatch/vscode-extension-env:latest

Secrets に入れた認証情報は {{ secrets.DOCKER_HUB_PASS }} な具合でコールしています。

3. Actionを回す

無事、Docker Hubへ push されていれば大丈夫です!

image.png

まとめ

めでたし!

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

Windows10 HomeにDockerをインストールしようと思ったがうまくいかなかった

Windows10 HomeにDockerをインストール

Pythonの勉強を始めようと思ってるんですが、どうせならDockerで
環境を作ろうかなと思ったわけです。

ただ、Docker Desktop for Windows は Hyper-V の利用を前提としているので
Windows10 Proが必要みたいなんですよね。
Windows10 HomeでDockerを使うにはDocker Toolboxをインストールすればいいらしい。

Docker Toolboxのインストール手順を調べてたんですが、
Docker Desktop for WindowsがWindows10 HomeDのWSL2に対応するという記事を見まして
Windows10 HomeにDockr Desktop for windowsのインストールを試してみました。

まずはDockerインストールやってみる

Dockerをインストール。

https://docs.docker.com/docker-for-windows/install/

docker1.jpg

DockerhubからGet stableボタンをクリック。

docker2.jpg

インストールをスタート。

docker3.jpg

ダメみたいですね。
OSビルドが古い感じ?

Windowsアップデートをやってみる

Docker Desktop for windowsに対応しているのは、
Windows10 Home(19018以降)ってことみたいなので、アップデートをしてみる。

調べてみるとWindows Insider Programでスローにしてアップデートするってことらしいけど。
insider.jpg

スロー設定ってないやん。

https://news.mynavi.jp/article/20200616-1057186/
配信方法が、リンク制からチャネル制にされてるのか。
Fastリング→Devチャネル、Slowリング→Betaチャネル、Release Previewリング→Release Previewチャネルってことね。

よし、Windows10 updateっと。

update.jpg

あれ、止まっちゃった。
何が引っかかってんだろ。

update2.jpg

アップデート先に進まないし。

これが解決するまで保留だな。

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

Docker for macの環境でk8sにECRの認証情報を渡すのに苦戦した件

概要

Dockerイメージを作成しAWS ECRにイメージを上げたが、K8Sでプルできなかった。
調べたらしっかり認証情報がわたっていなかった。

環境

  • mac Catalina
  • docker for mac
  • AWS Cli
    • これがしっかり使える前提です

解決手順

デスクトップ右上にあるDockerのマークをクリックしてPreferencesを開く。
そうすると「Include VM in Time Machine backups」というものがあるのでこれをクリックするとしたの、「Securely store Docker logins in macOS keychain」がアクティブになるのでクリックして無効化

その後、(vim -/.docker)を以下のように変更

config.json
"credsStore": "desktop" #これを削除

これで以下のようにコマンドを叩くとECRの認証情報が保存されてK8sでもとってこれる状態となる。

aws ecr get-login-password --region リージョン | docker login --username AWS --password-stdin ECRのエンドポイントのURL

その後この認証情報を持ったsecretを以下のコマンドで作れば、ECRからDockerイメージを持ってくることができるようになる。

kubectl create secret generic シークレットの名前 \
        --from-file=.dockerconfigjson=$HOME/.docker/config.json \
        --type=kubernetes.io/dockerconfigjson

参考資料

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

Docker Rails6 + MySQL mac環境構築メモ

Docker を使ってのmac上での Rails6 , MySQL 5.7 環境構築メモ

https://www.docker.com/
公式ページからmac用のdockerをインストールしておくこと

ファイル一式

ファイルの準備

・docker-compose.yml

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: root
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    ports:
      - "3306:3306"
    volumes:
      # 初期データを投入するSQLが格納されているdir
      - ./db/mysql_init:/docker-entrypoint-initdb.d
      # 永続化するときにマウントするdir
      - ./db/mysql_data:/var/lib/mysql

  web:
    build: .
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app_name
    ports:
      - "3000:3000"
    links:
      - db

・Dockerfile

FROM ruby:2.7.1

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

# 必要なパッケージのインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       libpq-dev \
                       nodejs yarn

# 作業ディレクトリの作成、設定
RUN mkdir /app_name
##作業ディレクトリ名をAPP_ROOTに割り当て 以下$APP_ROOTで参照
ENV APP_ROOT /app_name
WORKDIR $APP_ROOT

# ホスト側(ローカル)のGemfileを追加する
ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

# Gemfileのbundle install
RUN bundle install
ADD . $APP_ROOT

# おまじない
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

・Gemfile

source 'https://rubygems.org'
gem 'rails', '6.0.3'

・Gemfile.lock(空のファイル)

・entrypoint.sh

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app_name/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

「app_name」を間違えないように 本当は環境編集から取得するのが良さそう

mysql, rails のインストール

docker-compose run web rails new . --skip-action-mailer --skip-active-storage --skip-action-cable -d mysql

起動と確認

database.ymlの修正

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: db  # docker-compose.ymlで定義したMySQLのサービス名

DB初期化

docker-compose run web rake db:create

起動

docker-compose up web  

エラーが出たので再度コマンド実行

docker-compose up web
docker_rails6_db_1 is up-to-date
Creating docker_rails6_web_1 ... done
Attaching to docker_rails6_web_1
web_1  | => Booting Puma
web_1  | => Rails 6.0.3.2 application starting in development 
web_1  | => Run `rails server --help` for more startup options
web_1  | Exiting
web_1  | /usr/local/bundle/gems/webpacker-4.2.2/lib/webpacker/configuration.rb:95:in `rescue in load': Webpacker configuration file not found /app_name/config/webpacker.yml. Please run rails webpacker:install 
 Error: No such file or directory @ rb_sysopen - /app_name/config/webpacker.yml (RuntimeError)

メッッセージの通りコマンド実行

 docker-compose run web rails webpacker:install
# 略
Webpacker successfully installed ? ?

再度実行

docker-compose up web

http://localhost:3000/ でいつもの画面で見れればOK

rails コマンドの実行

コンソールをもう1つ立ち上げてrailsのコマンドが実行できることを確認しておく

docker-compose run [サービス名] [railsコマンド] の書式で実行

docker-compose run web rails g controller home index

http://localhost:3000/home/index で作成した画面にアクセスできればOK

docker 停止

 docker-compose down   

コンテナの中に入ってコマンドを実行したい場合

docker container ls で実行中のコンテナ名を確認後

docker exec -i -t [コンテナ名] bash

隠しファイルが見れない場合は

.ruby-versionとか確認で来ていない場合はこのコマンドを実行

defaults write com.apple.finder AppleShowAllFiles TRUE

Finderを強制再起動

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

あるあるなWebアプリの開発環境(PHP、Apache、MySQL)をDockerで構築した話

自社サービスのメンテナをしています。

悩み

  • PHP、Apache、MySQLのバージョン上げなアカン
  • でも、旧バージョンもメンテし続けなアカン
  • ローカルPCでの開発環境がゴチャついてきた
  • 顧客ごとにカスタマイズされてて、顧客環境ごとにソース自体が微妙に違ってる・・・
  • できたらリモートサーバなしで、ローカルPCだけで完結させたい

Webサーバのディレクトリ構造はこんな感じ

/var/apps/
|-- abc # 株式会社abcさま用アプリ
|   |-- abc.php
|   |-- abc.png
|   `-- ・・・
|-- def # 株式会社defさま用アプリ
|   |-- def.php
|   |-- def.png
|   `-- ・・・
`-- ghi # 株式会社ghiさま用アプリ
    |-- ghi.php
    |-- ghi.png
    `-- ・・・

Dockerでなんとかしたいのですが・・・

  • アプリのバージョンで、PHPやMySQLのバージョンが異なる
    • アプリのバージョンごとにそれぞれの環境が必要
  • 顧客ごとにDBのインスタンスが異なる
    • MySQLの公式Dockerイメージって、初回起動のときにしかDB初期化スクリプト走らない
    • なので、初回起動以降は、いちいちDBコンテナに入ってDB作ったりテーブル作ったりラジバンダリ
  • 開発環境なので、デバッグを容易にできるようにしたい

Docker Composeでなんとかする

  • アプリが依存するPHP、Apache、MySQLのバージョンを切り替えられるようにする
  • 各アプリが使用するMySQLのDBインスタンスの生成を手軽に行いたい
  • Xdebugでデバッグしたい

できあがったものがこちらです

appdock

くわしくはREADMEをご参照くださいmm


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

docker-compose ver2.* を使って buildで TypeError が出る人へ

mem_limitを使いたかった。

ver 3.* では使えないので、2.2仕様に書き換えて docker-compose build

Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 11, in <module>
    load_entry_point('docker-compose==1.17.1', 'console_scripts', 'docker-compose')()
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 68, in main
    command()
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 121, in perform_command
    handler(command, command_options)
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 249, in build
    build_args=build_args)
  File "/usr/lib/python2.7/dist-packages/compose/project.py", line 343, in build
    service.build(no_cache, pull, force_rm, build_args)
  File "/usr/lib/python2.7/dist-packages/compose/service.py", line 923, in build
    shmsize=parse_bytes(build_opts.get('shm_size')) if build_opts.get('shm_size') else None,
TypeError: build() got an unexpected keyword argument 'stream'
  • ぱいそん の えらー が あらわれた!

解決方法

最新のdockerで出るエラーの模様。

pip install 'docker<3.0'

でとりあえず治ります。

参考

https://github.com/ansible/ansible/issues/35612

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

docker: mongodb

terminal
# lauch
docker run --name mongodb -p 27017:27017 -v `pwd`/db:/data/db -d mongo

# stop
docker rm -f mongodb

# shell
docker exec -it mongodb mongo
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker: mysql

terminal
# launch
docker run --name mysqldb -p 3306:3306 -v `pwd`/db:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=p -d mysql

# mysql client
docker exec -it mysqldb mysql -uroot -pp

# stop db
docker rm -f mysqldb
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSのECSでDockerコンテナを起動して、ALBでHTTPのトラフィックを分散してみた。

AWSが提供しているコンテナオーケストレーションサービスを実際に触る機会がありましたので、「Elastic Container Service (ECS)でコンテナを起動し、コンテナへのHTTPトラフィックをApplication Load Balancer(ALB)で分散するまでの一連の流れ」を記事にしてみようと思います。

今回使用するAWSサービス

  • Virtual Private Cloud(VPC)
  • Elastic Compute Cloud(EC2)
  • Elastic Container Registry(ECR)
  • Elastic Container Service(ECS)/Fargate
  • Application Load Balancer(ALB)

概要構成図

まず、作業を始める前に「ECSでコンテナを起動し、ALBでHTTPのトラフィックを分散する」をAWSの構成図で表現してみます。
Qiita_AWS構成図.png

ネットワークの作成&設定

VPCの作成

まずは、AWS上に仮想ネットワーク(VPC)を構築します。
なお、リージョンは米国東部(オハイオ)リージョンを選択しています。 理由は東京リージョンよりもオハイオリージョンのほうがAWS各種サービスの利用料金を安く抑えることができるためです。
Screen Shot 2020-06-27 at 12.25.07 PM.png

インターネットゲートウェイのアタッチ

インターネットからVPC内の各種リソースに接続することを可能にするため、作成したVPCにインターネットゲートウェイをアタッチします。
Screen Shot 2020-06-27 at 12.33.01 PM.png

サブネットの作成

実際にコンテナを実行するサブネットをVPC内に作成します。今回は2つのサブネットをそれぞれ異なるアベイラビリティゾーン(AZ)に作成します。
Screen Shot 2020-06-27 at 12.46.34 PM.png

ルートテーブルの設定

作成したサブネットのルートテーブルにインターネットゲートウェイを追加します。
なお、「0.0.0.0」はデフォルトルートを指します。
Screen Shot 2020-06-27 at 12.56.36 PM.png

作業用インスタンスの作成

EC2インスタンスの起動

構成図には含まれていませんが、Dockerイメージを作成しECRにイメージをプッシュするための作業用インスタンスを起動します。インスタンス起動時は自動割り当てパブリックIPを有効し、セキュリティグループはSSH接続できるようにポート22をインバウンドルールに追加します。
なお、今回はCentOSのイメージからインスタンスを起動します。
Screen Shot 2020-06-27 at 1.35.11 PM.png

各種パッケージのインストール

作成したインスタンスにSSHでログインし、Dockerイメージの作成およびイメージをプッシュするために必要な各種パッケージをインストールします。

【参考】
Install Docker Engine on CentOS - docker docs
Linux で AWS CLI バージョン 2 をインストールする - AWSドキュメント
Dockerコマンドをsudoなしで実行する方法 - Qiita

# unzip, wgetのインストール
$ sudo yum install -y unzip wget

# AWS CLI(Version2)のインストール
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

# Dockerのインストール&起動
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install -y docker-ce docker-ce-cli containerd.io
$ sudo gpasswd -a {ユーザー名} docker
$ sudo systemctl restart docker
$ sudo systemctl enable dokcer

Dockerの再起動まで完了したら、一度サーバーからexitして再度SSHでログインします。

コンテナの実行

Dockerイメージの作成

作業用インスタンスでDockerコンテナのイメージを作成します。
なお、今回は株式会社イーシーキューブ様が提供しているEC-CUBE4のDockerfileからDockerイメージを作成します。

【参考】
ec-cube/Dockerfile at 4.0 - GitHub
Dockerを使用してインストールする - EC-CUBE4.0開発者向けドキュメント

# EC-CUBE4をダウンロード
$ wget https://github.com/EC-CUBE/ec-cube/archive/4.0.zip
$ unzip 4.0.zip

# Dokcerfileの生成
$ cd ec-cube-4.0/
$ docker build -t eccube4 .

# 生成したDockerイメージの確認
$ docker images
  REPOSITORY          TAG                  IMAGE ID            CREATED             SIZE
  eccube4             latest               xxxxxxxxxxxx        ◯ minutes ago       754MB
  php                 7.3-apache-stretch   xxxxxxxxxxxx        ◯ days ago          375MB

ECRのリポジトリにDockerイメージをプッシュ

AWSが提供しているコンテナイメージレジストリのElastic Container Registry(ECR)にEC-CUBEのDokcerイメージを保管するリポジトリを新規作成します。なお、リポジトリ名は作成したEC-CUBEのDockerイメージと同じ名前です。
Screen Shot 2020-06-28 at 5.32.37 PM.png

次に作成したECRのリポジトリにEC-CUBEのDockerイメージをプッシュします。「プッシュコマンドの表示」をクリックし、表示されるコマンドを作業用インスタンスで実行していきます。
Screen Shot 2020-06-28 at 5.45.29 PM.png

# 認証トークンを取得し、作成したレジストリに対してDockerクライアントを認証します。
$ aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin {アカウントID}.dkr.ecr.us-east-2.amazonaws.com

# イメージのタグ付け。
$ docker tag eccube4:latest {アカウントID}.dkr.ecr.us-east-2.amazonaws.com/eccube4:latest

# ECRのリポジトリにDockerイメージをプッシュします。
$ docker push {アカウントID}.dkr.ecr.us-east-2.amazonaws.com/eccube4:latest

なお、Dockerイメージは既に作成済みなのでdocker buildコマンドはスキップしています。

また、認証トークン取得時に以下のようなエラーが表示された場合はaws configureコマンドでアクセスキーとシークレットアクセスキーを登録する必要があります。

# 認証トークンを取得しようとするとcreentialsに関するエラーが表示される。
$ aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin {アカウントID}.dkr.ecr.us-east-2.amazonaws.com
  Unable to locate credentials. You can configure credentials by running "aws configure".
  Error: Cannot perform an interactive login from a non TTY device

# IAMユーザーのアクセスキーとシークレットアクセスキーを登録する。
$ aws configure
  AWS Access Key ID [None]: IAMユーザーのアクセスキーを入力。
  AWS Secret Access Key [None]: IAMユーザーのシークレットアクセスキーを入力。
  Default region name [None]: 今回はオハイオリージョンで作業しているので「us-east-2」と入力。
  Default output format [None]: 空欄のまま。

ECSクラスターの作成

コンテナを実行するECSクラスターを作成します。なお、クラスターテンプレートはAWS Fargateを選択しています。
Screen Shot 2020-07-04 at 10.50.00 PM.png
Screen Shot 2020-07-04 at 10.54.08 PM.png
Screen Shot 2020-07-04 at 10.58.11 PM.png

タスク定義

ECSでコンテナを実行するにはタスクを定義する必要があります。なお、起動タイプはクラスターと同様にAWS Fargateを選択します。
Screen Shot 2020-07-04 at 11.16.12 PM.png
Screen Shot 2020-07-05 at 8.13.54 AM.png

タスク定義の名前を入力し、CPUやメモリのタスクサイズを指定します。
Screen Shot 2020-07-05 at 8.24.12 AM.png
Screen Shot 2020-07-05 at 8.24.24 AM.png

「コンテナの追加」をクリックし、コンテナ名とECRに保管しているDockerイメージのURIを入力します。また、ポートマッピングに80番を追加します。
Screen Shot 2020-07-05 at 8.59.36 AM.png
Screen Shot 2020-07-05 at 9.01.07 AM.png
Screen Shot 2020-07-05 at 9.02.34 AM.png

タスク定義が作成されると以下の画面が表示されます。
Screen Shot 2020-07-05 at 9.07.00 AM.png

ロードバランサーの作成

タスク(コンテナ)に対するHTTPトラフィックを分散するために必要なApplication Load Balancer(ALB)をEC2のコンソールから作成します。
Screen Shot 2020-07-12 at 8.43.38 AM.png
Screen Shot 2020-07-12 at 8.46.01 AM.png

リスナーにはHTTPプロトコルと80番ポートを指定します。
Screen Shot 2020-07-12 at 8.47.57 AM.png

作成したVPCおよびサブネットを指定します。
Screen Shot 2020-07-12 at 8.50.56 AM.png
Screen Shot 2020-07-12 at 8.53.34 AM.png

80番ポートに対するトラフィックを許可するセキュリティグループを設定します。
Screen Shot 2020-07-12 at 8.56.06 AM.png

ルーティングのターゲットグループの設定でIPをダーゲットの種類として選択します。
Screen Shot 2020-07-12 at 9.25.35 AM.png
Screen Shot 2020-07-12 at 9.26.46 AM.png
Screen Shot 2020-07-12 at 9.27.15 AM.png

ロードバランサーが問題なく作成されると以下のような画面が表示されます。
Screen Shot 2020-07-12 at 9.27.37 AM.png

サービスの定義

必要となるタスク数(コンテナ数)を維持するためにサービスを定義します。
Screen Shot 2020-07-12 at 9.39.23 AM.png

起動タイプにFargateを選択し、作成したタスク定義およびクラスターを指定します。
なお、今回はタスク数を3にしています。(同じコンテナが3つ立ち上がります。)
Screen Shot 2020-07-12 at 1.14.31 PM.png
Screen Shot 2020-07-12 at 1.14.46 PM.png
Screen Shot 2020-07-12 at 1.15.30 PM.png

ネットワーク構成の設定で作成したVPCとサブネットを指定します。
また、パブリックIPの自動割り当てを「enabled」にします。
Screen Shot 2020-07-12 at 1.21.47 PM.png

ロードバランシングの設定画面で「Application Load Balancer」を選択し、作成したロードバランサーを指定します。
Screen Shot 2020-07-12 at 1.23.12 PM.png

Screen Shot 2020-07-12 at 1.23.30 PM.png
Screen Shot 2020-07-12 at 1.24.30 PM.png

Screen Shot 2020-07-12 at 1.27.41 PM.png

サービス定義が完了すると以下のような画面が表示されます。
Screen Shot 2020-07-12 at 1.29.37 PM.png

動作確認

コンテナの動作確認

サービスが作成できたら、タスクが起動していることを確認します。
Screen Shot 2020-07-12 at 2.54.40 PM.png

それぞれのタスクに割り振られているパブリックIPにブラウザからアクセスするとEC-CUBEのトップページが表示されます。(今回はわかりやすいようにEC-CUBEのショップ名をコンテナごとに変えています。)
Screen Shot 2020-07-12 at 2.55.29 PM.png
Screen Shot 2020-07-12 at 2.59.28 PM.png

ロードバランサーの動作確認

これらのコンテナはALBによるロードバランシングが適応されているので、ALBに割り当てられているDNS名からでもアクセスすることができます。
Screen Shot 2020-07-12 at 3.07.50 PM.png

画面をリロードすると別のコンテナにHTTPトラフィックが切り替わります。
Screen Shot 2020-07-12 at 3.10.14 PM.png
Screen Shot 2020-07-12 at 3.10.26 PM.png
Screen Shot 2020-07-12 at 3.10.48 PM.png

コンテナのセッション情報について

ここまでの手順で「ECSでコンテナを起動し、ALBでHTTPのトラフィックを分散する」ことができましたが、現時点ではセッション情報がそれぞれのコンテナに保持されている状態のため、ユーザー認証等ができません。EC-CUBEの認証画面でIDとパスワードを入力し「ログイン」を押しても、トラフィックが別のコンテナに振り分けられてしまうため、ユーザー認証を通過することができません。
上記の事象については2つの解決策があります。

ALBのステッキーセッションを有効にする。

ElastiCacheでセッション情報を管理する。

感想

この記事では「ECSでコンテナを起動し、ALBでHTTPのトラフィックを分散する」を実際にやってみました。ECSやALBはAWSコンソールから操作できるため、想像していたよりも簡単にコンテナを起動しトラフィックを分散することができました。特にECSはAWSが提供しているコンテナオーケストレーションサービスということもあり、AWS各種サービスと比較的連携しやすいという印象を受けました。
機会があれば次回はElastic Kubernetes Service(EKS)も触ってみようと思います。

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

[Windows][Docker] nodeコンテナでnpm installがハングアップする件の対策

nodeにgulpやらbabelやらonsen-uiやら大量にインポートしたサーバーアプリケーション。
いままでVagrantで動いていたこの環境を、Dockerコンテナ化するタスクを受けました。
加えてマルチOS(Windows, Mac, Linux)で動作する必要があります。

現状

  • ルートディレクトリに package.json は残っていました。
  • /node_modules はありませんでした。
    (そもそも、違う環境の /node_modules は(環境依存モジュールが有る可能性があるので)流用する気はないですけれども)

package.json をたよりに npm install を実行してみた

  • Mac ... 動いた。
  • Linux ... 動いた。
  • Windows ... 全然動かない。
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx'
... 
npm ERR! Maximum call stack size exceeded
"Failed to load external module @babel/register"

これらのエラーが途中で無秩序に発生します。
上記3種のエラーが出て止まればまだマシな方で、最悪、Docker Desktopがハングアップします。

なおコマンドインターフェース上のプログレス表示の傾向としては、

  • 最初は快速にnpm installが進行していきますが、
  • だんだん遅くなり、
  • やがてハングアップします。

現象の傾向から、メモリリークを大リファクタリングした昔の仕事をなんとなく思い出しました。

トライアンドエラー

ネット上には一見似たような事例が散見されるのですが、

  • npm install --no-bin-links
  • rm -f package-lock.json
  • docker desktopの性能設定を上げる
  • npm cache clean --force
  • .npmignore を作る
  • npm rebuild
  • npm config set registry http://registry.npmjs.org/
  • package.jsonをすべて手書きのnpm installにする

これらを全部やってみましたが、ダメでした。

結果的対処方法

割と泥臭い対応で対応しました。

  1. docker-nodeコンテナのワークディレクトリをdocker-compose.ymlなどでvolumeマウントしておく。
  2. コンテナの中のシェルにログオンする。
  3. /node_modules は絶対削除せずに、何度もnpm installする。(コンテナの外から直接docker-compose execnpm installを実行しない)
  4. インストール済のモジュールは飛ばされるので、徐々に/node_modulesの中身が充足していきます。
  5. 完成した /node_modules を(volumeマウント経由でdockerコンテナから確保し、)/windows_node_modules などとして確保しておく。
  6. ビルドスクリプトを修正し、次回からは npm install を実行させるのではなく、/windows_node_modules を mv windows_node_modules node_modules で済ませるようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】プロフィールに自己紹介機能を実装するシンプルな方法

プロフィールに自己紹介機能を実装する

ポートフォリオ完成後、追加実装したので順序を備忘録として残します。
ユーザー名・email・パスワードなどの既存カラムに、introductionカラムを新たに追加します。
なるべくシンプルに記します!

どうやって?

以下の順序です。

  1. git checkout -b introduction (ブランチ切る)
  2. usersテーブルにintroductionカラムを追加する
  3. データベースに反映させる
  4. usersコントローラーに必要コードの追記
  5. userモデルに必要コードの追記
  6. ユーザー詳細ページ(MYPAGE)に表示させる
  7. ユーザー編集ページ(EDIT)に表示させる
  8. 完成!

以下順番に記します!

1. git checkout -b introduction (ブランチ切る)

新たな機能を実装するため、ブランチを切リます。

2. usersテーブルにintroductionカラムを追加する

ターミナル
$ rails generate migration AddIntroductionToUsers introduction:text
      invoke  active_record
      create    db/migrate/20200712005652_add_introduction_to_users.rb

上記rails gコマンドでintroductionカラムを追加します。

3. データベースに反映させる

ターミナル
$ docker-compose run  web rails db:migrate
== 2020~~~~ AddIntroductionToUsers: migrating ===========================
-- add_column(:users, :introduction, :text)
   -> 0.0518s
== 2020~~~~ AddIntroductionToUsers: migrated (0.0519s) ==================

4. usersコントローラーに必要コードの追記

private methodに追記
introduction属性を付与する

users_controller.rb
   def user_params_update
      params.require(:user).permit(:name, :email, :image, :introduction) # introdution追加
   end

これでintroductionをupdate可能になります

5. userモデルに必要コードの追記

バリデーションを追加します。自己紹介は50文字以内で入力させます。
文字数は自由に設定してください。
※presenseですが、falseにしないと新規登録時に作用してintroductionがnilとなって新規登録できなくなりますので注意してください。新規登録時に自己紹介も入力必要な場合とするならtrueでOKです。

user.rb
validates :introduction, presence: false, length: { maximum: 50 } # 自己紹介の最高文字数は50文字

6. ユーザー詳細ページ(MYPAGE)に表示させる

show.html.slim
 = @user.introduction

SCSSなどで適宜修正してください

7. ユーザー編集ページ(EDIT)に表示させる

ユーザー編集はユーザー名・emailのみでしたがそこにintroductionを追記します。

edit.html.slim
.form-group
  = f.label :introduction
  = f.text_area :introduction, class: 'form-control', id: 'user_introduction'

完成

以上で自己紹介をusersテーブルに追加し、introduction属性を追加完了しました。
途中でintroductionをintroduceと書いていたりしたので、皆様も注意してください!

スクリーンショット 2020-07-12 13.33.19.png

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

初めて使う最低限のDockerコマンド

コンテナの確認

docker ps -a

ekosh@kekosh-mbp python % docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                    PORTS               NAMES
61e626614dac        continuumio/miniconda3   "/bin/bash"              10 hours ago        Exited (0) 10 hours ago                       elated_boyd
1d6cf6b1489b        continuumio/miniconda3   "/bin/bash"              10 hours ago        Exited (0) 10 hours ago                       lucid_pascal
71f13efbdf47        hello-world              "/hello"                 12 hours ago        Exited (0) 12 hours ago                       boring_burnell
d19acf3bb6bb        6b362a9f73eb             "cowsay hello!"          2 months ago        Exited (0) 2 months ago                       competent_hofstadter
b7b8c84c7252        6b362a9f73eb             "hello"                  2 months ago        Created                                       nifty_matsumoto
648b7c18dd75        6b362a9f73eb             "cowsay Hello!"          2 months ago        Exited (0) 2 months ago                       inspiring_bassi
b3e145e1cafe        6b362a9f73eb             "cowsay goodbye!"        2 months ago        Exited (0) 2 months ago                       goofy_thompson
60b883ba5862        6b362a9f73eb             "cowsay Helloclear"      2 months ago        Exited (0) 2 months ago                       epic_solomon
7978c44ef364        6b362a9f73eb             "cowsay Hellodocker …"   2 months ago        Exited (0) 2 months ago   

特定のコンテナを削除

docker rm [Container ID]

kekosh@kekosh-mbp python % docker rm f101ba4df6f0
f101ba4df6f0

一括削除

docker rm $(docker ps -aq)

  • -a : すべてを対象にする
  • -q : 画面にIDのみ表示する。
  • dockerコマンド $(コマンド):カッコ内のコマンド結果を変数としてdockerコマンドを実行する。(ループ処理)
kekosh@kekosh-mbp python % docker rm $(docker ps -aq) 
61e626614dac
1d6cf6b1489b
71f13efbdf47
d19acf3bb6bb
b7b8c84c7252
648b7c18dd75
b3e145e1cafe
60b883ba5862
7978c44ef364
e44c6a002484
0d927b281231
6f0b0267ba22
adbc5e5e443d

取得済みDockerイメージの確認

docker images

kekosh@kekosh-mbp python % docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
python-minicon           init                b9701ee9911d        10 hours ago        429MB
continuumio/miniconda3   latest              b4adc22212f1        4 months ago        429MB
hello-world              latest              fce289e99eb9        18 months ago       1.84kB
kekosh/my_whalesay       ver1                6b362a9f73eb        5 years ago         247MB

imageの削除

docker rmi [imageID]

イメージの削除

イメージを削除するためには先にイメージに紐付いているコンテナを削除する必要がある。

kekosh@kekosh-mbp python % docker rmi b9701ee9911d
Untagged: python-minicon:init
Deleted: sha256:b9701ee9911df562ba01ef99b7dfa4a3b2a3efc4bf9a059931281e5b86d3fa05
Deleted: sha256:79009b24f386f696f524b05869e52a1b0e644fda48683932c418e6b6a96ead4a

dockerイメージのインストール

docker pull [イメージ名]

<サンプル>
kekosh@kekosh-mbp python % docker pull django
Using default tag: latest
latest: Pulling from library/django
75a822cd7888: Pull complete 
e4665cede9d1: Pull complete 
202a45aa091c: Pull complete 
7799136eb561: Pull complete 
7a7f9ca3fd40: Pull complete 
412f2d081014: Pull complete 
Digest: sha256:5bfd3f442952463f5bc97188b7f43cfcd6c2f631a017ee2a6fca3cb8992501e8
Status: Downloaded newer image for django:latest
docker.io/library/django:latest

※イメージを自作しない場合は、「Docker Hub」で探す。
https://hub.docker.com/

イメージからコンテナを作成

docker run [-i -t (オプション)] imageID(またはイメージ名)

<サンプル:Anaconda公式イメージのコンテナを起動>
kekosh@kekosh-mbp python % docker run -i -t continuumio/anaconda3

(base) root@923d9b66994b:/# 
  • 最後に「/bin/bash」を指定してすることで、コンテナ起動直後からターミナルでコンテナ側のbash入力状態になる。(「(base)」の行)
  • 作成するコンテナに別名を付ける場合は、「--name "別名"」を run のあとに付ける。
  • 共有フォルダをマウントする場合は、「-v ホストのマウントフォルダ:コンテナのマウントフォルダ」
  • 共有フォルダをマウントする場合は、事前に docker>Preference>FILE SHARING でマウントするホストレィレクトリを指定する必要がある。
kekosh@kekosh-mbp docker % docker run --name continuumio -v /Users/kekosh/work/docker:/home/continuumio -i -t bdb4a7e92a49 

コンテナとローカルのポートを繋げる場合

Dockerで開発したWebアプリをの動作を確認する場合、ローカルのブラウザから確認できないとどうにもならない。
そのため、コンテナのポートとローカルのポートをつなげる。(つなげるという表現は正しくないけど理解のためにこの表現にする。)

kekosh@kekosh-mbp ~ % docker run --name pyworks -v /Users/kekosh/work/docker:/home -i -t -p 5000:5000 bdb4a7e92a49 /bin/bash
  • -p ローカルのポート:ホストのポート で指定する。
  • ポート番号は両者で異なっても問題ない。

コンテナを起動

docker start [ContainerID]

kekosh@kekosh-mbp ~ % docker start 923d9b66994b
923d9b66994b

#STATUSがUPになっている。
kekosh@kekosh-mbp ~ % docker ps -a
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
923d9b66994b        continuumio/anaconda3   "/bin/bash"         9 hours ago         Up 12 seconds                           zen_ride

この状況ではコンテナが起動しただけでアクセスはできていないので、アクセスしてセッションを作成するコマンドを実行する必要がある。

コンテナにアクセス(ターミナルを接続状態)にする。

docker exec -it [ContainerID] [/bin/bash]

  • /bin/bashの部分は実行したいコマンドに置き換え可能。
kekosh@kekosh-mbp ~ % docker ps -a
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
923d9b66994b        continuumio/anaconda3   "/bin/bash"         9 hours ago         Up 4 minutes                            zen_ride

#コンテナにアクセスする。(-itはとりあえず指定しておく)
#「(base)」という表示がターミナルに出たらコンテナにアクセスできている。
kekosh@kekosh-mbp ~ % docker exec -it 923d9b66994b /bin/bash
(base) root@923d9b66994b:/# 

コンテナの停止

コンテナを停止する。

docker stop [ContainerID]

#起動中のコンテナ(ターゲット)を確認
kekosh@kekosh-mbp ~ % docker ps -a
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
923d9b66994b        continuumio/anaconda3   "/bin/bash"         8 hours ago         Up About a minute                       zen_ride

#コンテナを停止
kekosh@kekosh-mbp ~ % docker stop 923d9b66994b                      
923d9b66994b

#コンテナを停止すると、STATUSが「Exit」になる。
kekosh@kekosh-mbp ~ % docker ps -a
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS                     PORTS               NAMES
923d9b66994b        continuumio/anaconda3   "/bin/bash"         8 hours ago         Exited (0) 2 minutes ago                       zen_ride

コンテナからのログアウト

Ctrl + Q または P
- デタッチと呼ぶ。
- コンソールの例えばpythonから抜ける感覚で「exit」 としてしまうとコンテナ自体が停止(シャットダウン)されてしまうので注意。

-- 追記 --
- Ctrl + D でも同様の結果になる。
- exitで抜けてもコンテナが停止しない。

#ここでCtrl+Qを押下
(base) root@923d9b66994b:/# 

ホスト側フォルダとコンテナのフォルダをマウントする。

コンテナ上の所定ディレクトリに作成したファイルがホスト側にも残る。

docker run -it -v ホスト側マウントディレクトリ:コンテナ側ディレクトリ イメージID 起動時コマンド

kekosh@kekosh-mbp ~ % docker run -it -v /Users/kekosh/work/docker/continuumio:/home/work bdb4a7e92a49 /bin/bash
(base) root@2db318e47b40:/# 

参考
https://qiita.com/Yarimizu14/items/52f4859027165a805630

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