UKey's Labo

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

動作環境

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

概要

以前、gitリモートリポジトリ、クライアントをCentOS7で構築しましたが、今回は軽量のalpine linuxで行いました。構築する内容は、以下の通り。

ファイル構成

.
├── .ssh
│   ├── id_rsa
│   └── id_rsa.pub
├── cli_Dockerfile
├── docker-compose.yml
├── repositories
│   └── master.git
└── rep_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(リモートリポジトリコンテナ)

FROM alpine:3

RUN apk update && \
    # sshdとopenrc, gitをインストール
    apk add openssh-server openrc git

        # sshdの設定 port22とrootログインを許可
RUN sed -i -e 's/^#*Port 22/Port 22/g' /etc/ssh/sshd_config && \
    sed -i -e 's/^#*PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config &&\
    # openrc設定
    sed -i 's/#rc_sys=""/rc_sys="lxc"/g' /etc/rc.conf &&\
    echo 'rc_provide="loopback net"' >> /etc/rc.conf &&\
    sed -i 's/^#\(rc_logger="YES"\)$/\1/' /etc/rc.conf &&\
    sed -i '/tty/d' /etc/inittab  &&\
    sed -i 's/hostname $opts/# hostname $opts/g' /etc/init.d/hostname &&\
    sed -i 's/mount -t tmpfs/# mount -t tmpfs/g' /lib/rc/sh/init.sh  &&\
    sed -i 's/cgroup_add_service /# cgroup_add_service /g' /lib/rc/sh/openrc-run.sh &&\
    # openrcを有効化、sshdをopenrcに追加、起動
    mkdir -p /run/openrc &&\
    touch /run/openrc/softlevel &&\
    rc-update add sshd &&\
    rc-status &&\
    /etc/init.d/sshd start &&\
    # ユーザ作成、パスワード設定
    adduser -D guser &&\
    echo "guser:d3ck" | chpasswd

# 新たに作成したユーザのホームディレクトリに.sshディレクトリ作成
USER guser
WORKDIR /home/guser/
RUN mkdir ./.ssh

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

USER root

    # 公開鍵のオーナ、パーミッションを変更
RUN chown guser:guser /home/guser/.ssh/authorized_keys &&\
    chmod 600 /home/guser/.ssh/authorized_keys

rep_Dockerfileの補足

以下のコマンドで/etc/ssh/sshd_configを編集し、ssh接続ポートを22、rootログインを拒否に設定しています。

sed -i -e 's/^#*Port 22/Port 22/g' /etc/ssh/sshd_config && \
sed -i -e 's/^#*PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config &&\

openrcはデフォルトのままでは使用できないため、以下のコマンドで有効化しています。openrcは、sshdサービスの起動、再起動に利用します。

# openrc設定
sed -i 's/#rc_sys=""/rc_sys="lxc"/g' /etc/rc.conf &&\
echo 'rc_provide="loopback net"' >> /etc/rc.conf &&\
sed -i 's/^#\(rc_logger="YES"\)$/\1/' /etc/rc.conf &&\
sed -i '/tty/d' /etc/inittab  &&\
sed -i 's/hostname $opts/# hostname $opts/g' /etc/init.d/hostname &&\
sed -i 's/mount -t tmpfs/# mount -t tmpfs/g' /lib/rc/sh/init.sh  &&\
sed -i 's/cgroup_add_service /# cgroup_add_service /g' /lib/rc/sh/openrc-run.sh &&\
# openrcを有効化、sshdをopenrcに追加、起動
mkdir -p /run/openrc &&\
touch /run/openrc/softlevel &&\

openrcにsshdサービスを追加し、起動します。

rc-update add sshd &&\
rc-status &&\
/etc/init.d/sshd start &&\

rootでssh接続しようとすると、パスフレーズのみでなく、パスワードもインタラクティブで入力要求されるため、ssh接続用のユーザを作成します。

# ユーザ作成、パスワード設定
adduser -D guser &&\
echo "guser:d3ck" | chpasswd

cli_Dockerfile(クライアントコンテナ)

FROM alpine:3

RUN apk update && \
    # sshクライアント, sshpass, gitをインストール
    # sshpassはリモートリポジトリの操作で使用
    apk add openssh-client sshpass git

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

    volumes:
      # data volumeを使用する場合は、下記コメントをはずす
      # - storage-repo:/home/guser/repositories/
      - ./repositories:/home/guser/repositories/

    tty: true

    # コンテナ起動後に、sshd再起動
    command: >
      /bin/sh -c
        " \
          /etc/init.d/sshd restart &&\
          /bin/sh
        "

  cli:
    build:
      context: .
      dockerfile: cli_Dockerfile

    command: >
      /bin/sh -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 git init --bare /home/guser/repositories/master.git && \
          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/sh
        "

    tty: true

    # リモートリポジトリ起動後に実行
    links:
      - rep

volumes:
  storage-repo:

docker-compose.ymlの補足

リモートリポジトリコンテナ起動後に、sshdを再起動して、rep_Dockerfileで変更したsshdの設定を有効化しています。

    # コンテナ起動後に、sshd再起動
    command: >
      /bin/sh -c
        " \
          /etc/init.d/sshd restart &&\
          /bin/sh
        "

クライアントコンテナ内のcommandでリモートリポジトリにbareリポジトリを作成するため、リモートリポジトリコンテナを先に起動し、クライアントコンテナを起動するようにしています。

    # リモートリポジトリ起動後に実行
    links:
      - rep

以下のコマンドで、リモートリポジトリにbareリポジトリ作成、クライアントコンテナにローカルリポジトリ作成、gitコンフィグを設定(適当です)、テストでpushするためのファイルaaa.txtを作成、add、コミット、リモートリポジトリ設定まで行っています。

    command: >
      /bin/sh -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 git init --bare /home/guser/repositories/master.git && \
          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/sh
        "

pushまで行いたかったのですが、git push -u origin masterを実行すると、インタラクティブでパスフレーズ入力を求められ、コマンドが止まってしまうため、実現できませんでした。

起動と初回コミット

# コンテナの起動
docker-compose up -d --build
# クライアントコンテナに接続
docker-compose exec cli sh
# ローカルリポジトリまで移動
> cd /home/guser/src

# リモートリポジトリにpush
> git push -u origin master
Enter passphrase for key '/root/.ssh/id_rsa': # ←パスフレーズ入力
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 215 bytes | 107.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://rep:22/home/guser/repositories/master.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.