このドキュメントでは、Docker コンテナを GitHub Actions で自動デプロイする設定手順を説明します。
目次
- Docker 設定
- GitHub Actions 設定
- サーバー側の設定
- トラブルシューティング
Docker 設定
Dockerfile(静的サイト + nginx)
静的 HTML を生成し、nginx で配信します。
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run generate
# 静的ファイル配信用のnginx
FROM nginx:alpine
# Nuxt 3 の場合: .output/public
# Nuxt 2 の場合: dist
COPY --from=builder /app/.output/public /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf(SPA 用設定)
SPA では動的ルート(/item/:id など)を index.html にフォールバックさせる必要があります。
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# gzip圧縮
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# SPA用: 存在しないパスは index.html にフォールバック
location / {
try_files $uri $uri/ /index.html;
}
# 静的ファイルのキャッシュ
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
docker-compose-prod.yml(Traefik 連携)
services:
cj_front:
build:
context: .
labels:
traefik.enable: true
traefik.http.routers.cj_front.rule: Host(`your-domain.com`)
traefik.http.routers.cj_front.entrypoints: websecure
traefik.http.routers.cj_front.tls.certresolver: myresolver
traefik.http.routers.cj_front.middlewares: gzip-compress
traefik.http.middlewares.gzip-compress.compress: true
networks:
- traefik-network
restart: always
ports:
- "8003:80"
networks:
traefik-network:
external: true
GitHub Actions 設定
.github/workflows/prod.yml
name: prod
on:
push:
branches: ['master']
workflow_dispatch:
repository_dispatch:
types: [webhook]
concurrency:
group: 'pages'
cancel-in-progress: true
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy Docker Container
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.REMOTE_KEY }}
port: ${{ secrets.REMOTE_PORT }}
script: |
set -e
cd /home/${{ secrets.REMOTE_USER }}/cj_front
git pull
docker compose -f docker-compose-prod.yml build
docker compose -f docker-compose-prod.yml down
docker compose -f docker-compose-prod.yml up -d
docker system prune -a --volumes -f
GitHub Secrets の登録
GitHub CLI を使って登録:
gh secret set REMOTE_HOST --body "xxx.xxx.xxx.xxx"
gh secret set REMOTE_USER --body "username"
gh secret set REMOTE_PORT --body "22"
gh secret set REMOTE_KEY ~/.ssh/your_key/id_rsa
または GitHub Web UI から:
Settings → Secrets and variables → Actions → New repository secret
| Secret名 | 説明 |
|---|---|
REMOTE_HOST | サーバーの IP アドレス |
REMOTE_USER | SSH ユーザー名 |
REMOTE_KEY | SSH 秘密鍵(全文) |
REMOTE_PORT | SSH ポート(通常 22) |
サーバー側の設定
1. リポジトリのクローン
cd /home/username
git clone git@github.com:your-org/your-repo.git cj_front
2. リモート URL を SSH 形式に設定
HTTPS 形式だと GitHub Actions からの git pull で認証エラーになります。
cd /home/username/cj_front
git remote set-url origin git@github.com:your-org/your-repo.git
3. GitHub のホストキーを追加
ssh-keyscan github.com >> ~/.ssh/known_hosts
4. SSH 公開鍵を GitHub に登録
サーバーの公開鍵を確認:
cat ~/.ssh/id_rsa.pub
鍵がない場合は生成:
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
公開鍵を GitHub に登録:
- アカウントレベル (推奨): GitHub → Settings → SSH and GPG keys → New SSH key
- リポジトリレベル : リポジトリ → Settings → Deploy keys → Add deploy key
注意 : 同じ SSH 鍵は GitHub 上で1つのリポジトリまたは1つのアカウントにしか登録できません。複数リポジトリで使う場合はアカウントレベルで登録してください。
5. docker-compose-prod.yml の作成
cp docker-compose-prod.example.yml docker-compose-prod.yml
# Host名を実際のドメインに変更
vim docker-compose-prod.yml
トラブルシューティング
nginx で 404 エラー(SPA)
動的ルート(/item/:id)にアクセスすると 404 になる場合、nginx.conf に以下を追加:
location / {
try_files $uri $uri/ /index.html;
}
GitHub Actions で git pull エラー
エラー : fatal: could not read Username for 'https://github.com'
原因 : リポジトリが HTTPS 形式でクローンされている
解決 : SSH 形式に変更
git remote set-url origin git@github.com:your-org/your-repo.git
エラー : Host key verification failed
解決 : GitHub のホストキーを追加
ssh-keyscan github.com >> ~/.ssh/known_hosts
エラー : Permission denied (publickey)
解決 : サーバーの SSH 公開鍵を GitHub に登録