20190215のdockerに関する記事は8件です。

CircleCI で GCR(Container Registry) の private な Docker image を利用する方法

CircleCI 2.0, 2.1 で確認。

会社のプロジェクトなどで、 GCR等で private にした Docker image をそのままCircleCIのジョブで使用したいことがあると思います。特に GCR はやり方を忘れそうだったので備忘録として残しておきます。

手順

① GCRにアクセスするための適当なサービスアカウントをIAMで作成

GCR のDocker imageは GCS のあるバケットに保存されており、
CircleCI からそのバケットにアクセスする必要がある。

② GCRのimageが保存されているGCSバケットに対して、①に閲覧権限を付与

GCRにDocker imageを置いていれば artifacts.プロジェクト名.appspot.com のような名前のバケット名が自動的にできており、そこにimageが保存されている。
(GCRのリージョンによっては asia.artifacts.プロジェクト名.appspot.com のようになる)

GCSの画面にて、このバケットの ストレージオブジェクト閲覧者 の権限を ①で作成したサービスアカウントに対して付与する。
(GCR自体にアクセスするためのロールは存在しないことに注意。 参考: https://cloud.google.com/container-registry/docs/access-control#permissions_and_roles)

③ 権限を付与したサービスアカウントのJSONキーをCircleCIの環境変数に設定

②で権限を付与した後にサービスアカウントのJSONキーをダウンロードし、CircleCIの環境変数に設定する。 (今回は GCR_CREDS という名前に。)
JSONキーの内容をコピーしてそのまま環境変数の値として入れればOK。

.circleci/config.yaml に認証情報を記述

③で設定した環境変数を使って以下のように記述すれば完成。

_json_key は、GCRにサービスアカウントからアクセスする際のユーザー名らしい。
(参考: https://cloud.google.com/container-registry/docs/advanced-authentication)

.circleci/config.yaml
docker: 
  - image: gcr.io/プロジェクト名/イメージ名:タグ
    auth:
      username: _json_key
      password: $GCR_CREDS

参考: Impossible to use a private gcr.io base image on Circle 2.0?

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

docker buildする際にhost側のssh keyを使ってbuildする

docker buildする際にhost側のssh keyを使いつつbuildしたいことがある。
docker run -vなら~/.sshをmountするとかでhost側のssh keyが使えるけど、buildではできなかった。
これがDocker v18.09からできるようになった。(まだexperimental扱いではある)
keyをADDして最後に消す、みたいなワークアラウンドが不要になりそう。

buildkitの有効化

$ export DOCKER_BUILDKIT=1

Dockerfile

# syntax=docker/dockerfile:1.0.0-experimental

FROM ubuntu:18.04
RUN apt-get update

RUN apt-get install -y git
RUN apt-get install -y openssh-client
RUN apt-get install -y ruby

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.e >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone git@github.e:org/repo.git

build

$ docker build --ssh default .
  • 先頭に# syntax=docker/dockerfile:1.0.0-experimentalを書くのがポイント
  • ssh-keyscanでknow_hostsにhost情報を書いとかないと、Host key verification failed.で蹴られてしまう
  • 上記の例だとforward agentを使っている。

hostのssh keyを直接mountする場合

RUN --mount=type=secret,id=ssh,target=/root/.ssh/id_rsa git clone 〜

build

docker build --secret id=ssh,src=$HOME/.ssh/id_rsa .
  • これはssh key以外のmountにも使える

参考

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

Laravelの開発環境をDockerを使って構築する

何回Laravelの開発環境を構築するねん...ってツッコミたくなりますが、4回目の記事です?

概要

docker(docker-compose)でLEMP環境(PHP/nginx/MySQL)を構築し、Laravelの新規プロジェクト作成まで行います。
使用するコマンドについても軽く説明していきます。

リポジトリ

https://github.com/ucan-lab/docker-laravel5

お急ぎの方は README 参照

対象読者

  • Laravelが動く環境をdockerで作りたい人

Docker とは

Dockerとは、一台のマシン上に複数の隔離された環境を構築する軽量なコンテナ型の仮想化技術です。

特定のプロセスの実行環境を Dockerイメージ という単位で管理できます。

Dockerのメリットとしては、
仮想マシン(VirtualBox)と違ってハードウェア(CPU, メモリ)をシミュレーションする必要がないためとても軽快です。

補足

コンテナに出たり入ったりすることが多いので下記のようにします。

[mac] $ Macで実行するコマンド
[web] $ dockerの web コンテナ内で実行するコマンド
[app] $ dockerの app コンテナ内で実行するコマンド
[db] $ dockerの db コンテナ内で実行するコマンド
[node] $ dockerの node コンテナ内で実行するコマンド
[redis] $ dockerの redis コンテナ内で実行するコマンド

前提

  • docker
  • docker compose
  • git(Macは標準でインストールされている)

上記のツールが入っていることが前提となってます。

docker インストール

docker for macをインストールして起動します。

[mac] $ brew cask install docker
[mac] $ open /Applications/Docker.app

dockerが入っていることを確認する

[mac] $ docker --version
Docker version 18.09.1, build 4c52b90

[mac] $ docker-machine --version
docker-machine version 0.16.1, build cce350d7

[mac] $ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

git

gitが入っていること、sshできることを確認する

[mac] $ git --version
git version 2.17.2 (Apple Git-113

[mac] $ ssh -T github.com
Hi ucan-lab! You've successfully authenticated, but GitHub does not provide shell access.

もしsshできなかった場合は、
過去記事にssh接続の設定手順の記事を書いてるので良かったら参考にしてください。

推奨アプリ

  • Kitematic
    • コンテナをGUIで管理するツール
    • dockerを触るなら必須
  • TablePlus
    • MySQLをGUIで管理するツール
    • MySQLを触るなら必須
    • MySQL8.0に対応
  • Visual Studio Code
    • Microsoft製のテキストエディタ
    • こだわりがない人は入れておこう
  • PhpStorm
    • JetBrains製の統合開発環境(IDE)
    • お金がある人は入れておこう

環境

Mac

  • MacOS Mojave 10.14.2

Docker

最終的に次の環境を構築します!!

$ docker-compose run web nginx -V
nginx version: nginx/1.15.7
built by gcc 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
built with OpenSSL 1.1.0f  25 May 2017
TLS SNI support enabled

[mac] $ docker-compose run app php -v
PHP 7.3.2 (cli) (built: Feb  9 2019 02:11:33) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies

[mac] $ docker-compose run app composer -V
Composer version 1.8.4 2019-02-11 10:52:10

[mac] $ docker-compose run db mysql -V
mysql  Ver 8.0.15 for Linux on x86_64 (MySQL Community Server - GPL)

[mac] $ docker-compose run redis redis-cli --version
redis-cli 5.0.3

[mac] $ docker-compose run node node -v
v11.8.0

[mac] $ docker-compose run node npm -v
6.5.0

[mac] $ docker-compose run node yarn --version
1.13.0

※バージョン固定してないものもあり、構築するタイミングによってバージョン差異はあります。

ディレクトリ構成

[mac] $ tree .
.
├── README.md
├── docker => 各コンテナの設定ファイル
│   ├── mysql
│   │   ├── Dockerfile
│   │   ├── data
│   │   ├── logs => MySQLのログファイルはここ
│   │   └── my.cnf
│   ├── nginx
│   │   ├── default.conf
│   │   └── logs => nginxのログファイルはここ
│   └── php
│       ├── Dockerfile
│       └── php.ini
├── docker-compose.yml
└── src => Laravelプロジェクトをインストールするディレクトリ

ディレクトリ構成はとても悩みましたが、この形で行きます。

Docker環境を構築する

今回は handson という作業ディレクトリを作ります。

[mac] $ mkdir ~/handson
[mac] $ cd ~/handson

GitHubリポジトリからDockerテンプレートをダウンロード

[mac] $ git clone git@github.com:ucan-lab/docker-laravel5.git
[mac] $ cd docker-laravel5

環境設定ファイルの確認

dockerの.env の中身を確認します。

$ less .env
MYSQL_DATABASE=homestead
MYSQL_USER=homestead
MYSQL_PASSWORD=secret

データベースの接続情報を記述している箇所があります。
ここは Laravelの.env の初期設定に合わせてます。
必要に応じて 環境設定ファイルや各コンテナの設定ファイルを変更してください。

Dockerのビルド、起動

[mac] $ docker-compose build
[mac] $ docker-compose up -d
  • build コマンドで サービスの構築 を行う
  • up コマンドで コンテナを作成してサービスを開始 します
  • -d オプションで デタッチド・モードで起動(デフォルトはアタッチド・モード) します。
    • これにより通常はコンテナを実行するとすぐに終了しますが、バックグラウンドで動作するようになります。
[mac] $ docker-compose ps
      Name                     Command               State                  Ports
-----------------------------------------------------------------------------------------------
myproject_app_1     docker-php-entrypoint php-fpm    Up       0.0.0.0:3501->8000/tcp, 9000/tcp
myproject_db_1      docker-entrypoint.sh mysqld      Up       0.0.0.0:3502->3306/tcp, 33060/tcp
myproject_node_1    node                             Exit 0
myproject_redis_1   docker-entrypoint.sh redis ...   Up       6379/tcp
myproject_web_1     nginx -g daemon off;             Up       0.0.0.0:3500->80/tcp
  • ps コマンドで起動しているコンテナの一覧を表示します。

上記のようにコンテナが表示されていればokです。

Laravelプロジェクトを新規に作成する場合

[mac] $ docker-compose exec app ash
[app] $ composer create-project laravel/laravel --prefer-dist .
  • exec コマンドで指定した起動しているコンテナのプロセスを実行できます。
  • ash を指定することでコンテナの中に入って任意のコマンドを実行できます。
  • composer create-project laravel/laravel 新しいLaravelプロジェクトを作成するコマンド
    • --prefer-dist はzipでダウンロードする(高速)、デフォルトはgit cloneする
    • . カレントディレクトリにインストールする

http://127.0.0.1:3500

上記のアドレスにアクセスしてLaravelのウェルカムページが表示されればokです。

スクリーンショット 2019-02-09 11.46.14.png

ポート番号は他の環境と被らないようあえて 3500 番号に設定してます。

LaravelのDocker環境構築は以上で完了です!!
お疲れ様です???

必要に応じて...

Laravelのコマンドを実行したい場合

php, composer, artisan コマンドは app コンテナ内で実行します。

[mac] $ docker-compose exec app ash
[app] $ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
  • migrate すると userspassword_resets テーブルが生成される。

MySQLに接続したい場合

MySQLはdbコンテナに入ってMySQLコマンドを実行します。
環境変数に接続情報が入っているのでこのままコピペでログインできます。

[mac] $ docker-compose exec db bash
[db] $ mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE}

上記のコマンドでMySQLにログインし、MySQLコマンドを実行できます。

[db] mysql> show variables like '%time_zone%';
+------------------+------------+
| Variable_name    | Value      |
+------------------+------------+
| system_time_zone | UTC        |
| time_zone        | Asia/Tokyo |
+------------------+------------+

[db] mysql> show variables like '%char%';
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8                           |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
[db] mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| homestead          |
| information_schema |
+--------------------+

[db] mysql> show tables;
+---------------------+
| Tables_in_homestead |
+---------------------+
| migrations          |
| password_resets     |
| users               |
+---------------------+

[db] mysql> select * from migrations;
+----+------------------------------------------------+-------+
| id | migration                                      | batch |
+----+------------------------------------------------+-------+
|  1 | 2014_10_12_000000_create_users_table           |     1 |
|  2 | 2014_10_12_100000_create_password_resets_table |     1 |
+----+------------------------------------------------+-------+
  • タイムゾーン: Asia/Tokyo
  • 文字コード: utf8mb4

上述の php artisan migrate を実行していれば migrations テーブルに2件データが入ってるはず。

MySQL管理ツールから接続したい場合

オススメのMySQL管理ツールはTablePlusです。理由はMySQL8.0に対応してるから?

設定例

スクリーンショット 2019-02-12 0.18.32-min.png

変更箇所

Name: docker-laravel5(任意)
Host: 127.0.0.1
Port: 3502
User: homestead
Password: secret
Database: homestead

TablePlusの画面

スクリーンショット 2019-02-12 0.24.15-min.png

Node(npm, yarn)を実行したい場合

Nodeのコンテナは起動させてないので run コマンドで起動させてコンテナ内に入ります。

[mac] $ docker-compose run node ash
[node] $ npm install # OR yarn install
[node] $ npm run dev # OR yarn run dev
  • run コマンドで指定したコンテナを作成して起動し、プロセスを実行します。

Redisを使いたい場合

[mac] $ docker-compose exec redis ash
[redis] $ redis-cli
127.0.0.1:6379> SET hoge bar
OK
127.0.0.1:6379> GET hoge
"bar"

RedisをLaravelで使いたい場合

[mac] $ docker-compose exec app ash
[app] $ composer require predis/predis
[app] $ sed -i -e 's/CACHE_DRIVER=file/CACHE_DRIVER=redis/' .env
[app] $ sed -i -e 's/SESSION_DRIVER=file/SESSION_DRIVER=redis/' .env

参考: https://readouble.com/laravel/5.7/ja/redis.html

Laravelのビルドインサーバを使いたい場合

[mac] $ docker-compose exec app ash
[app] $ php artisan serve --host 0.0.0.0

http://127.0.0.1:3501

  • serve Laravelのビルトインサーバを起動します。コンソール上にログが表示されます。
  • --host 外部からのアクセスを許可する指定をします。

データベースを初期化する

データベースを真っさらな状態に戻したい場合。
まずは、定義されているデータベースのボリュームを探します。

$ docker volume ls | grep db-data
local               docker-laravel5_db-data

docker-laravel5_db-data これです。

$ docker-compose down
$ docker volume rm docker-laravel5_db-data
$ docker-compose up -d

使用中のボリュームは削除できないので、コンテナを停止してボリュームを削除し、コンテナを再び起動するとデータベースが初期化された状態になります。

既存のLaravelプロジェクトの実行環境を構築する

例えば、このLaravelプロジェクトを動かしてみたいなぁという時。

https://github.com/ucan-lab/laravel-microposts

[mac] $ mkdir ~/handson
[mac] $ cd ~/handson
[mac] $ git clone git@github.com:ucan-lab/docker-laravel5.git
[mac] $ git clone git@github.com:ucan-lab/laravel-microposts.git
[mac] $ cd docker-laravel5

.env を書き換える

#PROJECT_PATH=./src
PROJECT_PATH=../laravel-microposts

あとは環境構築して動作確認します?

[mac] $ docker-compose build
[mac] $ docker-compose up -d
[mac] $ docker-compose exec app ash
[app] $ composer install
[app] $ cp .env.example .env
[app] $ php artisan migrate

http://127.0.0.1:3500

今回Dockerを勉強して知ったこと

上記の方々にレビューいただき、今回改めて知ったことを共有します。

コンテナ名の衝突を避ける

コンテナを起動するとフォルダ名が初期値としてプロジェクト名となってしまい、フォルダ名を変えた場合に、プロジェクト名が勝手に変わってしまう問題があります。

コンテナ名だけでなく、イメージ名、ネットワーク名、ボリューム名の衝突にも気を付ける必要があります。

COMPOSE_PROJECT_NAME

COMPOSE_PROJECT_NAME を使えば、 container_name も指定する必要なく、「COMPOSE_PROJECT_NAME 変数 + _ + サービス名 + _ + 連番」という名前になります?

RUN set -eux

RUN を実行する際にはじめにシェルオプションを設定すると
buildを実行する際にコマンドが表示されるので、処理が途中で失敗した場合などに原因調査しやすいというメリットがあります。

  • -e オプションによって実行したコマンドが1つでもエラーになれば直ちに終了するようにし、
  • -u オプションで未定義の変数などを使おうとすればエラーにするようにしている。
  • -x オプションでは実行コマンドとその引数をトレースとして出力するようにしている。

複数行でRUNの実行

Dockerは文を実行するたびにイメージのレイヤーを作成されてしまう。
RUN コマンドは繋げてワンライナーにする方が良い。
コマンドが長くなる場合は \ で改行して見やすくする。

# NG
RUN apk update
RUN apk add git

# GOOD!
RUN apk update && \
  apk add git

一時的な変数は ENV ではなく ARG を使う

ARG は Dockerfile 内で使用可能な変数です。

ARG foo=bar
RUN echo $foo

ADD より COPY

ファイルをコピーする意図であれば、 ADD より COPY を使った方がより直感的で分かりやすい

ADD ./my.cnf /etc/mysql/my.cnf # NG
COPY ./my.cnf /etc/mysql/my.cnf # GOOD!

トップレベルボリュームを使用する

トップレベルボリュームを使用するとデータの永続化が可能になります。名前付きvolume とも呼ぶそうです。
また、ボリュームが隠蔽化されるため誤って削除する心配が少なくなり開発しやすくなります。

テスト用に使うデータベースを用意する

Laravelの場合、テスト用のデータベースを作成することが多いので、
テスト用のDBも合わせて作成してあると開発環境としてはさらに良い。

/docker-entrypoint-initdb.d のディレクトリ配下に .sql.sh ファイルを配置すれば初回起動時に実行してくれます。

ベースイメージはコンテナの軽さを重視するならAlpine

Alpine Linux(アルパイン・リナックス)とは、
muslBusyBoxをベースとしたLinuxディストリビューションです。
(用語を説明すると新たな用語の説明をしなければならなくなる説)

セキュリティ・シンプルさ・リソース効率を重視したOSです。

特定のOSのシェルを実行するようなアプリでなければ、Alpineはとても軽量です。

ただ、徹底的に軽量化されているため、AWSやGCPにデプロイした際に苦戦しそうです?

Alpine以外のDockerイメージとしては、UbuntuやDebianのイメージが良く使われる傾向にあるみたいです。個人歴にはCentOSとかRedHat系のOSが好きです?

関連記事

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

さいごに

初めてdocker環境の構築に挑戦しましたが、個人的にはイイ感じに作れたかなと満足してます?
もっとこうした方がイイよ!っていうアドバイスがあったらコメントいただけると嬉しいです!

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

変異のHGVS表記の相互変換(Ensembl variant_recoder)

HGVSとは

ゲノム等のリファレンス配列に対する違いを表現する表記としてHGVS(Human Genome Variation Society)が推奨している表記で、変異を表す際の標準となっている表記法

例えばcDNA上での変異であれば下記のように表現される
NM_000603.4:c.894T>G

詳細はSequence Variant Nomenclatureを参照

変異の表現方法の変換

cDNA上で表現された変異とその位置をゲノム上や、発現しているアミノ酸の位置を求めるにはどうすれば良いだろうか

ここではensemblで提供されているVariant Recoderを利用して変換を行ってみよう

Variant RecodeはEnsemblのVariant Effect Predictor Ensembl/ensembl-vepと共にgit上で公開されているツール

本体はPerlで記述されているので、インストールは比較的容易だけれど、Docker hub上でDockerイメージも提供されているので、ここはDockerを利用する事でインストールの手間を省こう

まずは、Docker イメージの取得

$ docker pull ensemblorg/ensembl-vep 

Dockerのイメージが取得できたら後は実行してみよう

$ docker run ensemblorg/ensembl-vep variant_recoder --input_data "NM_000603.4:c.894T>G" --grch37  --pretty  
オプション 説明 コメント
--input_data 変換元のhgvsで表記された文字列 ダブルクオーテーション又はシングルクオーテーションで区切る
--grch37 ヒトゲノムのバージョン指定 無指定であればhg38が利用される
--pretty JSON表記を見やすく整形表示する

変換結果

変換には若干の時間が必要だけれど、この例では次のようなJSON表記のデータが得られる

[
   {
      "hgvsc" : [
         "ENST00000297494.3:c.894T>G",
         "ENST00000461406.1:c.276T>G",
         "ENST00000467517.1:c.894T>G",
         "ENST00000484524.1:c.894T>G",
         "NM_000603.4:c.894T>G",
         "NM_001160109.1:c.894T>G",
         "NM_001160110.1:c.894T>G",
         "NM_001160111.1:c.894T>G"
      ],
      "input" : "NM_000603.4:c.894T>G",
      "id" : [
         "rs1799983",
         "CM981388"
      ],
      "hgvsp" : [
         "ENSP00000297494.3:p.Asp298Glu",
         "ENSP00000417143.1:p.Asp92Glu",
         "ENSP00000420551.1:p.Asp298Glu",
         "ENSP00000420215.1:p.Asp298Glu",
         "NP_000594.2:p.Asp298Glu",
         "NP_001153581.1:p.Asp298Glu",
         "NP_001153582.1:p.Asp298Glu",
         "NP_001153583.1:p.Asp298Glu"
      ],
      "hgvsg" : [
         "NC_000007.13:g.150696111T>G"
      ]
   }
]

戻り値のJSONのキーと値は次の通り

キー 意味
hgvsc cDNA上の変異
hgvsp アミノ酸配列上の変異
hgvsg ゲノム配列上の変異
input 問い合わせした変異文字列
id 変異のID:dbSNPのrsIDやHGMDのAccession等

問い合わせの変異情報を表す文字列としては、ここで利用しているHGVS表記の他に、VCFの表記、VEPの表記、dbSNPのrsID、HGMDのAccession番号が利用できる

項目の絞り込み

取得したい項目のみ指定して変換する事もできる
例えば、ゲノム上の位置のみが必要であれば、--fields hgvsgとする

$ docker run ensemblorg/ensembl-vep variant_recoder --input_data 'NM_000603.4:c.894T>G' --grch37 --fields hgvsg --pretty 

これで、次の結果が得られる

[
   {
      "hgvsg" : [
         "NC_000007.13:g.150696111T>G"
      ],
      "input" : "NM_000603.4:c.894T>G"
   }
]

複数の項目を指定する場合には、--fieldsオプションの後に必要なキーをカンマ区切りで指定すれば良い

$ docker run ensemblorg/ensembl-vep variant_recoder --input_data 'NM_000603.4:c.894T>G' --grch37 --fields hgvsg,hgvsc --pretty 

複数の対象の変換

ここまでは一つの変異を対象に処理をおこなっていたが、対象が複数ある場合には、変異の一覧を作成して処理する方が効率が良い
変換する対象を一行ごとに区切って格納したファイルを作成し、--input-fileオプションで指定しよう

refseq_nm.txt
NM_000603.4:c.894T>G
NM_000029.3:c.803T>C
$ docker run -v${PWD}:/work -w=/work ensemblorg/ensembl-vep variant_recoder --input_file refseq_nm.txt --grch37 --pretty
オプション 説明
--input_file 変異の一覧を記入したファイルを指定

カレントディレクトリのrefseq_nm.txtファイルをdocker内で読み込むために、dockerに-v${PWD}:/work -w=/workというオプションを指定している
このオプションで、ホストのカレントディレクトリをdocker内部の/workディレクトリとしてマウントして、/workディレクトリ内でツールを実行するよう指定している

結果は次の通り

[
   {
      "hgvsp" : [
         "ENSP00000297494.3:p.Asp298Glu",
         "ENSP00000417143.1:p.Asp92Glu",
         "ENSP00000420551.1:p.Asp298Glu",
         "ENSP00000420215.1:p.Asp298Glu",
         "NP_000594.2:p.Asp298Glu",
         "NP_001153581.1:p.Asp298Glu",
         "NP_001153582.1:p.Asp298Glu",
         "NP_001153583.1:p.Asp298Glu"
      ],
      "hgvsg" : [
         "NC_000007.13:g.150696111T>G"
      ],
      "hgvsc" : [
         "ENST00000297494.3:c.894T>G",
         "ENST00000461406.1:c.276T>G",
         "ENST00000467517.1:c.894T>G",
         "ENST00000484524.1:c.894T>G",
         "NM_000603.4:c.894T>G",
         "NM_001160109.1:c.894T>G",
         "NM_001160110.1:c.894T>G",
         "NM_001160111.1:c.894T>G"
      ],
      "input" : "NM_000603.4:c.894T>G",
      "id" : [
         "rs1799983",
         "CM981388"
      ]
   },
   {
      "input" : "NM_000029.3:c.803T>C",
      "hgvsc" : [
         "ENST00000366667.4:c.803T>C",
         "NM_000029.3:c.803T>C"
      ],
      "id" : [
         "rs699",
         "CM920010"
      ],
      "hgvsg" : [
         "NC_000001.10:g.230845794A>G"
      ],
      "hgvsp" : [
         "ENSP00000355627.4:p.Met268Thr",
         "NP_000020.1:p.Met268Thr"
      ]
   }
]

変換時に何かの問題が発生した場合

例えば'NM_000603.5:c.894T>G'を変換してみよう

$ docker run ensemblorg/ensembl-vep variant_recoder --input_data 'NM_000603.5:c.894T>G' --grch37 --fields hgvsg --pretty 

下記の様に、キーとしてwarningsが出力される

[
   {
      "warnings" : [
         "Unable to parse HGVS notation 'NM_000603.5:c.894T>G': Could not get a Transcript object for 'NM_000603': Could not get a Transcript object for 'NM_000603.5'"
      ]
   }
]

Refseq のバージョン番号の解決

上記の通り、RefseqのIDのバージョン番号が利用しているEnsebmlのDBのそれと一致していないと変換が実行できない
例えば、これを記述している時点でのNM_000603の最新版はNM_000603.5なのだけれど、これはEnsemblのDBのそれとは異なっている

RefseqのIDについてバージョン番号を取得せずにはこれらの変換を実施する事ができない

Ensembl内のRefseqのバージョン番号を取得する

この問題を解決するためにEnsemblのref.txtファイルをftpで取得する(それぞれのサイズは28MB程)

Ensemblのサイトで最新のバージョンを確認してほしい
これを記述している時点での最新版はrelease-95

release-95のヒトゲノムのリファレンスGRCh37の場合のEnsemblのファイルは下記
ftp://ftp.ensembl.org/pub/grch37/release-95/mysql/homo_sapiens_core_95_37/xref.txt.gz.bz2

release-95のヒトゲノムのリファレンスGRCh38の場合のEnsemblのファイルは下記
ftp://ftp.ensembl.org/pub/release-95/mysql/homo_sapiens_core_95_38/ref.txt.gz

これらのファイルを展開して下記のカラムを抽出する

カラム コメント
カラム3 Version番号を含まないRefseqのID
カラム4 Version番号を含むRefseqのID (Version番号無しも有る)

実際のところここにはRefseq以外の情報も入っている

$ cut -f 3-4 xref.txt | grep "^NP_" > np_map.tsv
$ cut -f 3-4 xref.txt | grep "^NM_" > nm_map.tsv

上記のような方法で作成したデータを利用してRefseqのIDの対応をとってから変換をおこなうと良いだろう

今回はここまで:smile:

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

Docker Rails pry-byebug で pry 入力できなかった時

*メモ書きです。

docker-compose.yml
  web:
  ...

  + tty: true
  + stdin_open: true

上記の tty: true stdin_opne: true を追加することで解決しました。

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

Airflow を単体の docker container で立ち上げる

目的

  • Airflow の最小構成を構築することにより airflow.cfg などの設定方法の理解を深める
  • puckel/docker-airflow を参考にする

結論

diff --git a/script/entrypoint.sh b/script/entrypoint.sh
index fb3f9ad..62d4198 100755
--- a/script/entrypoint.sh
+++ b/script/entrypoint.sh
@@ -70,8 +70,8 @@ fi
 case "$1" in
   webserver)
     airflow initdb
-    if [ "$AIRFLOW__CORE__EXECUTOR" = "LocalExecutor" ]; then
-      # With the "Local" executor it should all run in one container.
+    if [ "$AIRFLOW__CORE__EXECUTOR" != "CeleryExecutor" ]; then
+      # With the "Sequential" or "Local" executor it should all run in one container.
       airflow scheduler &
     fi
     exec airflow webserver

※ PR 送りましたが author はもうメンテしてないようで merge される可能性は低いです。。
  あと、数時間前に別の人が同じような PR してたので確認不足でした。。
  https://github.com/puckel/docker-airflow/pull/316

以下のコマンドで build して起動

docker build --rm -t puckel/docker-airflow .
#  -e LOAD_EX=y で example_dags を有効にする
docker run -d -p 8080:8080 -e LOAD_EX=y puckel/docker-airflow webserver

airflow.cfg について

airflow/config_templates にある default_airflow.cfg などを参考にするとよい
また puckel/docker-airflow や、Google Cloud Composer などの設定と見比べるとより理解が深まると思われる

SequentialExecutor と LocalExecutor

puckel/docker-airflow でも docker container 単体で動作させる際の Executor としては SequentialExecutor が選択されています

By default, docker-airflow runs Airflow with SequentialExecutor :

docker run -d -p 8080:8080 puckel/docker-airflow webserver

https://github.com/puckel/docker-airflow/blob/79c6ea7f4e5d309d0c923ee9fde14e5ce4f7eb9e/README.md#usage

しかし前述の通り patch を当てないとこれは動作しません
今まではここで疑問を持たずに docker-compose-LocalExecutor.yml を利用してきました
おそらく SequentialEecutor にも airflow scheduler は必要なのだと思われます

airflow/executors/local_executor.py には以下のようなコメントがあります

LocalExecutor runs tasks by spawning processes in a controlled fashion in different
modes. Given that BaseExecutor has the option to receive a parallelism parameter to
limit the number of process spawned, when this parameter is 0 the number of processes
that LocalExecutor can spawn is unlimited.
The following strategies are implemented:
1. Unlimited Parallelism (self.parallelism == 0): In this strategy, LocalExecutor will
spawn a process every time execute_async is called, that is, every task submitted to the
LocalExecutor will be executed in its own process. Once the task is executed and the
result stored in the result_queue, the process terminates. There is no need for a
task_queue in this approach, since as soon as a task is received a new process will be
allocated to the task. Processes used in this strategy are of class LocalWorker.
2. Limited Parallelism (self.parallelism > 0): In this strategy, the LocalExecutor spawns
the number of processes equal to the value of self.parallelism at start time,
using a task_queue to coordinate the ingestion of tasks and the work distribution among
the workers, which will take a task as soon as they are ready. During the lifecycle of
the LocalExecutor, the worker processes are running waiting for tasks, once the
LocalExecutor receives the call to shutdown the executor a poison token is sent to the
workers to terminate them. Processes used in this strategy are of class QueuedLocalWorker.
Arguably, SequentialExecutor could be thought as a LocalExecutor with limited
parallelism of just 1 worker, i.e. self.parallelism = 1.
This option could lead to the unification of the executor implementations, running
locally, into just one LocalExecutor with multiple modes.

SequentialExecutor は parallelism を 1 に限定した LocalExecutor と考えることもできます
docker-compose-LocalExecutor.yml も postgresql と webserver しか service はありません
ちなみに SequentialExecutor 以外では sqlite が利用できないことから postgresql が利用されています

https://github.com/apache/airflow/blob/1.10.2/airflow/configuration.py#L163-L169

SequentialExecutor 側にもこんなコメントがあります

This executor will only run one task instance at a time, can be used
for debugging. It is also the only executor that can be used with sqlite
since sqlite doesn't support multiple connections.
Since we want airflow to work out of the box, it defaults to this
SequentialExecutor alongside sqlite as you first install it.

デバッグ用、初期インストール時のデフォルト

https://github.com/apache/airflow/blob/1.10.2/airflow/executors/sequential_executor.py#L29-L34

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

DockerがホストOSのディスクを圧迫するので、コンテナ再作成のついでにディスクスペースを空ける

開発中のアプリの動作確認でデータベースを頻繁に更新するため、docker-composeでmysqlのコンテナを作っては壊ししています。
手軽にデータベースを初期状態に戻せて便利なのですが、使っているとホストのディスク容量をあっという間に占領します。
データベース初期化のついでにディスクスペースも空けるようにシェルスクリプト化してしまいました。

前提・参考ページ

OS: CentOS Linux release 7.2.1511 (Core)
Docker: Docker version 1.13.1, build 8633870/1.13.1

コチラの投稿お手本丸パクリして、docker-composeからmysqlコンテナを立ち上げています。
Dockerがディスクスペースを圧迫した時の対処法は、コチラの投稿で知りました。

使用するコード

やっていることは
・コンテナの破棄・作成
・docker関連のファイル削除
くらいです

conductor.sh
#!/bin/bash

######################################################
# 環境を初期化します。
#  ・DBの初期化
#####################################################

echo "::Started::"
SPACE_S=`df -h | grep '/dev/mapper/centos-root' | awk '{print $5}' | awk -F'%' '{print $1}'`
if [ ${SPACE_S} -gt 85 ];
then
        echo "Exec space opener"
        sudo sh /root/space_opener.sh
fi

sh ./subcommands/initDB.sh &
sh ./subcommands/AnyOtherShellscripts.sh &
wait

echo "::Completed::"
df -h | grep "centos\-root"

・ディスク使用量が85%を超えたらスペースを空けるようにしています

/root/space_opener.sh
#!/bin/bash
echo "# 作業前 空き容量"
df -h

# rootユーザでなければ終了
if [[ "root" == $(whoami) ]];
then
        echo "# root user"
        docker system prune -f
        docker rmi -f $(sudo docker images -a | awk '/^[^R]/{print $3}')
else
        echo "# Not root user"
        exit 1
fi

echo "# 作業後 空き容量"
df -h
subcommands/initDB.sh
#!/bin/bash

docker-compose down
sleep 2s
docker-compose up -d

参考

先達の皆様のおかげで快適に使えております。
ありがとうございます。

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

Amazon Linux 2でSQLite3を最新バージョンにする

Amazon Linux 2でSQLite3のバージョンを上げるのに四苦八苦したのでメモ。

Dockerコンテナ立ち上げ

Amazon Linuxのイメージを取得してコンテナを立ち上げます。

> docker pull amazonlinux
> docker -it amazonlinux
bash-4.2#

Amazon LinuxのイメージはすでにSQLite3がインストール済みですが、バージョンが3.7.17 と少し古めです。amazon-linux-extras にもSQLite3はありません。

Amazon Linux 2 に関するよくある質問
https://aws.amazon.com/jp/amazon-linux-2/faqs/

SQLite3を最新バージョンに上げることができないかを確認します。

コンテナ内
bash-4.2# sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

bash-4.2# yum --version
3.4.3
  Installed: rpm-4.11.3-25.amzn2.0.3.x86_64 at 2019-02-07 20:40
  Built    : Amazon Linux at 2018-09-12 21:28
  Committed: Panu Matilainen <pmatilai@redhat.com> at 2017-03-17

  Installed: yum-3.4.3-158.amzn2.0.2.noarch at 2019-02-07 20:40
  Built    : Amazon Linux at 2018-08-21 16:27
  Committed: CentOS Sources <bugs@centos.org> at 2018-04-10

yum でSQLite3の詳細を確認しますが、バージョンは3.7.17 のみのようです。

bash-4.2# yum list | grep sqlite
sqlite.x86_64                          3.7.17-8.amzn2.0.2             installed
apr-util-sqlite.x86_64                 1.6.1-5.amzn2.0.2              amzn2-core
freeradius-sqlite.x86_64               3.0.13-9.amzn2                 amzn2-core
golang-googlecode-sqlite-devel.x86_64  0-0.9.hg74691fb6f837.amzn2.0.2 amzn2-core
libdbi-dbd-sqlite.x86_64               0.8.3-16.amzn2.0.1             amzn2-core
sqlite.i686                            3.7.17-8.amzn2.0.2             amzn2-core
sqlite-devel.x86_64                    3.7.17-8.amzn2.0.2             amzn2-core
sqlite-doc.noarch                      3.7.17-8.amzn2.0.2             amzn2-core
sqlite-tcl.x86_64                      3.7.17-8.amzn2.0.2             amzn2-core

bash-4.2# yum info sqlite
Loaded plugins: ovl, priorities
Installed Packages
Name        : sqlite
Arch        : x86_64
Version     : 3.7.17
Release     : 8.amzn2.0.2
Size        : 795 k
Repo        : installed
()

bash-4.2# yum check-update
Loaded plugins: ovl, priorities

amazon-linux-extras.noarch                                 1.6.6-1.amzn2                                 amzn2-core

bash-4.2# find /usr/ -name sqlite3
/usr/lib64/python2.7/sqlite3
/usr/bin/sqlite3

bash-4.2# /usr/lib64/python2.7/sqlite3 --version
bash: /usr/lib64/python2.7/sqlite3: Is a directory

bash-4.2# /usr/bin/sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

試しにyum remove sqlite してみましたが、Error: Trying to remove "yum", which is protected となり削除できません。yum が依存しており削除できないように保護されてるようです。

bash-4.2# yum remove sqlite
Loaded plugins: ovl, priorities
Resolving Dependencies
--> Running transaction check
()
--> Finished Dependency Resolution
Error: Trying to remove "yum", which is protected

もし保護がされていないとして、SQLite3を削除するとyum が利用できなくなる罠があるみたいです。oh...

sqlite3を消すとyumが使えなくなる - maru.cc@はてな
http://marucc.hatenablog.com/entry/20080420/1208632521

centos で sqlite3 を削除すると yum が使えなくなる - 年寄りプログラマの備忘録
http://d.hatena.ne.jp/kawabes/20110921/1316577549

仕方ないので、公式から最新バージョンを取得してmake && make install します。インストール方法は下記が参考になりました。

SQLite Installation
https://www.tutorialspoint.com/sqlite/sqlite_installation.htm

最新バージョンのファイルは下記から取得可能です。現在の最新バージョンは3.27.1 でした。(2019/02/13時点)

SQLite Download Page
https://www.sqlite.org/download.html

コンテナ内
## ビルドするのに必要なパッケージをインストール
bash-4.2# yum install -y wget tar gzip gcc make

## ソースを取得
bash-4.2# wget https://www.sqlite.org/2019/sqlite-autoconf-3270100.tar.gz
bash-4.2# tar xvfz sqlite-autoconf-3270100.tar.gz

## ビルドしてインストール
bash-4.2# cd sqlite-autoconf-3270100

bash-4.2# ./configure --prefix=/usr/local

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... no
()
configure: creating ./config.status
config.status: creating Makefile
config.status: creating sqlite3.pc
config.status: executing depfiles commands
config.status: executing libtool commands


bash-4.2# make

source='sqlite3.c' object='sqlite3.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ./depcomp \
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.27.1\" -DPACKAGE_STRING=\"sqlite\ 3.27.1\" -DPACKAGE_BUGREPORT=\"http://www.sqlite.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.27.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_FDATASYNC=1 -DHAVE_USLEEP=1 -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1 -DHAVE_DECL_STRERROR_R=1 -DHAVE_STRERROR_R=1 -DHAVE_POSIX_FALLOCATE=1 -I.    -D_REENTRANT=1 -DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE  -g -O2 -c -o sqlite3.lo sqlite3.c
()
libtool: link: gcc -D_REENTRANT=1 -DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB -g -O2 -o sqlite3 sqlite3-shell.o sqlite3-sqlite3.o  -lm -ldl -lpthread


bash-4.2# make install

make[1]: Entering directory `/sqlite-autoconf-3270100'
 /usr/bin/mkdir -p '/usr/local/lib'
 (略)
 /usr/bin/mkdir -p '/usr/local/include'
 /usr/bin/install -c -m 644 sqlite3.h sqlite3ext.h '/usr/local/include'
 /usr/bin/mkdir -p '/usr/local/share/man/man1'
 /usr/bin/install -c -m 644 sqlite3.1 '/usr/local/share/man/man1'
 /usr/bin/mkdir -p '/usr/local/lib/pkgconfig'
 /usr/bin/install -c -m 644 sqlite3.pc '/usr/local/lib/pkgconfig'
make[1]: Leaving directory `/sqlite-autoconf-3270100'

インストールできたか確認します。

コンテナ内
bash-4.2# find /usr/ -name sqlite3
/usr/local/bin/sqlite3
/usr/lib64/python2.7/sqlite3
/usr/bin/sqlite3

bash-4.2# /usr/local/bin/sqlite3 --version
3.27.1 2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd

bash-4.2# /usr/lib64/python2.7/sqlite3 --version
bash: /usr/lib64/python2.7/sqlite3: Is a directory

bash-4.2# /usr/bin/sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

bash-4.2# sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

/usr/local/bin/sqlite3 にインストールされました。このままだと、元からインストールされていた方をみにいってしまうので、シンボリックリンクを貼ります。yum remove できないし、しゃーない。

コンテナ内
bash-4.2# mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
bash-4.2# ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3

bash-4.2# sqlite3 --version
3.27.1 2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd

bash-4.2# yum update
Loaded plugins: ovl, priorities
amzn2-core                                                                                  | 2.4 kB  00:00:00
No packages marked for update

yum も動くし、まあいけるでしょう。

Dockerfile でインストールする

コンテナ立ち上げるたびにインストールするのは手間なので、Dockerfile を利用してイメージ作成しておくと便利です。

Dockerfile
FROM amazonlinux:latest

RUN yum install -y wget tar gzip gcc make && \
    wget https://www.sqlite.org/2019/sqlite-autoconf-3270100.tar.gz && \
    tar xvfz sqlite-autoconf-3270100.tar.gz && \
    cd sqlite-autoconf-3270100 && \
    ./configure --prefix=/usr/local && \
    make && \
    make install && \
    mv /usr/bin/sqlite3 /usr/bin/sqlite3_old && \
    ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3

まとめ

yum でアップデートできたら簡単で良かったのですが、無事に最新バージョンに上げることができたので、良しとします。

参考

Amazon Linux 2 に関するよくある質問
https://aws.amazon.com/jp/amazon-linux-2/faqs/

sqlite3を消すとyumが使えなくなる - maru.cc@はてな
http://marucc.hatenablog.com/entry/20080420/1208632521

centos で sqlite3 を削除すると yum が使えなくなる - 年寄りプログラマの備忘録
http://d.hatena.ne.jp/kawabes/20110921/1316577549

SQLite Installation
https://www.tutorialspoint.com/sqlite/sqlite_installation.htm

SQLite Download Page
https://www.sqlite.org/download.html

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