UKey's Labo

dockerでgitリモートリポジトリとクライアント(SSH接続)- CentOS

動作環境

環境 バージョン
ホスト macOS Catalina 10.15.1
docker docker desktop for mac 2.1.0.4

概要

gitリポジトリコンテナを作成するにあたり、gitbucketを使用するつもりだったが、コンテナ起動時点でリポジトリが作成されていてほしかったので、自分でリポジトリを作成してみました。構成は以下のようになってます。

PlantUML Syntax:
rectangle docker {
    frame “container : repository” as con1 {
        folder “centos7” as os1 {
            [bare repository] as bare
            [sshd]
        }
    }

    frame “container : client” as con2 {
        folder “centos7” as os2 {
            [local repository] as local
        }
    }

}

sshd -[hidden]down-> bare</p>
<p>local -right-> sshd
sshd  -down–> bare : push

ファイル構成

.
├── .ssh
│   ├── id_rsa
│   └── id_rsa.pub
├── cli_Dockerfile
├── docker-compose.yml
├── repositories
│   └── master.git
└── srv_Dockerfile

repositoriesは永続化したbareリポジトリです。コンテナ起動後に作成されます。

秘密鍵、公開鍵の準備

# .sshフォルダ作成
> mkdir .ssh
# 鍵をrsa形式で作成
> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/user/.ssh/id_rsa): ./.ssh/id_rsa # 上で作った、直下の.sshフォルダに作成する
Enter passphrase (empty for no passphrase): # パスフレーズ入力
Enter same passphrase again: # もう一度同じパスフレーズ入力
Your identification has been saved in ./.ssh/id_rsa.
Your public key has been saved in ./.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:/0BRcVcfyTlHE1WhoPMm9K8jxVnEat6nUynYqxjzKxY [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|           .+.o*#|
|          ...+.*=|
|         +. o.  +|
|        . ++ .   |
|        S.=+*   .|
|         Eo*.+ + |
|         o=  .*  |
|         +=+.+   |
|        ..o== .  |
+----[SHA256]-----+

鍵の確認

> ls -l .ssh
total 16
-rw-------  1 user  staff  1896 11 15 16:33 id_rsa
-rw-r--r--  1 user  staff   416 11 15 16:33 id_rsa.pub

Dockerfile

リモートリポジトリのコンテナをrep_Dockerfile

クライアントのコンテナをcli_Dockerfileに定義します。

rep_Dockerfile

#-------------------------
# リモートリポジトリ コンテナ
#-------------------------
FROM centos:7

RUN yum update -y && \
    # sshdとgitをインストール
    yum install -y openssh-server git && \
    yum clean all

WORKDIR /root

RUN mkdir ./.ssh

WORKDIR /root/.ssh

# 公開鍵をサーバに追加
ADD ./.ssh/id_rsa.pub ./authorized_keys

# port22とrootログインを許可
RUN sed -i -e 's/#Port 22/Port 22/g' /etc/ssh/sshd_config && \
    sed -i -e 's/#PermitRootLogin/PermitRootLogin/g' /etc/ssh/sshd_config

# systemctlを使用するために/sbin/initを使用します
CMD ["/sbin/init"]

rep_Dockerfileの補足

以下で、sshdのconfigを変更しています。

# port22とrootログインを許可
RUN sed -i -e 's/#Port 22/Port 22/g' /etc/ssh/sshd_config && \
    sed -i -e 's/#PermitRootLogin/PermitRootLogin/g' /etc/ssh/sshd_config

これを反映するためのsshd再起動で、以下を使用します。

# systemctlを使用するために/sbin/initを使用します
CMD ["/sbin/init"]

cli_Dockerfile

#-------------------------
# クライアント コンテナ
#-------------------------
FROM centos:7

RUN yum update -y && \
    # sshクライアント, sshpass, gitをインストール
    # sshpassはリモートリポジトリの操作で使用
    yum install -y openssh-clients sshpass git && \
    yum clean all

RUN mkdir /root/.ssh

WORKDIR /root/.ssh

# 秘密鍵
ADD ./.ssh/id_rsa /root/.ssh/
# パスフレーズファイル
ADD ./.ssh/keypass /root/.ssh/

# ローカルリポジトリ用のディレクトリを作成
RUN mkdir -p /home/guser/src

WORKDIR /home/guser/src

docker-compose.yml

version: '3'
services:

  rep:
    build:
      context: .
      dockerfile: rep_Dockerfile

    # 特権許可しないと/sbin/initが起動しない
    privileged: true

    volumes:
      # data volumeを使用する場合は以下を使用
      # - storage-repo:/home/guser/repositories/
      - ./repositories:/home/guser/repositories/

  cli:
    build:
      context: .
      dockerfile: cli_Dockerfile

    command: >
      /bin/bash -c
        " \
          sshpass -f /root/.ssh/keypass -P 'Enter passphrase for key' ssh [email protected] -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no mkdir -p /home/guser/repositories && \
          sshpass -f /root/.ssh/keypass -P 'Enter passphrase for key' ssh [email protected] -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no git init --bare /home/guser/repositories/master.git && \
          mkdir -p /home/guser/src && \
          cd /home/guser/src && \
          git init && \
          git config --global user.email '[email protected]' && \
          git config --global user.name 'Your Name' && \
          echo test > aaa.txt && \
          git add . && \
          git commit -m 'first commit' && \
          git remote add origin ssh://[email protected]:22/home/guser/repositories/master.git && \
          /bin/bash
        "

    # command実行後もコンテナ起動を継続
    tty: true

    # リモートリポジトリ起動後に実行
    links:
      - rep
# data volumeを使う場合は以下を指定しておく
volumes:
  storage-repo:

docker-compose.ymlの補足

インタラクティブが発生するコマンドを実行すると、command内の処理が途中で止まうので、とにかく回避するようにコマンドを実行していってます。git push時にパスフレーズ入力がどうしても発生してしまうため、今回は諦めました。どうしてもやらなければいけない処理でもないので、保留にしてます。

以下のコマンドは、インタラクティブをなんとか躱そうとしていた名残です。

# リモートリポジトリにリポジトリ用ディレクトリ作成
sshpass -f /root/.ssh/keypass -P 'Enter passphrase for key' ssh [email protected] -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no mkdir -p /home/guser/repositories

# リモートリポジトリにbareリポジトリ作成
sshpass -f /root/.ssh/keypass -P 'Enter passphrase for key' ssh [email protected] -i ~/.ssh/id_rsa git init --bare /home/guser/repositories/master.git

上記コマンドでは、リモートリポジトリにログインして、bareリポジトリ用のディレクトリ作成、bareリポジトリの初期化、作成を行っています。

sshpassコマンドの-P 'Enter passphrase for key'でインタラクティブな秘密鍵のパスフレーズ入力をパス、-o StrictHostKeyChecking=noでサーバ証明書をknown_hostsに格納させて、以下の対話が発生するのを回避してます。

The authenticity of host 'repo (192.168.208.2)' can't be established.
ECDSA key fingerprint is SHA256:d7Cf97aAKEYRMYX3TiBEexs5WfpI/eqGcXv3nxQKQNY.
ECDSA key fingerprint is MD5:4f:92:57:bd:6d:d4:c3:39:62:f9:ca:b3:11:5d:cc:75.
Are you sure you want to continue connecting (yes/no)? 

1回目のsshpass ~でサーバ証明書はknown_hostsに格納されているので、2回目は-o StrictHostKeyChecking=noは省いてます。

以下のコマンドでは、ローカルリポジトリの作成、gitconfigでユーザ情報を設定、テスト用のファイルaaa.txtを作成、add、commit、リモートリポジトリの追加、まで行っています。

mkdir -p /home/guser/src && \
cd /home/guser/src && \
git init && \
git config --global user.email '[email protected]' && \
git config --global user.name 'Your Name' && \
echo test > aaa.txt && \
git add . && \
git commit -m 'first commit' && \
git remote add origin ssh://[email protected]:22/home/guser/repositories/master.git && \
/bin/bash

コンテナの起動と初回pushまで

# コンテナ起動
> docker-compose up -d

# クライアントコンテナにログイン
> docker-compose exec cli bash
# commit済みのaaa.txtをリモートリポジトリにpush
> git push -u origin master

Enter passphrase for key '/root/.ssh/id_rsa':  # ← パスフレーズを入力
Counting objects: 3, done.
Writing objects: 100% (3/3), 213 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://[email protected]:22/home/guser/repositories/master.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.