20200808のdockerに関する記事は15件です。

CircleCIでdockerイメージをbuild & pushする

はじめに

githubにてmasterブランチにmergeされたときに、GCPのContainer Registryにimageをpushする

CircleCIセットアップ

  1. CIの実行ファイルを作成
  2. CircleCIの管理画面でプロジェクト追加

1. CIの実行ファイルを作成

ルート直下に.circleciのフォルダを作成して、その中にconfig.ymlのファイルを作成する
(いったん、hello worldするだけ実行ファイル)

version: 2.1
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.5
    steps:
      - checkout
      - run: echo "hello world"

2. CircleCIの管理画面でプロジェクト追加

CircleCIのサイトからgithubログインして対象のリポジトリを追加して完了
そして、hello world確認!

スクリーンショット 2020-08-08 19.40.20.png

config.ymlにdockerイメージビルドする処理を書く

  1. Gcloud連携
  2. dockerイメージをbuild & push
  3. masterブランチへmergeされた時だけ実行する

1. Gcloud連携

公式ドキュメントを参考に進める
https://circleci.com/docs/ja/2.0/google-auth/

ciの実行環境にgcloudのsdkを加える

executors:
  docker:
    - image: google/cloud-sdk

Google Cloud SDK のツールを使用する前に、gcloud を承認する必要があるので、下記手順にしたがってサービスアカウントを作成する
https://cloud.google.com/sdk/docs/authorizing#authorizing_with_a_service_account

CircleCI にキーファイルをプロジェクト環境変数として追加する
https://circleci.com/docs/ja/2.0/env-vars/#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%86%85%E3%81%A7%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B

gcloudを使用してGoogle Cloud SDKを承認する
また、GCRにpushするのでその認証もする

version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
#(workflowsは省略)

実行してみると、承認できていることが確認できた!

スクリーンショット 2020-08-08 20.54.06.png

2. dockerイメージをbuild & push

まずは、CI環境でdockerを使えるようにする
なんとsetup_remote_dockerを追加するだけで完了!

version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
#(workflowsは省略)

https://circleci.com/docs/ja/2.0/building-docker-images/

次に、checkoutしてからdockerイメージをbuild & pushする

version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
      - checkout
      - run:
          name: Docker Build
          command: |
            docker build . -t gcr.io/${GOOGLE_PROJECT_ID}/gcp-rails_sports-rails_backend:${CIRCLE_SHA1}
      - run:
          name: Docker Push
          command: |
            docker push gcr.io/${GOOGLE_PROJECT_ID}/gcp-rails_sports-rails_backend:${CIRCLE_SHA1}
#(workflowsは省略)

build & push できていることを確認!

3. masterブランチへmergeされた時だけ実行する

最後にmasterのときだけcreate_imageのジョブを実行するようにfilterを追加して完成!?

version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
      - checkout
      - run:
          name: Docker Build
          command: |
            docker build . -t gcr.io/${GOOGLE_PROJECT_ID}/#{任意のイメージ名}:${CIRCLE_SHA1}
      - run:
          name: Docker Push
          command: |
            docker push gcr.io/${GOOGLE_PROJECT_ID}/#{任意のイメージ名}:${CIRCLE_SHA1}
workflows:
  build:
    jobs:
      - create_image:
          filters:
            branches:
              only: master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-composeでのvolume作成方法

概要

dockerでのvolumeの作成方法に手こずったので、備忘録です。

よくあるvolume作成方法

docker-compose.yml
version: "3"
services:
  db:
    image: mysql
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql

この記述のみではそのコンテナ自体にvolumeが作成され、データを保存を行うことはできるがデータの永続化はできない。
理由は、コンテナが削除されると一緒にデータも削除されてしまうため。

データを永続化するには

docker-compose.yml
version: "3"
services:
  mysql:
    image: mysql
    volumes:
      - mysql-db:/var/lib/mysql
volumes:
  mysql-db:
    driver: local

これが正しい記述となる。

やっていること

  1. mysqlコンテナにデータを格納するvolumeを作成
  2. そのvolumeを「データを永続化するためだけの役割」であるvolumeコンテナとマウント

実際にvolumeを確認

まずdocker-compose.ymlの設定を反映させる&サーバー起動

$ docker-compose up --build

その後、volumeの一覧を表示してみると

$ docker volume ls
DRIVER              VOLUME NAME
local               b1d0c166382335a52c546e1ea2eaddf752d6f410c4c6664bdc59e9606f4bd25
local               myapp_mysql-db

新たにvolumeが作成できていることを確認できるはずです。

参考にした記事

Docker Composeでボリューム作成

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

Herokuで動かす仮想ブラウジング環境

この記事について

Heroku Container Registry & RuntimenoVNCで、日本語入力可能な一時的なブラウジング環境を作って使う話。

恐らくもう散々同じことが成された領域だと考えられるが、アウトプットとして残しておこうと思う。今回の記事ではブラウジングに限定しているが、制限はありつつ普通にターミナルやWindowManagerも動くので、ちょっとした用途に色々使うことができる。

余談だが、IBM Cloudの無料Liteアカウントで使えるCloud Foundryではdiego_dockerが有効なので、同じことができるか試してみた。結果としては、メモリやディスクの制限が厳しすぎて無理だった。もっと技量があればいろいろ削ったりして、いけるのかもしれない。

背景

様々な事情により、「今すぐ使える仮想デスクトップというか、ブラウザだけ動く環境でいいから、ちょっとだけ欲しい」という感覚になることはないだろうか。

そこで皆大好きHerokuである。誰でも一度は何らかをデプロイして個人で使ったことがあるのではないだろうか。今回はHerokuに、デスクトップというかブラウジング環境をデプロイして使ってみたい。

用語説明

Heroku Container Registry & Runtime

Heroku Container Registry & RuntimeはHerokuでDockerベースのアプリケーションを動かす仕組みで、割と前の2017年10月くらいにGAになったもの。Dockerfileを書いてheroku container:pushheroku container:releaseすることでアプリケーションをデプロイできる。イメージに特定のタグをつけてdocker pushでも可能。

なお、コンテナ内でのアプリケーション実行ユーザはuXXXXXで、コンテナ内部のファイルの所有者も/etc/shadowだとか一部を除いてuXXXXXのユーザになる。

noVNC

noVNCは、ブラウザをクライアントにしてVNCを使うことができるもの。HTML5を使って作られていて、通信はWebSocketで行われ、websockifyで後ろにたっているVNCサーバとの仲介をする。

クライアントはブラウザさえあればいい、というのが簡単で良い。

今回つくったもの

上記のHeroku Container Registry & RuntimeでnoVNCとブラウザの入ったコンテナを入れて動かした。ソースはここ (https://github.com/qb0C80aE/ghostship) で、Herokuのアカウントを持っていてDockerとHeroku CLIがあれば、恐らく10分もかからずデプロイできる。

構成物は簡単なDockerfile、エントリポイントにするシェルスクリプト、あとは後述する日本語を打つための設定をあらかじめいれた.configディレクトリだけである。

また、README.mdにも書いたとおり、偉大なるGitHub ActionsはDockerとHeroku CLIをサポートしているため、GitHubのアカウントを持っていればローカルにDockerとHeroku CLIをインストールする必要もなかったりする。

Screenshot

このスクリーンショットでは、外枠のブラウザがローカルで、内側のブラウザはHeroku上のものをVNCで操作しているものである。

偉大なプラットフォームとソフトウェア

正直、このリポジトリではすごい事はなにひとつしていない。
すごいのはこれを実現してくれるHerokuとソフトウェア群である。

HerokuもnoVNCも本当にすごい。いつもお世話になっているし、足を向けて寝ることは決して出来ない。

なお、特に何かにログインとかせずに外とデータの受け渡しがしたいときは、piping-serverという偉大なOSSを使ったりすることで実現できる。

ちょっとした工夫

ところで、皆大好きHerokuのfree dynoは、執筆時点ではたしか30分アクセスがない状態が続くと自動的にダウンする仕様になっている。
dynoのログを見るとわかるが、noVNCで繋いでいる間は、reconnect&autoconnectしていても、再接続時にHTTPアクセスがあったという動きにはならない。
このままでは環境の利用中にdynoがダウンするため、noVNCのvnc.htmlにすこし工夫をして、KeepAliveをいれている。

具体的には、Dockerfileに以下のような適当なパッチをいれた。

...
  sed -i "s/<\/head>/    <script>\n        var skeepalive = function() {fetch(window.location.protocol + '\/\/' + window.location.host, {cache: 'no-cache'});};\n        setInterval(skeepalive, 300000);\n    <\/script>\n<\/head>/g" /opt/noVNC-master/vnc.html && \
  sed -i "s/<\/head>/    <script>\n        var skeepalive = function() {fetch(window.location.protocol + '\/\/' + window.location.host, {cache: 'no-cache'});};\n        setInterval(skeepalive, 300000);\n    <\/script>\n<\/head>/g" /opt/noVNC-master/vnc_lite.html && \
...

これで、環境をブラウザで開いている間だけ、このdynoは生きることができる。
そして元々の仕様のとおり、ブラウザを閉じてしばらく経過するとダウンする。

欲しい間だけ環境に生きていてほしいので、このように勝手にダウンしてくれるのは逆に都合が良かったりもするが、それとは別にいつも助けてもらっているHerokuにはお布施を奉納することにする。

なお仕様上、一日一回dynoが再起動するのは運命なのでしかたない。一時的なブラウジング環境なので、割り切りが重要であり、この環境では決して重要な仕事をしないことが肝心である。

日本語変換

ややもすると、検索では日本語を打ちたくなるので、日本語変換ができてほしい。
そこで、fcitxをいれて、Ctrl+Spaceで日本語変換ができるようにした。
技量が足りずmozcを動かすことができなかったので、anthyを使うことにした。

制限

TwitterはEC2のIPアドレスを弾いているのか、閲覧不能になることが大半である。どこかのproxyを設定するなりすれば閲覧可能になるので、どうしてもこの上でTwitterが見たい人は設定してみてほしい。

なお、スレッド数上限が256とか色々制限があるので、沢山タブを開きすぎたり、色々な条件でダウンすることもよくあるが、気にしないことにする。

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

Laravel×Docker×Dusk×Seleniumでのテスト実行

はじめに

インターン現場でLaravelを使用しており、テスト環境の構築を行いました。

テストツールとしてDuskを使用し、seleniumとの連携という構成をとり、導入で何度かつまづいたので自分メモとして残したいと思います。

Duskって?

-ドキュメント
Laravelが標準で用意している、ブラウザの自動操作によるテストAPI。
テスト中はブラウザが勝手に動くのを眺めながらのんびりできます(笑)

Duskは「$php artisan dusk:install」でコマンドインストール後、すぐに使えます。
しかし今回は現場の意向でデフォルトのChromeDriverの使用ではなくseleniumを使用することになりました。

目標

--開発環境---
  • Laravel 6.18.26
  • Docker(Docker-compose) 19.03.8

docker環境でDusk × seleniumでテストを実行することを目標とします。
開発環境でdockerを使用していたので、selenium用のコンテナを準備するところからはじめました。

以下、順にまとめていきます

1.seleniumのコンテナを準備

selenium用のコンテナを定義するために、docker-compose.ymlに以下を追記。

docker-compose.yml
selenium:
    image: selenium/standalone-chrome-debug
    ports:
      - 4444:4444
      - 5900:5900
    container_name: selenium-container
    depends_on:
      - nginx
    privileged: true

ポートを2つ開放してますが、

4444 ⇨ selenium serverのポート
5900 ⇨ VNCのポート

です。
[参考]VNCについて

2.コンテナ起動

terminal

$ docker-compose up

...

Creating mysql-container      ... done
Creating phpmyadmin-container      ... done
Creating php-fpm-container         ... done
Creating nginx-container           ... done
Creating selenium-container        ... done

seleniumのコンテナが無事立ち上がりました。
php-fpmのコンテナ中に入ります。

terminal
$ docker exec -it php-fpm-container bash

3.Duskのインストール

ほぼ公式の引用です。
以下のコマンドはコンテナ中で行ってください!

terminal(コンテナ内)
# 共存パッケージのインストール
$ composer require --dev laravel/dusk

# dusk install
$ php artisan dusk:install

dockerを起動するとselenium portとVNCポートが開放されます。

4.seleniumの接続(:4444)

デフォルトのChromeDriveではなくseleniumを使用する場合、tests/DuskTestCase.phpを書き換える必要があります。

DuskTastCase.php
#driverメソッドを以下に書き換え

protected function driver()
    {
        return RemoteWebDriver::create(
            'http://selenium:4444/wd/hub', DesiredCapabilities::chrome()
        );
    }

ここで、docker-compose.ymlで定義した4444portが登場します!

5.VNCの接続(:5900)

今度はVNCに接続を行います。
macのfinderからlocalhost:5900に接続します。

スクリーンショット 2020-07-31 20.17.43.png

↓dockerが起動していればこんな感じでseleniumの画面が表示されました!!
スクリーンショット 2020-07-31 20.18.30.png

6.テストの実行

以下の簡単なログインテストを実行してみました。

LoginTest.php
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;


class LoginTest extends DuskTestCase
{
    /**
     * A Dusk test example.
     *
     * @return void
     */
    public function test_02_PassReset(){

        // login test
        $this->browse(function (Browser $browser) {
            // ページ"/login"で文字列"LARAVEL"を確認
            $browser->visit('login')
                    ->assertSee('LARAVEL');
        }); 
    } 
}

こちらのテストを実行。

スクリーンショット 2020-07-31 22.53.20.png

↑テスト実行時のキャプチャです。きちんとテストブラウザが動いて/loginにアクセスできています!

terminal
$ php artisan dusk
PHPUnit 8.5.8 by Sebastian Bergmann and contributors.

..                                                2 / 2 (100%)

Time: 4.4 seconds, Memory: 18.00 MB

OK (2 tests, 2 assertions)

テスト結果も◎でした!!!

まとめ

ブラウザテスト自体が初めてだったので、単純に楽しかったです!
時間があればselenium関連でスクレイピングとかにも挑戦したい!!!

※誤りや質問等ございましたらコメント頂けますと幸いです。

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

Dockerで作る、環境整備 (PythonでのGrADSの後処理をしたい

何をしたいのか?

  • PythonでGrADS用のファイルを読み込んで後処理をしたい
  • しかし共有計算資源の環境はクリーンでなければならない
  • だがしかし、変換ソフト、ライブラリなどなどインストールしたいものがいっぱいある

ということで、コンテナ仮想化を使おうということです。

Docker

Dockerを使うと何がいいかというと、計算資源を汚すことなく、必要な後処理を行う専用の仮想計算機を作り上げることができます。使うときにコンテナを立ち上げ、処理を行った後は破棄してまた必要になったら立ち上げることができます。
Dockerの場合は立ち上げのコストが非常に低いので、気軽に立ち上げて一つの処理をした後また破棄することが気軽にできます。

環境整備手順

Dockerfileを書くと自動化できていいのですが、ここでは単にシェルを立ち上げて整備して、それを単純にコミットしてイメージを作ることにします。
長期的に使いたいなら、バージョンアップも可能になるようにDockerfileを作るべきですが、最初の基本の機能の確認はシェルで行ったほうが理解が深まります。

今回はUbuntuをもとに、cdoとpip3, netcdf4をインストールします。

1. もとになるイメージをpull(拾ってくる)して走らせる

今回はUbuntuを使います。

$ docker pull ubuntu/ubuntu
$ docker images

で、イメージが作れたことが確認できます。

イメージを走らせるためには、

$ docker run -it ubuntu/ubuntu

とします。

2. 必要なソフトウェアのインストール

pip3cdoをインストールします。
pip3netCDF4もインストールします。

# apt update
# apt install python3 python3-pip cdo
# pip3 install netCDF4

3. 動作確認

きちんとcdoで変換できてnetCDF4もインポートできるか確認します。

# python3
>>> import netCDF4 as nc
>>> ^D
# cdo
....

4. コミットしてimageを作成する

exitコマンドかCtrl+dで抜けて、イメージを作りましょう。
イメージを作るために必要なコンテナIDは、終了したコンテナを確認するために-aが必要です。

# exit
(host) $ docker ps -a

このような画面になると思います。
CONTAINER IDはコミットの時に指定するコンテナIDになります。
IMAGEのところにimageの名前があって、STATUSのところでexited ** agoとなっているので、大体どれかはそこを見ればわかると思います。
image.png

$ docker commit [container id] [author]/[image名]

というようにコミットしてあげましょう。

$ docker images

で、イメージが作れたことが確認できます。

5. 実際に計算させてみる

実際に計算させるとき、2通りあって、runしてからインタラクティブにシェルから実行することもできます。ただ、今回はrunの際にコマンドを指定して実行させてみます。

プログラム、データ群のディレクトリをDockerへとバインドすることで、実際にコンテナから容易にアクセスることができます。また、グラフの確認にXフォワーディングをします。

$ sudo docker run -e DISPLAY=$DISPLAY --net host -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/root/.Xauthority -v /home/xxx/:/home/ --shm-size 16g xxx/ubuntu-cdo2 /bin/bash -c "cd /home/speedy-epyc/speedy/python-script; python3 rmse.py"

--shm-sizeは、足りなくなるプログラムがあれば必要に応じてつけてください。

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

dockerコマンド実行時に出たエラー

dockerのimageを作成しようとしたら以下のエラー発生

$ docker-compose build
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

ググって見つけた記事には権限を変更しろとあるので以下を実行(ec2等の場合はexitしてから再起動)
$ sudo usermod -aG docker $USER
$ sudo chmod +x /usr/local/bin/docker-compose

しかし、エラーは変化せず。。。
試しに以下のコマンドを実行するとrunningになっていなかった。
$ sudo service docker status

dockerをスタートさせたら無事にコマンドが通るようになった。
$ sudo service docker start

エラー出たらまずstatus確認するの大事ですね!

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

docker-compose upでDBが立ち上がらない「Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)」への対処法

dockerで環境構築をし、サーバーを起動しようとdocker-compose upをすると
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)というエラーが出てしまう。

ターミナルにて、エラーログを確認すると
image.png
何かが原因でDBがシャットダウンしてしまっている模様。

privilege tablesなのでsudoで作成するユーザのテーブル?
なぜdockerでこの内容のエラーが出る?
と色々疑問に思ったが、とりあえず一度全てのvolumeを削除してみることに。

解決策

①volumeのIDを調べる

$ docker volume ls
DRIVER              VOLUME NAME
local               b1d0c8467782387a61c446e1ea2aedaa745d6f120c4c6423bdc37e9005a7bd34

②上記で調べたVOLUME NAMEを用い、rmコマンドにてvolumeを削除

$ docker volume rm [VOLUME NAME]
# 例↓
$ docker volume rm b1d0c8467782387a61c446e1ea2aedaa745d6f120c4c6423bdc37e9005a7bd34

docker-compose.ymlを元に、コンテナ&サーバー再起動

$ docker-compose up --build
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

④localhost:3000にアクセス
無事エラーなく起動

原因

mysqlのテーブル情報が保存される場所がvolumeなのでコンテナを削除した際にvolumeコンテナを削除しきれておらず、前回のmysqlの情報が中途半端に残っていたため、権限不足となっていたみたいです。

これ以前に何回もコンテナを作って削除して、を繰り返して試行錯誤していたため、その時の残骸でしょう...

参考にした記事

docker-compose up で db が立ち上がらない時は volume を削除してみる

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

docker-compose upでDBが立ち上がらないときにやったこと

dockerで環境構築をし、サーバーを起動しようとdocker-compose upをすると
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)というエラーが出てしまう。

ターミナルにて、エラーログを確認すると
image.png
何かが原因でDBがシャットダウンしてしまっている模様。

privilege tablesなのでsudoで作成するユーザのテーブル?
なぜdockerでこの内容のエラーが出る?
と色々疑問に思ったが、とりあえず一度全てのvolumeを削除してみることに。

解決策

①volumeのIDを調べる

$ docker volume ls
DRIVER              VOLUME NAME
local               b1d0c8467782387a61c446e1ea2aedaa745d6f120c4c6423bdc37e9005a7bd34

②上記で調べたVOLUME NAMEを用い、rmコマンドにてvolumeを削除

$ docker volume rm [VOLUME NAME]
# 例↓
$ docker volume rm b1d0c8467782387a61c446e1ea2aedaa745d6f120c4c6423bdc37e9005a7bd34

docker-compose.ymlを元に、コンテナ&サーバー再起動

$ docker-compose up --build
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

④localhost:3000にアクセス
無事エラーなく起動

原因

mysqlのテーブル情報が保存される場所がvolumeなのでコンテナを削除した際にvolumeコンテナを削除しきれておらず、前回のmysqlの情報が中途半端に残っていたため、権限不足となっていたみたいです。

これ以前に何回もコンテナを作って削除して、を繰り返して試行錯誤していたため、その時の残骸でしょう...

参考にした記事

docker-compose up で db が立ち上がらない時は volume を削除してみる

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

Docker + Rails6 + Postgresql の開発環境を構築する

前提

Rails環境を構築していないチームメンバーも環境構築に手間をかけずにローカルで簡単にプロジェクトを動かせるようにとDockerを導入しました。私自身はローカルにRails環境を構築しているため、プロジェクト作成はローカルで行い、Dockerとローカル直のいずれも動作できるようにしました。
Dockerはすでにインストールされているものとします。

環境

  • macOS Catalina 10.15.4
  • Ruby 2.7.1
  • Rails 6.0.3.2
  • PostgreSQL 12.3
  • Docker version 19.03.12

プロジェクト新規作成

$ mkdir myapp; cd $_
$ rails new . --skip-coffee --skip-turbolinks --database=postgresql

環境変数を管理するdotenv-railsを導入

環境変数によって、Dockerで動かすかローカル直で動かすか選べるようにします。

Gemfile
gem 'dotenv-rails'

gemをインストール

$ bundle install

下記はDockeで動かす場合の環境変数の設定例です。

.env
DATABASE_HOST=db
DATABASE_USER=postgres
DATABASE_PASSWORD=secret

ローカル直で動かす場合はDATABASE_HOST=localhostとします。

Docker用ファイル作成・編集

docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    ports:
      - "5433:5432"
    environment:
      POSTGRES_USER: 'postgres'
      POSTGRES_PASSWORD: 'secret'
      POSTGRES_DB: 'db'

  webpacker:
    build: .
    command: bundle exec bin/webpack-dev-server
    volumes:
      - .:/myapp
    ports:
      - "8080:8080"

  web:
    build: .
    command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
      - webpacker

dockerfile
FROM ruby:2.7.1

ENV LANG C.UTF-8

# 必要なライブラリをインストール
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

# yarnパッケージ管理ツールインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
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 && \
apt-get update && apt-get install -y yarn

# ワークディレクトリ設定
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
EXPOSE  3000

database.ymlhostusernamepasswrdの設定を追加

/config/database.yml
: 省略

default: &default
  adapter: postgresql
  encoding: unicode
  host: <%= ENV.fetch("DATABASE_HOST") { "127.0.0.1" } %>               # 追記
  username: <%= ENV.fetch("DATABASE_USER") { "postgres" } %>            # 追記
  password: <%= ENV.fetch("DATABASE_PASSWORD") { "" } %>                # 追記
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

: 省略

image構築

$ docker-compose build

パッケージインストール

$ docker-compose run --rm web bin/yarn install

データベース作成

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

起動

$ docker-compose up

http://localhost:3000/ へアクセスできます。

ローカル直で動かす場合

.envを編集し、yarn installrails db:createrails sで起動します。

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

転職活動のためのデータ取得コード - Linkedin編

はじめに

こんにちは、今日はLinkedinのAPIを使用することで、友達の友達の友達までのプロフィール情報を取得するコードを紹介したいと思います。
このコードを使用することで、気になるあの企業では、どのくらいの人が退職しているのか、退職した人はどんな人なのか、平均勤続年数、転職先はどういう企業が多いのかを定量的に分析するためのデータが取得できます。(特にベンチャー企業とかはなかなか内部の情報が分からないのでベンチャー転職の役に立つ予感がしています。)
しかも、LinkedinのAPIは自身のアカウントさえ持っていれば、基本的には何の登録も必要とせず叩けるので、お手軽に試すことができます。
ただし、以下の注意点があります。

  • 友人検索は無料アカウントだと、回数制限があるので無駄に検索しないことをおススメします。有料アカウントになればいくらでも検索かけられます
  • 友達数が少ないと、気になる企業の関係者の情報が取得できない可能性が高いです。その場合はエージェントとか業界のリーダーみたいな人と繋がると良きかと思います。

では、早速友達の友達の友達のプロフィール情報を取得するコードを作っていきたいと思います。
今回は、docker上で動くように作成したので、多くの人の環境で動くものになっています。
是非動かせるところまで作ってみて、転職活動のための情報収集に役立てて頂ければ嬉しいです。

一応docker初心者の方にもわかる形で記載しているので、dockerの勉強にもなるかもしれません。

フォルダ構成

ローカル環境に適当にlinkedinみたいなフォルダを作成して、以下のフォルダ構成を作成してもらえればと思います。
(余談ですが、フォルダ構成を書く際はこの記事が役に立ちます)

linkedin/
 ├ input/
    ├ company.csv
 ├ output/
 ├ script/
    ├ api.py
 ├ .dockerignore
 ├ docker-compose.yml
 ├ Dockerfile
  • input: 調査したい企業名を入力したcsvファイルを入れておきます。csvファイルは以下のような形式で作成します。
    • 会社名というカラムに対して、その下に気になる企業を色々入れることができます。
会社名
Preferred Networks
PKSHA Technology
  • output: 調査したい企業に関係している方のプロフィール情報がjson形式で出力されます。
  • script: linkedinからデータを引っ張ってきて、outputにデータを格納するコードが記載されています。

dockerの設定

dockerをご存知ない方は以下のサイトとか見てみてください。簡単に言うと、PC内に仮想環境をお手軽に作ることができ、その仮想環境でごちゃごちゃやって、仮想環境をぶっ壊しても問題ないよという技術です。
- Dockerでデータ分析環境を手軽に作る方法

dockerとdocker-composeをインストールしていない方は、window系とmacとかlinuc系はインストール方法が異なるので、適切なインストール方法を行ってください。

今回は、docker-composeを使うことで、linkedinのフォルダに移動して、以下のコマンドを打ち込めば、お手軽にデータ取得ができるようにdockerの設定を行います。

docker-compose up

DockerFile

以下のような内容をファイルの中に記述していきます。
- どういうイメージを使ってインストールするのか
- どんなライブラリを追加で入れておくのか
- イメージにローカル環境のどんなファイルを持ってくるのか
- dockerの起動と共にどのpythonファイルを実行するのか

今回はanaconda環境の上にlinkedinのAPIとかを追加でインストールします。
linkedinのAPIにはこのリポジトリが一番使いやすそうだったので、こちらをもとにコードを作成します。

docker.compose.yml
# anacondaの開発環境をベースにする
FROM continuumio/anaconda3:latest

# ライブラリの追加インストール
RUN pip install -U pip && \
    pip install linkedin-api~=2.0.0a

# docker環境内でフォルダ移動を行い、ローカルファイルを移動先のフォルダにコピーする
WORKDIR /tmp/working
COPY ./ ./

# api.pyを実行する
CMD ["python", "-u", "./script/api.py"]

docker-compose.yml

お手軽実行できるようにするために、docker-compose.ymlを作成していきます。
このファイル内では、マウントするディレクトリがどこかも記載します。
(マウントによってdocker上の特定のフォルダとローカル上の特定のフォルダを同期することができます。これによりdocker上で作成したファイルをローカル環境で取得できるようになります。)

docker-compose.yml
version: "3"
services:
  app:
    build: .
    # ローカル環境の現在のディレクトリとdocker環境上の/tmp/workingを同期する
    volumes:
      - ./:/tmp/working

.dockerignore

このファイルはさほど重要ではないのですが、Dockerfileをビルドする際に除去するファイルを記述でき、重いファイルで不必要なものを入れているとビルドが遅くなるそうなので、outputとかinputとかを中に記述します。

input
output
script

上記の操作でdocker関係の設定は終了です。
後は、api.pyを記述し、実際にデータを持ってくる処理を書きます。

データ取得処理

特段難しいことを行っているわけではないのですが、基本的には以下の処理を行っていきます。

  • inputフォルダにある企業リストのcsvファイルを読み込んでくる
  • 企業リストをもとにlinkedinから関係者のデータを取得してくる
  • outputフォルダに関係者のプロフィール情報をjson形式で吐き出す

linkedinAPIの認証だけお忘れなくいただければと思います。

api.py
# coding: utf-8

import os
import json
import logging
import pandas as pd

from linkedin_api import Linkedin

def main():
    # get company list
    df_company = pd.read_csv('./input/company.csv')

    # Authenticate using any Linkedin account credentials
    api = Linkedin('linkedinに登録しているメールアドレス', 'linkedinのログインパスワード')

    for company_name in df_company['会社名']:
        # retry processing
        for _ in range(3):
            try:
                logging.info(f'start to {company_name}')
                person_ids = get_people_ids(api, company_name)
                logging.info(f'number of person_id :{len(person_ids)}')
                profiles = list(get_person_profile(api, person_ids))
                output_profile_data(company_name, profiles)
                logging.info(f'success to output')
            except:
                logging.info(f'retry to {company_name} :{_}_times')
            else:
                break

def get_people_ids(api, company):
    '''get people ids in a company
    '''
    network_depth_list = ['F', 'S', 'O']

    results = []
    for network_depth in network_depth_list:
        result = api.search_people(
          keywords=company,
          network_depth=network_depth
        )
        results.extend(result)
    return results

def get_person_profile(api, ids):
    '''get person profile information about career
    '''
    for person_id in ids:
        profile = api.get_profile(person_id['public_id'])
        yield profile

def output_profile_data(company, data):
    '''output profile data to output folder
    '''
    os.makedirs(f'./output/{company}', exist_ok=True)
    for d in data:
        name = d['lastName'] + d['firstName']
        with open(f'./output/{company}/{name}.json', 'w') as f:
            json.dump(d, f, indent=4)

if __name__ == '__main__':
    main()

これで準備は完了です。
では、早速実行してみましょう。

実行

ターミナルかコマンドプロンプト上でlinkedinフォルダに移動し、以下のコマンドを打って下さい。
このコマンドを打つことで、docker-compose.ymlの中身を読み取って、dockerを起動してくれます。

docker-compose up

すると、実行にそこそこ時間がかかりますが、データの取得が開始されるかと思います。

僕は少し異なる設定でやっているのですが、以下のような結果が出てきました。person_idは該当者数を表しています。
sample.JPG

データを取得後は、お好きなようにデータを調理するだけです。ここの調理方法は色々あると思いますが、私がどんな分析をしたのか別記事で紹介しようかなと考えています。

まとめ

この記事では、docker環境上でLinkedinのAPIを叩くコードを作成し紹介しました。
この記事が転職を考えている人の情報収集やdockerの学習に役立てば幸いです。

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

【学習メモ】Docker(Docker運用の流れ、Linux操作、コマンド操作の基本)

なぜDockerを採用するのか?

コンテナ1つ作れば、テスト環境・本番環境もコンテナ起動でOKになるから

Dockerなしの場合
1回1回、テスト・開発・本番環境ごとにインストーラをダウンロード、起動、エラー修正しなきゃいけない

しかもチーム開発だと、全く同じバージョンの同じアプリで同じ挙動をしないといけないため大変

Linuxについて

・Linuxのコンテナ技術を利用するので、Linuxの知識が必要
・Linux:Unixをベースに1から作ったオープンソースのOS
・ターミナルでは、Shellを仲介してKernelに命令を出している
・Shell:bazh,zsh,shなど
・Shellを起動するために必要なアプリがターミナルであって、Shell=ターミナルではない

Dockerを使ってみる

運用の流れ
・Docker imageを管理するDockerHubから自分のhostに、Docker imageを持ってくる
・Docker imageをbashでコンテナ起動
・コンテナでの作業が終わったらexitかdetach
・Hostに戻ったときに、現在のコンテナの状況をps-a、imagesで確認
・exit状態にあるコンテナを再起動
・コンテナをcommitして新しいimageを作成する(=更新内容をDocker imageにする)
・DockerHubにアップする際、リポジトリ名と一致する必要があるので、古いimageを新しいimage名に変更する
・その後保存したDocker imageをDockerHubにpushする
※タグ=バージョン管理

コマンド操作の例

$ docker login                     #Dockerにログイン
$ docker pull <image>              #DockerHubからDocker imageを出力
$ docker run -it <image> bash      #bashはshell。そのDocker imageでコンテナ起動
$ exit                             #コンテナでの作業を終了
$ docker ps-a                    #Dockerコンテナ一覧を確認
$ docker images                #Docker images一覧を確認
$ docker restart                 #Dockerを再起動
$ docker exec -it <container> bash #特定のコンテナで作業開始
$ docker commit <container><image>  #特定のコンテナの変更をDocker imageに反映
$ docker tag <source> <target>     #Docker imageの名前を変更
$ docker push <image>              #Docker imageをリポジトリにpush
$ docker rmi <image>               #Docker imageを削除

参考

米国AI開発者がゼロから教えるDocker講座

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

Django3チュートリアル準備

Django3の環境構築をdockerで行う

環境構築

Django3.0の開発環境をDocker,Docker-compose,Poetryで作ってみた
上記の記事がシンプルで分かりやすかったので、参考にしました。
私の環境では下記のディレクトリー 構造となりました。
Makefileは私が作成したものです。
記事の最後に載せてあります。

.
├── Dockerfile
├── docker-compose.yml
├── Makefile
└── src
    ├── manage.py
    ├── project
    ├── pyproject.toml
    └── poetry.lock

git管理する

//git config でユーザー名と設定
git config --global user.email "xxx.yyy@example"
git config --global user.name "password"

//git hubでリポジトリの作成後リモートリポジトリの追加をします。
git remote add origin [remote repository PATH]

//git pullを実行し設定終了
git pull

.gitignore 作成

Djangoについて全くと言っていいほど理解しておらず【gitignore】に追加すべきファイルがわからなったので、gitignore.ioで作成
https://www.toptal.com/developers/gitignore

Makefile作成

dockerコマンドは長いので打つのが面倒なので、Makefileに記述しています。

up:
    docker-compose up -d

build:
    docker-compose build --no-cache --force-rm

stop:
    docker-compose stop
down:
    docker-compose down

restart:
    @make down
    @make up

destroy:
    docker-compose down --rmi all --volumes

django:
    docker exec -it django3_django_1 bash

参考にさせていただいた記事

Django3.0の開発環境をDocker,Docker-compose,Poetryで作ってみた
#django 用の .gitignore を一瞬で自動生成する

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

Docker で CPU 使用率 100% のコンテナを軽減・回避する

foreach ループを使い Server-Sent Events を監視している Docker コンテナがあります。
コンテナを起動して、しばらくするとマシンが「フォーーっ」と唸り始めたので、 docker stats コマンドで確認すると CPU 使用率が 100% を超えていました。どうしよう

Qiita 記事に絞って「Docker CPU 使用率 100% コンテナ 軽減」でググってもヒットしなかったので、自分のググラビリティとして。

TL; DR

for/foreach/while ループ内の処理の最後に支障をきたさない範囲で sleep を入れる。0.5 秒入れるだけでも劇的に変わる。

その上で Docker もしくは docker-compose の設定で最大使用率に制限をかけるのがベター。

TS; DR

強制的に制限する(docker 編)

もともと Docker にはコンテナごとに CPU の最大使用率を制限するオプション --cpus があります。これは、コンテナに対し使用する CPU の個数を指定でき、リソースを分配することができます。

例えば4コア CPU の場合、以下は使用率を最大 50% に制限できます。

2つぶんのCPUを割り当てる(2/4=0.5=50%)
docker run -it --cpus="2" ubuntu /bin/bash

最大 80% に制限したい場合は以下。

3.2個ぶんのCPUを割り当てる(3.2/4=0.8=80%)
docker run -it --cpus="3.2" ubuntu /bin/bash

強制的に制限する(docker-compose 編)

docker-compose で制限したい場合は、deploy ディレクティブで cpus を指定します。

docker-compose.yml
version: '3.8'

services:
  my-service:
    container_name: my-cont1
    build: .
    deploy:
      resources:
        limits:
          cpus: "1"

注意点として、deploy の項目は基本的に Docker Swarm 用の設定であるため、docker-compose では無視されてしまいます。docker-compose up コマンド実行時に --compatibility オプションをつけると、docker-compose 互換で動作します。

compatibilityオプションを付けないとdeployの内容は有効にならない
docker-compose --compatibility up

しかし、これは制限をかけるだけです。そもそも、抜本的に CPU の使用率を下げない限り、リソースは制限値まで無駄に消費されることになります。おそらく、Docker の問題ではなく、プログラムの組み方に問題があるのは容易に想像できます。

プログラムを見直す

Server-Sent Events のメッセージを受信するために SSL 接続のソケットからデータを読み込み、処理を行うループ箇所が臭います。

どうやら、データが流れてこない間は処理を行わないため、空ループが発生してしまうのが原因のようです。つまり、何も処理しない最速のループが実行されているわけで、「そりゃ CPU 使用率 100% になるわ」と納得しました。

そこで、PHP の「ループ処理を行った際の CPU の負荷」や .NET の「CPU使用率100%を回避する方法」を参考に、試しに1秒間の sleep をループの最後に入れてみました。

これが、効果的てきめん! 100〜110% であった使用率が 0.00〜0.01% をウロチョロする程度にまで押さえ込めました。0.5 秒でも 0.01〜0.03% 程度でした。

以上から、まずはループ箇所を見直し、ループの支障を来さない範囲で sleep を入れるのは効果的だと思います。その上で、保険として dockerdocker-composecpus で最大値を制限するのがベターだと思われます。

参考文献

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

ローカルにdockerを使ってHTTPS環境を立ち上げるスニペット

皆さん良いWEBライフ送れていますか?
今回はいつも困るローカルでのSSL環境構築です。

内容を見ていただけたらわかりますが、基本mkcertに頼りっぱなしになっています。一度mkcertで設定してしまえば、opensslコマンドで証明書を作る際に面倒なオレオレ認証局署名やSSL証明書自体のインストールの手間が省けるので、今の所採用しています。

目次

  1. コード全貌
    1. ファイル構成
    2. docker-compose.yml
    3. ssl.conf
  2. 手順
  3. 解説
    1. docker-compose.yml
    2. ssl.conf
  4. まとめ

1. コード全般

1-1. ファイル構成

project-root:
    - docker-compose.yml
    docker:
        - ssl.conf
        ssl:
            - example.com-key.pem
            - example.com.pem
    public:
        - index.html

1-2. docker-compose.yml

version: '3'
services:
  web:
    image: nginx:latest
    container_name: 'ssl_web'
    ports:
      - '4430:443'
    volumes:
      - ./docker/ssl:/etc/nginx/ssl
      - ./docker/ssl.conf:/etc/nginx/conf.d/default.conf
      - ./public:/var/www/html

1-3 ssl.conf

server {
  listen              443 ssl;
  server_name         localhost;
  root                /var/www/html;
  index               index.html;
  ssl_certificate     /etc/nginx/ssl/example.com.pem;     # SSL証明書
  ssl_certificate_key /etc/nginx/ssl/example.com-key.pem; # 秘密鍵
}

※ 証明書のファイル名は適宜変更してください

2. 手順

brew install mkcert
mkcert -install
cd project-root/docker/ssl
# ここで証明書ファイルを作っています。
mkcert example.com
cd ../../
docker-compose up -d

アクセス方法

  • PCの場合: https://127.0.0.1:4330
  • スマホの場合: https://{ifconfigなどで表示されたローカルIP}:4330

※ localhostだとdockerがうまく解釈できないのでIP指定にしています。

3. 解説

3-1. docker-compose.yml

image: nginx:latest

confがnginxのフォーマットなのでnginxにしていますが、confさえWEBサーバーにあったものを書ければapacheでも動くと思います。

ports:
  - '4430:443'

自分でも理解しきれていませんがハマったポイントです。
443:443といったlocalhostの443ポートをdockerの443ポートに繋げる記述でも動くと思っていましたが、4430:443とlocalhost側のポートは通常のSSLポートと変えてあげる必要があるようです。

volumes:
  - ./docker/ssl:/etc/nginx/ssl
  - ./docker/ssl.conf:/etc/nginx/conf.d/default.conf
  - ./public:/var/www/html

ローカルのディレクトリ、ファイルをdockerにマウントしています。

- ./docker/ssl:/etc/nginx/ssl

sslディレクトリに関しては証明書ファイルをマウントしているだけです。

- ./docker/ssl.conf:/etc/nginx/conf.d/default.conf

ssl.confはnginxイメージのデフォルトの設定ファイルを上書きする設定にしています。default.confを指定して上書きしないとややこしかったのでこうしています。

- ./public:/var/www/html

publicディレクトリ以下のhtmlファイルなどをnginxのドキュメントルート以下にマウントしています。
nginxのデフォルトルートのままだと、index.htmlがすでに存在していてシンプルにマウント出来なかったので、あえて別ディレクトリをドキュメントルートに設定しています。

3-2. ssl.conf

ssl_certificate     /etc/nginx/ssl/example.com.pem;     # SSL証明書
ssl_certificate_key /etc/nginx/ssl/example.com-key.pem; # 秘密鍵

特に解説することもないですが、上記でdockerにマウントした証明書や鍵を読み込んでいます。

4. まとめ

mkcertを使うことでとても簡易にSSL環境が構築できると思います。
dockerで出来るというのも環境を汚さなくて良いですね。

良いWEBライフを!

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

Andorid Native + Flutterのビルドに便利なDocker Imageを作る

Androidアプリのビルドによう使うツールをインストールしたDocker Imageの作り方を説明する(Android SDK, Flutter SDK, GCloud, Bundler, Firebase tools)。
Dockerを使ったことはあるが、実用的なDocker Imageを作ったことはない人向けの説明。

Docker Imageを作る手順

1. Dockerfileを記述する

# BaseはCircle CIのものにする。android sdk, gcloudが既に入っているので楽。
FROM circleci/android:api-29-node

# Install firebase tools
RUN sudo curl -sL https://firebase.tools | bash

# Install tools for easylauncher
RUN sudo apt-get update && sudo apt-get install -y fontconfig ttf-dejavu

# Install Flutter SDK
# ほぼ以下のファイルのコピペ。flutter_verisonの初期化とprecacheの部分は独自。
# https://github.com/cirruslabs/docker-images-flutter/blob/master/sdk/Dockerfile
ARG flutter_version=1.20.1

ENV FLUTTER_HOME=${HOME}/sdks/flutter \
    FLUTTER_VERSION=$flutter_version
ENV FLUTTER_ROOT=$FLUTTER_HOME

ENV PATH ${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin

RUN git clone --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git ${FLUTTER_HOME}

RUN flutter precache

RUN yes | flutter doctor --android-licenses && flutter doctor

2. Docker Imageをビルドする

上記のDockerfileと同じディレクトリで以下のコマンドを実行する。

docker build -t kamikazezirou/android:1.0 .

「kamikazezirou/android」の部分はImage名。
「:1.0」は、ImageのTag。
適宜変更すること。

3. Docker ImageをDocker Hubにpushする

docker push kamikazezirou/android:1.0

※docker loginでDocker Hubにログインしておくこと。アカウントも必要。

4. CIから使う(Cirlce CIでの例)

jobs:
  build:
    working_directory: ~/code
    docker:
      - image: kamikazezirou/android:1.0
...

背景

仕事で開発しているアプリで、Android Native onlyのアプリにFlutterモジュールを組み込むことになった。
仕事のAndroidアプリ開発ではCirlce CIを使っているが、その設定をしていて、ビルドツール全部入りのDocker Imageが必要になった。

CIのワークフローはは、デバッグapkのビルド -> Firebase Test Lab実行 -> リリースビルドというような流れにしている。最初は、ビルドのDocker Imageには「cirrusci/flutter:1.17.5」を使い、Firebase Test Labの実行のDocker Imageには「circleci/android:api-28-node」を使う、といった形にしようとした(前者はFlutter SDK有り かつ GCloudなし。後者はFlutter SDKなし かつ GCloudあり)。

この方式だと2つ問題があった。

  1. 依存ライブラリのキャッシュの復元時にエラーが発生した(2つのDocker Imageのhomeディレクトリが違うことが原因)
  2. この2つのDocker Imageに含まれないビルドツールがあり、それらを毎回インストールする必要があった(→ビルド時間が遅くなる、ビルドスクリプトが雑然とする)

この2つの問題を解決するために、ビルドツール全部入りのDocker Imageを作ろうと思い立った。
1つのDocker Imageであればhomeディレクトリは常に同じであり、ビルドツールのインストール処理も不要。

参考:作ったDocker Image

https://hub.docker.com/repository/docker/kamikazezirou/android

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