Docker＋Next.js+GitHub ActionsでGitHub Pagesに静的ページをデプロイするまでの手順メモ

# 概要
GitHub Actionsを用いてDockerで構築したNext.jsアプリのSSGで静的ファイルを生成し、GitHub Pagesへデプロイする手順のメモです。



# 手順
## 各種ファイル作成
### Dockerfile
```Dockerfile:Dockerfile
FROM node:lts-buster-slim
WORKDIR /app
```
### docker-compose
```docker-compose:docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    tty: true
    volumes:
      - .:/app
    environment:
     - WATCHPACK_POLLING=true
    ports:
      - "1313:3000"
    command: sh -c "cd src && npm run dev"
```
### GitHub Actions用yml
```:nextjs-deploy.yml
name: nextjs-deploy

on:
  push:
    branches:
      - "main"

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  build:
    name: Build
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3
      - name: Install packages
        run: docker compose run --rm app sh -c "cd src && npm install" 
      - name: Build and export
        run: docker compose run --rm app sh -c "cd src && npm run build" 
      - name: add nojekyll
        run: touch src/out/.nojekyll
      - uses: actions/upload-pages-artifact@v1
        with:
          path: "src/out"

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1
```
### フォルダ構成
```
nextjs-app/
├ Dockerfile
├ docker-compose.yml
└ .github/
 　└ workflows/
 　　　└ nextjs-deploy.yml/
```

## アプリ作成からデプロイまで

### Next.jsアプリ作成
nextjs-appディレクトリで下記コマンドを実行する。
```
docker-compose build
docker-compose run --rm app sh -c 'npx create-next-app src --typescript'
```
create-next-app実行後のフォルダ構成。
```
nextjs-app/
├ Dockerfile
├ docker-compose.yml
├ src
│  ├ pages
│  │  └ ・・・
│  ├ package.json
│  ├ next.config.js
│  ・・・
└ .github/
 　└ workflows/
 　　　└ nextjs-deploy.yml/
```

### package.json
2. package.jsonを以下のように変更。
```diff:package.json
"name": "src",
"version": "0.1.0",
"private": true,
"scripts": {
  "dev": "next dev",
- "build": "next build",
+ "build": "next build && next export",
  "start": "next start",
  "lint": "next lint"
},
"dependencies": {
  "@types/node": "18.11.9",
  "@types/react": "18.0.25",
```
これによってビルド時にoutディレクトリへHTML等の静的ファイルが出力される。

### next.config.js
next.config.js内の`module.exports`を以下のように変更。
```diff:next.config.js
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,

- module.exports = nextConfig
+ module.exports = {
+   images: {
+     unoptimized: true,
+   },
+   basePath: '/[GitHubのリポジトリ名]',
+ }
```
`unoptimized` : 設定なしの場合、buildコマンド実行時のexportでoutディレクトリにファイルが正しく出力されないため追加。[^1]
`basePath` : GitHub Pagesにデプロイした時にHTMLのhrefの参照が正しくなるよう追加。

### GitHub Pagesへのデプロイ
ソースをPushするリポジトリのPagesの設定から、Build and deploymentのSourceを`GitHub Actions`に変更しておく。
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119044/89eed562-9cc3-ac77-87bd-e0214e4f298f.png)
nextjs-appフォルダをリポジトリにPushする。Push後に自動でデプロイが開始される。

デプロイ完了後、デプロイ先のURLにアクセスすると下記画面が表示される。
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119044/364208d0-8e66-2af8-74ce-6ec1be5a1be1.png)

## 参考にしたページ
* https://zenn.dev/temple_c_tech/articles/setup-next-on-docker
* https://qiita.com/manten120/items/87e9e822800403904dc8
* https://nextjs.org/docs/advanced-features/static-html-export
* https://nextjs.org/docs/api-reference/next.config.js/basepath

[^1]:https://github.com/vercel/next.js/issues/40240