DockerfileのWORKDIRに$HOMEと書いても認識されない

環境

$docker --version
Docker version 18.09.0, build 4d60db4

概要

DockerfileのWORKDIRはDockerfileのENVで定義された環境変数しか使えないので下記の2点を考慮する。

ドキュメント

https://docs.docker.com/engine/reference/builder/#workdir

You can only use environment variables explicitly set in the Dockerfile.

build結果

build失敗して気づくパターン

$HOME単体ならbuild失敗して気づける

Dockerfile

FROM alpine
WORKDIR $HOME

docker buildの結果

…
Step 2/5 : WORKDIR $HOME
cannot normalize nothing

build成功して気づかないパターン

定義されていない環境変数+パスが含まれているとbuild時に気づけないので注意
Dockerfile

FROM alpine
WORKDIR $HOME/hoge
RUN pwd

docker buildの結果

Step 3/3 : RUN pwd
 ---> Running in 81645314a99f
/hoge
Removing intermediate container 81645314a99f
 ---> 1f8259c44e59
Successfully built 1f8259c44e59

チーム移行するときに抑えておくべきポイント

概要

チーム移行するときに抑えておくべきポイントをまとめる
システムによって特性は異なるので優先順位や、必要かどうかは変化する

チェックすべきポイント

リポジトリを事前に見せてもらう

これから関わるプロダクトがどういうものか?事前に確認する必要がある。

ナレッジが管理されているか?

チームで活動していく上で必要なドキュメントが揃っているか?更新されているか?参照しやすい・検索しやすい状態になっているか?

各種図が存在するか?更新されているか?

システム構成図、ER図、クラス図、サーバ一覧などがあるか?
pngなど編集できないようなファイル形式で作らない。
ない場合は、システムの理解や問題発見につながるので早めにつくる。

セキュリティ対策できているか?

基本的なセキュリティについて、対策できているならその理由をまとめておく。
対策できていない場合は、ユーザやシステムに被害が出ないように最優先で対応する。

障害は検知できているか?

障害が起きてもわからないという状況をさけるため、障害検知は優先的におこなうべき。

ログ集約・監視はしているか?

「サーバ入ってファイルを見る」のような運用は辛いので、ログ集約・監視はやっておきたい。

パフォーマンスモニタリングできているか?

自分たちのシステムは、普段どれくらいのリクエストが来るか?CPU・メモリ利用率はどれくらいの値か?把握しておくべき。
パフォーマンスの異常を検知することで、障害の早期発見・事前解決につながる。

テストは書いてあるか?

単体テスト結合テスト、統合テストは書いてあるか?

テストが充分でないと起こる不都合について

  • 単体テストの中で外部APIを呼び出したり、DB処理をおこなっているケース
    APIのテスト、DB処理のテストは必要だが、単体テストの中でおこなうと、テスト失敗の原因が分かりづらくなったり、単体テストに時間がかかるので分けるべき。
    さらにこのようテストをCI上でおこなうと、API呼び出しのためのトークンの登録なども必要になってくる。
  • 単体テストが書いていないケース
    コード変更の影響範囲がわかりづらい、結合テストが書いていないので検証に時間と労力がかかる。

CI・CDフローは整っているか?

自動テスト、自動デプロイできるようになっているか?
なるべく短い期間でデプロイするのが理想なので、デプロイに時間がかかったり、ミスが起きやすいフローになっている場合は修正する。

まとめ

これらの問題に対してチーム全体で話し合い、システムがどのような状況なのか?どこまでできるようにするのか?認識を合わせておく必要がある。
そうしないと、開発チーム間で認識の不一致が起きてしまう。

Qiita記事をローカル管理するツールが入門としてよかった話

概要

Goの入門としてQiitaをローカル管理するツールを作った。
リポジトリは以下。
https://github.com/ma-bo-do-fu/qsync
今回はその感想をメモしておく。対象読者はGo言語やツール開発初心者。

環境

$go version
go version go1.10.3 darwin/amd64

モチベーション

  • Goの練習したい
  • Qiita記事をGithub管理したい
  • ドキュメント管理をCIに載せたい

作ったもの

詳細は下記参照。
https://github.com/ma-bo-do-fu/qsync/blob/master/README.md
概要だけ記載する。

$qsync pull

すべての投稿を指定した場所に保存する。

$qsync push /path/to/entry

保存した投稿を更新する。

$qsync post

新規に投稿する。

入門としてよかった点

題材が練習としてちょうどよかった。 今回のツールを通して以下の処理について学ぶことができた。

  • APIクライアント
  • josnやyamlエンコードとデコード
  • 文字列操作
  • ファイル読み書き
  • 日付操作

問題点

画像添付できない

画像添付用のAPIがないので画像が添付できない状態。
運用としてローカルで画像保存用のディレクトリ(例:YYYY/mm/dd/images)を作ってそこで管理し、記事公開時に改めてブラウザ側で添付するなどか…
Qiitaの画像はS3で管理されているので、

$qsync attach 記事ID /path/to/image

とかでS3のURLが返ってきたらローカルで作業が完結できそう。

マークダウンの表示が異なる

VSCodeのマークダウンプレビューととQiitaの編集画面とで表示が異なる。 結局微調整のためにブラウザで編集することに…

感想

  • テストを書かずに開発するのはつらい
    とりあえず動くものを作ろうとテストを書かずに開発したら苦労した。次はテストの書き方を覚える予定。
  • 毎回go build/go installをするのが大変
    コード変更したら自動でビルドとインストールが走るようにしたい。
  • プロジェクトの名前が被っていた
    ツールを作るときはGoogleGithubで検索して被っていないか調べたほうが良い。
  • rangeの書き方が馴染んだ
    tour of goをやっているときにrangeの書き方に戸惑ったが、ツールを書いていたら馴染んだ。
  • gometalinterを早めに入れればよかった
    linterは開発初期から入れるべき。後から入れると修正が大変。
  • ちゃんと設計しないと後からつらくなる
    README駆動開発という言葉もあるように、最初に要件定義を書くと全体の見通しが立ちやすいと思う。

何かのサービスのAPIクライアントを作るのは、その言語に初めて触れるときに良い練習になると感じた。 新しい言語を学びたいけど作るものに困っている方はAPIクライアントにチャレンジしてみるとよいかもしれない。

php artisan migrateでautoload.phpがなくて失敗する

環境

$ php -v
PHP 7.1.10 (cli) (built: Aug 22 2018 18:45:08) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans

発生したエラー

$php artisan migrate

Warning: require(/var/www/app/bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in /var/www/app/bootstrap/autoload.php on line 17

状況

  • /var/www/app/bootstrap/../vendor/autoload.phpが存在しない
  • vendor/は存在する

原因究明

$composer install -vvv

とすることでcomposer installデバッグログが見れる。
すると下記のようなエラーが(docker-comopseで実行していた)

app_1    | 
app_1    |                                                                 
app_1    |   [RuntimeException]                                            
app_1    |   /var/www/app/vendor does not exist and could not be created.  
app_1    |                                                                 
app_1    | 
app_1    | Exception trace:
app_1    |  () at phar:///usr/bin/composer.phar/src/Composer/Util/Filesystem.php:186

解決方法

プロジェクトルート(今回は/var/www/app/)に書き込み権限を与えて解決

IntelliJがシステム環境変数を読み込むタイミングについて

概要

IntelliJがシステム環境変数を読み込むタイミングはIDE起動時。 途中でシステム環境変数を設定した場合はIDE再起動すること。

環境

$go version
go version go1.10.3 darwin/amd64

IntelliJ IDEA 2018.2.1 (Ultimate Edition)
(Goのプラグインを入れている)

再現手順

  1. HOGE="fuga"という環境変数を設定
  2. 以下のコードをIntelliJでctrl+shift+dでデバッグ
package main

import (
    "fmt"
    "os"
)

func main() {
    hoge := os.Getenv("HOGE")
    fmt.Println(hoge)
    fmt.Println("end")
}
  1. 出力結果
end

対応

IDEを再起動する。

感想

焦ってNode.jsで同じコードを書いて確認した。 go runしたらちゃんとシステム環境変数が読み込まれるので、IDEに問題があることに気づけた。

TODO

システム環境変数を更新したら毎回再起動するのは面倒なのでなにかいい方法がないか調べる。

vagrant up時にThe box 'bento/centos-6.8' could not be foundと表示される

問題

vagrant upしようとすると下記メッセージが出て失敗する。

$vagrant up
Bringing machine 'webserver' up with 'virtualbox' provider...
Bringing machine 'database' up with 'virtualbox' provider...
==> webserver: Box 'bento/centos-6.8' could not be found. Attempting to find and install...
    webserver: Box Provider: virtualbox
    webserver: Box Version: >= 0
The box 'bento/centos-6.8' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: ["https://atlas.hashicorp.com/bento/centos-6.8"]
Error: The requested URL returned error: 404 Not Found

https://atlas.hashicorp.com/bentohttps://app.terraform.io/bento にリダイレクトされたので表示されているURLが古いっぽい。

解決方法

vagrantのバージョンをあげる。
アップデート前

$vagrant --version
Vagrant 1.9.3

アップデート後

$vagrant --version
Vagrant 2.1.2

CircleCI上でDockerfileのCMDが動かない

問題

CircleCI上でDockerイメージを使うとDockerfileのCMDが動かない。 ローカルでDockerコンテナを起動するとCMDが動く。

原因

最初のコンテナはcommandを書かないとエントリポイントが動かない https://circleci.com/docs/2.0/configuration-reference/#docker

For primary container (listed first in the list) if no command is specified then command and image entrypoint will be ignored, to avoid errors caused by the entrypoint executable consuming significant resources or exiting prematurely. At this time all steps run in the primary container only.

以下のようにDockerイメージをビルドしてコンテナに入ると、エントリポイントのスクリプトが動いている事がわかる。

$ cat Dockerfile 
FROM selenium/standalone-chrome
$ docker build . -t test:test
…
Successfully built 251941c07ece
Successfully tagged test:test
$ docker run -itd 251941c07ece
2848233eeaed57f855915a9046836f0f193d6bea71daa231df95203d8fbfac09
$ docker exec -it 2848233eeaed57f855915a9046836f0f193d6bea71daa231df95203d8fbfac09 /bin/bash
seluser@2848233eeaed:/$ ps auxw
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
seluser      1  0.2  0.1  20980  3332 pts/0    Ss+  15:44   0:00 /bin/bash /opt/bin/entry_point.sh
seluser     10  0.0  0.0   4500  1616 pts/0    S+   15:44   0:00 /bin/sh /usr/bin/xvfb-run -n 99 --server-args=-screen 0 1360x1020x24 -ac +extension RANDR java -jar /opt/selenium/selenium-server-standalone.jar
seluser     21  0.2  2.0 213644 41396 pts/0    Sl+  15:44   0:00 Xvfb :99 -screen 0 1360x1020x24 -ac +extension RANDR -nolisten tcp -auth /tmp/xvfb-run.JaVrPQ/Xauthority
seluser     26  5.8  2.5 2968504 51176 pts/0   Sl+  15:44   0:01 java -jar /opt/selenium/selenium-server-standalone.jar
seluser     46  0.7  0.1  21188  3668 pts/1    Ss   15:44   0:00 /bin/bash
seluser     53  0.0  0.1  37360  3228 pts/1    R+   15:44   0:00 ps auxw

エントリポイントをたどると以下のようになっている

しかし、CircleCI上で動かすと、selenium-server-standaloneなどが動いていないことが確認できる。

config.yml

version: 2
jobs:
  build:
    docker:
      - image: selenium/standalone-chrome
    steps:
      - checkout
      - run: ps auxw

workflows:
  version: 2
  build_and_test:
    jobs:
      - build

f:id:mMQnaZ7vL2DWkoU:20180712004910p:plain

対応

config.ymlにcommandを追加する。

version: 2
jobs:
  build:
    docker:
      - image: selenium/standalone-chrome
        command: ["/opt/bin/entry_point.sh"]
    steps:
      - checkout
      - run: ps auxw

workflows:
  version: 2
  build_and_test:
    jobs:
      - build