Ansibleでプライベートリポジトリをクローン・ビルドしてDockerを実行する
はじめに
プライベートGitHubリポジトリのコードを自動デプロイして実行する作業は多くの開発・運用現場で必要とされます。本記事では次の作業を自動化する手順を記録します。
- GitHubプライベートリポジトリのクローン
- Dockerfileからのイメージビルド
- Dockerコンテナの実行
- GitHub Actionsによる定期実行
※Terraform/AnsibleでのVM構築をしており、具体的なやりたいこと(アプリケーション)を別リポジトリにまとめている前提です。主にAnsible関連の内容になりますが、GitHub Actionsでの自動化の流れでの開発ですので、そちらの内容も記載しています。
環境準備
使用ツール:
- Ansible
- Docker
- GitHub Actions
- dotenvx(環境変数管理)
認証方法
GitHubプライベートリポジトリへのアクセスには2種類の認証方法があります。
認証方法 | メリット | デメリット |
---|---|---|
HTTPS | シンプルな設定、ファイアウォール対応 | 認証情報管理、トークン期限切れ |
SSH | セキュリティ強化、鍵の管理 | 初期設定複雑 |
本記事ではSSH認証を使用します。
Ansibleプレイブックの実装
SSHキー認証の設定
まず、SSHキーを使ってGitHubプライベートリポジトリにアクセスするためのAnsibleプレイブックを作成します。
※Githubの対象リポジトリにDEPLOY KEYにSSHのPUBIC KEY登録がされていること。
---
- name: GitHubプライベートリポジトリの管理(SSH認証)
hosts: your_target_servers
vars:
# 環境変数から情報を取得
github_repo: "{{ lookup('env', 'GITHUB_REPO') }}"
github_branch: "{{ lookup('env', 'GITHUB_BRANCH') | default('main') }}"
repo_dest: "{{ lookup('env', 'REPO_DEST') }}"
ssh_private_key: "{{ lookup('env', 'SSH_PRIVATE_KEY') }}"
ssh_public_key: "{{ lookup('env', 'SSH_PUBLIC_KEY') }}"
# 実行ユーザーの情報
target_user: "{{ ansible_user | default('ubuntu') }}"
target_user_home: "/home/{{ target_user }}"
# Docker関連の変数
docker_image_name: "{{ lookup('env', 'DOCKER_IMAGE_NAME') }}"
docker_image_tag: "{{ lookup('env', 'DOCKER_IMAGE_TAG') | default('latest') }}"
slack_webhook_url: "{{ lookup('env', 'SLACK_WEBHOOK_URL') }}"
tasks:
- name: 必要なパッケージをインストール
package:
name:
- git
- docker.io
state: present
become: yes
- name: DockerサービスがRunningか確認
service:
name: docker
state: started
enabled: yes
become: yes
- name: Dockerグループが存在することを確認
group:
name: docker
state: present
become: yes
- name: ユーザーをdockerグループに追加
user:
name: "{{ target_user }}"
groups: docker
append: yes
become: yes
- name: SSHディレクトリが存在することを確認
file:
path: "{{ target_user_home }}/.ssh"
state: directory
mode: '0700'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
- name: 環境変数からSSHプライベートキーを作成
copy:
content: |
{{ ssh_private_key }}
dest: "{{ target_user_home }}/.ssh/id_github"
mode: '0600'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
when: ssh_private_key is defined and ssh_private_key != ""
- name: 環境変数からSSH公開キーを作成(必要な場合)
copy:
content: "{{ ssh_public_key }}"
dest: "{{ target_user_home }}/.ssh/id_github.pub"
mode: '0644'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
when: ssh_public_key is defined and ssh_public_key != ""
- name: SSHの設定ファイルを作成
blockinfile:
path: "{{ target_user_home }}/.ssh/config"
create: yes
mode: '0644'
owner: "{{ target_user }}"
group: "{{ target_user }}"
block: |
Host github.com
IdentityFile {{ target_user_home }}/.ssh/id_github
IdentitiesOnly yes
become: yes
- name: GitHubのホスト鍵を取得
command: ssh-keyscan -t rsa github.com
register: github_host_key
check_mode: no
changed_when: false
- name: known_hostsファイルを作成
copy:
content: "{{ github_host_key.stdout }}"
dest: "{{ target_user_home }}/.ssh/known_hosts"
mode: '0644'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
- name: リポジトリのクローンディレクトリを作成
file:
path: "{{ repo_dest }}"
state: directory
mode: '0755'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
- name: GitHubプライベートリポジトリのクローン実行
git:
repo: "git@github.com:{{ github_repo }}.git"
dest: "{{ repo_dest }}"
version: "{{ github_branch }}"
update: yes
accept_hostkey: yes
key_file: "{{ target_user_home }}/.ssh/id_github"
become: yes
become_user: "{{ target_user }}"
- name: Dockerイメージをビルド
command:
cmd: docker build -t {{ docker_image_name }}:{{ docker_image_tag }} .
chdir: "{{ repo_dest }}"
become: yes
register: docker_build_result
changed_when: docker_build_result.rc == 0
- name: Dockerコンテナを実行
command:
cmd: >
docker run --rm
-e SLACK_WEBHOOK_URL={{ slack_webhook_url }}
{{ docker_image_name }}:{{ docker_image_tag }}
chdir: "{{ repo_dest }}"
become: yes
このプレイブックは以下の処理を行います:
- 必要なパッケージ(GitとDocker)のインストール
- Dockerサービスの起動と自動起動設定
- SSHディレクトリの作成と設定
- 環境変数からSSHキーを取得し、ファイルとして保存
- GitHubのホスト鍵を取得して登録
- GitHubのプライベートリポジトリをクローン
- Dockerイメージのビルド
- 必要な環境変数を設定してDockerコンテナを実行
プレイブックの実行
Ansibleプレイブックを実行するには:
ansible-playbook -i inventory.ini playbook.yml
GitHub Actionsによる自動化
次に、GitHub Actionsを使ってこのプロセスを自動化します。以下のワークフローファイルを作成します。実行イメージにはansibleやdotenvxがインストールされているものを使用しています:
name: Deploy and Run Docker Container
on:
schedule:
- cron: '0 8 * * *' # 毎日午前8時に実行
workflow_dispatch: # 手動実行も可能
jobs:
deploy:
runs-on: ubuntu-latest
container: ghcr.io/xxx/xxx # ansibleとdotenvx使用の実行イメージ
env:
# 共通の環境変数(Variables/Secretsから取得)
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
DOCKER_IMAGE_NAME: my-app
DOCKER_IMAGE_TAG: latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
- name: Run Ansible playbook
run: dotenvx run -f .env.encrypted -- ansible-playbook -i inventory.ini playbook.yml
env:
ANSIBLE_HOST_KEY_CHECKING: False
このワークフローは以下を行います:
- 毎日午前8時に自動実行、または手動で実行可能
- 必要なPythonパッケージとdotenvxをインストール
- SSHキーを設定
- 環境変数を表示して確認
- dotenvxを使用してAnsibleプレイブックを実行
GitHub ActionsでのSecret/Variables管理
GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」で、以下の値を設定します:
Secrets(暗号化されて保存されます):
-
SSH_PRIVATE_KEY
- GitHubへのアクセス用のSSH秘密鍵 -
SLACK_WEBHOOK_URL
- Slack通知用のWebhook URL
Variables(平文で保存されます):
トラブルシューティング
SSHキーのフォーマット問題
SSHキーを環境変数として設定し、それをファイルに書き込む際に「error in libcrypto」エラーが発生する場合があります。これは主にキーの最後の改行が失われていることが原因です。
解決策:
YAMLのリテラルスタイル(|
記号)を使用して改行を保持します:
- name: 環境変数からSSHプライベートキーを作成
copy:
content: |
{{ ssh_private_key }}
dest: "{{ target_user_home }}/.ssh/id_github"
mode: '0600'
owner: "{{ target_user }}"
group: "{{ target_user }}"
become: yes
Dockerの権限問題
「permission denied while trying to connect to the Docker daemon socket」というエラーが発生する場合、Dockerデーモンソケットへのアクセス権がないことが原因です。
解決策:
- ユーザーをdockerグループに追加
- Dockerソケットのパーミッションを直接変更
- 新しいSSHセッションを開始して変更を反映
- name: Dockerグループが存在することを確認
group:
name: docker
state: present
become: yes
- name: ユーザーをdockerグループに追加
user:
name: "{{ target_user }}"
groups: docker
append: yes
become: yes
- name: Docker設定の変更を反映するために新しいSSHセッションを作成
meta: reset_connection
まとめ
この記事では、Ansibleを使用したGitHubプライベートリポジトリのクローン、Dockerイメージのビルド・実行、そしてGitHub Actionsによる自動化手順を紹介しました。
ポイント:
- SSH認証によるGitHubアクセス
- GitHub ActionsのSecrets/Variables活用
- SSHキーのフォーマット、Docker権限問題への対処
この方法で開発からデプロイまでの自動化を実現し、運用効率を向上させることができます。
Discussion