Dockerコンテナ内開発でgitを使用する方法

こんにちは!
seiです!

 

Dokcerコンテナを仮想環境としてチーム開発するときにgitが使えなくて、てこずったので備忘録です!

環境

ホストマシン: WSL:Ubuntu 20.04.2 LTS
VSCodeの拡張機能「dev container」を用いて開発
コンテナの起動はdocker-compose.yamlファイルから

 

 

Dockerコンテナ内開発でgitを使用する方法

コンテナ内でgitを使う場合の選択肢は二つあるかと思います。

  • ssh-agentやkeychainを用いて、接続先コンテナにも秘密鍵の情報を持っていく
  • コンテナにgitをインストールし、秘密鍵などの接続情報もコンテナ内に持っていく

ビルドしてDockerイメージにしない場合は関係ないですが、コンテナ内に秘密鍵などの秘匿情報を持っていくのは危ないので、ssh-agentでやる方法を推奨します!

dev containerの公式ドキュメントにも実は記載があります。
https://code.visualstudio.com/remote/advancedcontainers/sharing-git-credentials

 

ssh-agentを接続元ローカルサーバで起動しておけば、接続先リモートサーバでもssh-agentを経由して秘密鍵を使用することができます。これによって例えば、ローカルサーバでgit cloneしたい場合などにリモートサーバ上に鍵を保存しなくて済むのでセキュアになります。

 

ssh-agentを使ってもいいのですが、shellを新しく開くたびにssh-agentの新しいプロセスが起動して嫌なので、
今回はkeychainを使ったやり方を紹介します。
keychainはssh-agentのラッパーツールで、ssh-agentのプロセスを使いまわしてくれます。

key chainのインストール

sudo apt update
sudo apt install keychain

 

bash_profileに以下を記載

eval $(keychain --eval --agents ssh some_ssh_key1 some_ssh_key2)

.sshディレクトリ下にある使いたい秘密鍵を列挙すれば、keychainにssh鍵を追加することができます。
必要な環境変数の設定も上記コマンドで自動的に登録してくれます。

 

設定はこれだけです!
これでローカルで使用している秘密鍵を共有して、コンテナ内でも使用できます!

秘密鍵などの接続情報もコンテナ内に持っていく

推奨される方法ではありませんが、コンテナ内に直接秘密鍵を持っていく方法も紹介します。

 

Dockerfile

from python3.8

RUN apt-get update && apt-get install -y git

ENTRYPOINT ["/bin/bash"]

 

コンテナ内にapt install でgitをインストールしましょう。
また、コンテナ内でシェルが開けるようにENTRYPOINTを設定しています。

 

docker-compose.yamlファイル

version: '2'
services:
  api:
    build: . //このディレクトリ内にあるdockerファイルを用いる
    ports:
      - "8000:8000"
    volumes:
      - ./:/var/www/

    tty: true
    stdin_open: true

コンテナ内でbashシェルを用いて対話的に操作したいのでtty:trueとstdin_open:trueを設定します。

コンテナに入ってバックエンドサーバを立ち上げたかったのでこのようにしています。

 

githubに接続する設定を行う

 

githubからpushしたり、pullしたりする場合はsshの秘密鍵が必要です。

しかし、以下のようにしても秘密鍵はCOPYされません。

COPY .ssh var/www/.ssh
# .ssh
- .ssh
   - id_rsa.pem
   - known_hosts


# /var/www/.ssh
- .ssh
    - known_hosts   //  id_rsa.pemはコピーされない!

これは秘密鍵が含まれたイメージを誤って配布しないための仕様です。
もし、秘密鍵が含まれたdockerイメージをdocker_hubなどに公開してしまったら…

業務でやらかしたと思うと震えが止まりません(笑)

 

bind mountを使おう!
なので、bind mountを使ってssh秘密鍵をコンテナ内にもっていきましょう。
/home/user/.sshにある秘密鍵をコピーしてきます。
僕のプロジェクトの構成は以下のような感じでした。

/project-root
│
├── .devcontainer
│   ├── devcontainer.json
│
├── docker-compose.yaml
├── Dockerfile
│
├── .ssh
│   ├── id_rsa.pem
│   ├── config
│
└── app
    ├── APIサーバのディレクトリ達

使用する秘密鍵を指定する

git pushやgit pullでgithubと通信するときに使用される秘密鍵は、デフォルトでは.sshフォルダの中を見に行きます。
コンテナ内だとrootユーザでログインするので、以下のフォルダの秘密鍵を使用します。
/root/.ssh/id_rsa

先ほどのプロジェクトルートにある
.sshフォルダの中にconfigファイルを作って使用する秘密鍵を指定してあげます。

.ssh/config

Host github.com
        HostName github.com
        IdentyFile /var/www/.ssh/id_rsa
これをコンテナ作成時にコンテナ内の/root/.ssh/configにCOPYするために、Dockerファイルを修正します。
from python3.8 

RUN apt-get update && apt-get install -y git

// 設定ファイルをコピーする
COPY ./ssh/conig /root/.ssh/config 

ENTRYPOINT ["/bin/bash"]
DockerファイルでCOPYできるのはDockerファイルがあるディレクトリ以下なので、気を付けてください。相対パスで上の階層を通ることはできません。

 

お疲れ様でした!これでコンテナ内でgitが使えるはずです!

コンテナ内に秘密鍵をもっていくのは結構大変でした。僕は秘密鍵がコピーできないことを知らなかったので、そこではまってしまいました。
ssh-agentやkeychainが使える場合はそちらがおすすめです。

今までのプロジェクトでは、dockerコンテナを仮想マシンとして使っているケースはまだまだ少ないように感じます。
チームメンバーが全員VScodeを使っているのであれば、コンテナを仮想マシンとして使用することで拡張機能までそろえることができるのでとても便利です。

virtual box等に比べてもOSはホストマシン側にあるDokcerのほうがメモリ使用量も少なく、軽いのでとても使いやすいです。

もっとdockerコンテナでの開発が進めば良いなと思っています。

プログラミング学習方法を発信してます!