開発環境用のDockerでprivate repositoryにあるgemやnpmパッケージをインストールする

  • 3
    Like
  • 0
    Comment

TL;DR

GitHub向けの独自の認証情報キャッシュを用意する。

git-credential-github-token
#!/bin/sh

echo protocol=https
echo host=github.com
echo username=$GITHUB_USERNAME
echo password=$GITHUB_TOKEN

Dockerfileに以下のような内容を追記し、gitでcloneする際https経由でcloneするようにし、httpsの認証に独自の認証情報キャッシュを使うよう設定する。

Dockerfile
FROM ruby

WORKDIR /app

COPY ./git-credential-github-token /usr/local/bin
RUN git config --global url."https://github.com/YOUR_ORG_NAME/".insteadOf ssh://git@github.com/YOUR_ORG_NAME/ \
  && git config --global credential.helper github-token

GitHubでrepo権限を持ったPersonal Access Tokenを発行する。
https://github.com/settings/tokens

以下のように環境変数でユーザー名とPersonal Access Tokenを渡して実行。

$ docker build .
$ docker run -it -e GITHUB_USERNAME=YOUR_USER_NAME -e GITHUB_TOKEN=YOUR_GITHUB_TOKEN -v .:/app IMAGE bash

bundle install/npm installする

GitHubのprivate repositoryをcloneする際sshではなくhttpsを使う

例えばGemfileに以下のようにgitオプションが指定されていることがあります。

gem :your_gem_name, git: 'ssh://git@github.com/YOUR_ORG_NAME/your_gem_name.git'

sshを使うとGitHubで使っている鍵をDockerコンテナーに渡さないとbundle install出来ません。
鍵にパスフレーズがかかっているとbundle install時にパスフレーズ入力が必要になり不便です。

回避するために色々やりかたがあります。

  • sshをつかわない
  • パスフレーズがない鍵をGitHubに登録して使う
  • docker containerを立ててそこにssh -Aして開発
  • ssh-agentのコンテナを立てておきそこから情報をもらう e.g. https://github.com/nardeas/docker-ssh-agent

ここではsshをつかわない方向で進めていきます。
sshをつかわない方法はいくつかあります。

  • gitの設定を上書きして常にhttpsを使うようにする
  • Gemfileのgitオプションを書き換える

デプロイの都合などでなるべくGemfileを変更したくない場合、gitの設定を上書きして常にhttpsを使うようにするのがお手軽です。

Dockerfileに以下のコマンドを追加します。

$ git config --global url."https://github.com/YOUR_ORG_NAME/".insteadOf ssh://git@github.com/YOUR_ORG_NAME/

このコマンドを実行すると以下のような設定ファイルが作成されます。

~/.gitconfig
[url "https://github.com/YOUR_ORG_NAME/"]
        insteadOf = ssh://git@github.com/YOUR_ORG_NAME/

この設定を行うとGitHubのYOUR_ORG_NAME以下のプライベートなリポジトリをcloneする際に、常にhttpsが使われるようになります。

git config --global credential.helper github-token

privateリポジトリをcloneする場合、GitHubではユーザーの認証が必要です。
privateなgemファイルやnpmパッケージをインストールする際に以下のようなプロンプトが出ます。

Username for 'https://github.com': 

手入力は面倒です。入力する手間を省くため独自の認証情報キャッシュを使って認証の手間を省きます。

参考: Git - 認証情報の保存

今回は以下のような認証情報キャッシュを作成します。
環境変数のGITHUB_USERNAME/GITHUB_TOKENを用いて認証を行います。

git-credential-github-token
#!/bin/sh

echo protocol=https
echo host=github.com
echo username=$GITHUB_USERNAME
echo password=$GITHUB_TOKEN

パスが通っているところにgit-credential-github-tokenを置いて、以下のようなコマンドを叩いて~/.gitconfigに設定を追加します。

$ git config --global credential.helper github-token
~/.gitconfig
[credential]
        helper = github-token

GitHubの認証に使うトークンを発行する

GitHubでrepo権限を持ったPersonal Access Tokenを発行します。
https://github.com/settings/tokens

環境変数経由でGitHubの認証情報を渡す

独自の認証情報キャッシュで使っている環境変数に自身のユーザー名と先程作成したPersonal Access Token設定してコンテナーを起動します。

$ docker run -it -e GITHUB_USERNAME=YOUR_USER_NAME -e GITHUB_TOKEN=YOUR_GITHUB_TOKEN -v .:/app IMAGE bash
root@04d6eff95b41:/app# bundle install

ユーザー名やトークンがhistoryやrcに残るのが嫌なので、僕はenvchainを使って環境変数を設定しています。
https://github.com/sorah/envchain

$ envchain --set myapp GITHUB_USERNAME GITHUB_TOKEN
$ envchain myapp docker run -it -e GITHUB_USERNAME=$GITHUB_USERNAME -e GITHUB_TOKEN=$GITHUB_TOKEN -v .:/app IMAGE bash

実際のdocker-compose.ymlの例

こういう感じです。

docker-compose.yml
version: '3'

services:
  web:
    build: .
    command: sh -c 'bundle check && bundle exec rails s -b 0.0.0.0'
    environment:
      GITHUB_USERNAME: $GITHUB_USERNAME
      GITHUB_TOKEN: $GITHUB_TOKEN
    volumes:
      - .:/app
      - gem-data:/usr/local/bundle
      - npm-data:/app/node_modules

volumes:
  gem-data:
  npm-data:

upする前に以下のような感じでbundle install/npm installしてます。

$ envchain myapp docker-compose build
$ envchain myapp docker-compose run --rm web bash
root@04d6eff95b41:/app# bundle install