> ## Documentation Index
> Fetch the complete documentation index at: https://doc.howen.ink/llms.txt
> Use this file to discover all available pages before exploring further.

# 배포

> Vercel, Docker Compose 또는 docker run으로 일본어 문장 분석을 배포합니다.

앱은 Vercel에 배포할 수도 있고, Docker로 자신의 서버에서 실행할 수도 있습니다. AI 코딩 도우미에게 맡기고 싶다면 [AI 에이전트로 배포](/ko/ai-deploy)를 참고하세요.

| 방식                                   | 적합한 경우                     |
| ------------------------------------ | -------------------------- |
| [Vercel](#vercel에-배포)                | 서버가 없고 가장 빠르게 공개하고 싶을 때.   |
| [Docker Compose](#docker-compose-사용) | VPS에서 장기간 운영할 때. 권장 방식입니다. |
| [docker run](#docker-run-사용)         | Compose 파일을 쓰고 싶지 않을 때.    |

## Vercel에 배포

<Steps>
  <Step title="저장소 가져오기">
    아래 버튼을 누르거나 Vercel에서 `cokice/japanese-analyzer`를 가져오세요.

    <Card title="Deploy with Vercel" icon="triangle" href="https://vercel.com/new/clone?repository-url=https://github.com/cokice/japanese-analyzer">
      GitHub 저장소로 새 Vercel 프로젝트를 만듭니다.
    </Card>
  </Step>

  <Step title="환경 변수 설정">
    프로젝트에서 **Settings** → **Environment Variables**를 열고 최소한 `DEEPSEEK_API_KEY`를 추가하세요.

    Gemini 모델이나 Gemini TTS가 필요하면 `GEMINI_API_KEY`도 추가합니다. 접속 비밀번호가 필요하면 `CODE`를 추가합니다. 전체 목록은 [구성](/ko/configuration)을 참고하세요.
  </Step>

  <Step title="다시 배포">
    새 배포를 한 번 실행한 뒤 Vercel이 할당한 도메인을 여세요.
  </Step>
</Steps>

<Tip>
  Vercel CLI를 설치하고 로그인했다면 저장소 디렉터리에서 `vercel`을 실행하고, `vercel env add`로 변수를 추가한 다음 `vercel --prod`로 게시할 수도 있습니다.
</Tip>

## Docker Compose 사용

공식 이미지 `howenhowen/japanese-analyzer`는 `linux/amd64`와 `linux/arm64`를 지원합니다. 컨테이너는 `3002` 포트에서 수신합니다.

<Steps>
  <Step title="디렉터리 준비">
    ```bash theme={null}
    mkdir -p ~/japanese-analyzer && cd ~/japanese-analyzer
    curl -fsSL https://raw.githubusercontent.com/cokice/japanese-analyzer/master/docker-compose.hub.yml -o docker-compose.yml
    ```

    이미 저장소를 복제했다면 그 안의 `docker-compose.hub.yml`을 바로 사용할 수 있습니다.
  </Step>

  <Step title="구성 파일 만들기">
    `.env.production`을 만들고 키를 하나 이상 입력하세요.

    ```env .env.production theme={null}
    DEEPSEEK_API_KEY=your_deepseek_api_key
    GEMINI_API_KEY=
    CODE=
    ```

    다른 사용자가 읽지 못하도록 파일 권한을 제한하세요.

    ```bash theme={null}
    chmod 600 .env.production
    ```
  </Step>

  <Step title="서비스 시작">
    ```bash theme={null}
    docker compose up -d
    ```
  </Step>

  <Step title="확인">
    ```bash theme={null}
    docker compose ps
    docker compose logs --tail 50
    curl -fsS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3002
    ```

    컨테이너 상태가 `running`이고, 로그에 오류가 없고, `curl`이 `200`을 반환하면 배포에 성공한 것입니다. `http://서버IP:3002`를 열어 앱에 접속하세요.
  </Step>
</Steps>

Compose 파일에는 `restart: unless-stopped`가 설정되어 있어 서버가 재시작되면 컨테이너도 자동으로 시작됩니다.

<Accordion title="docker-compose.hub.yml 내용">
  ```yaml theme={null}
  services:
    japanese-analyzer:
      image: ${DOCKER_IMAGE:-howenhowen/japanese-analyzer:latest}
      env_file:
        - .env.production
      environment:
        NODE_ENV: production
        PORT: "3002"
        HOSTNAME: 0.0.0.0
      ports:
        - "3002:3002"
      restart: unless-stopped
  ```

  `DOCKER_IMAGE` 환경 변수를 설정하면 특정 버전 태그나 `sha-<commit>` 태그처럼 다른 이미지 태그를 지정할 수 있습니다. 사용 가능한 태그는 [이미지 태그](/ko/development#이미지-태그)를 참고하세요.
</Accordion>

### 포트 변경

호스트의 `3002` 포트가 이미 사용 중이라면 `ports` 왼쪽의 호스트 포트만 바꾸고 컨테이너 내부 포트는 그대로 두세요.

```yaml theme={null}
ports:
  - "3102:3002"
```

### 소스 코드로 이미지 빌드

저장소의 `docker-compose.yml`은 로컬 `Dockerfile`로 이미지를 빌드합니다.

```bash theme={null}
git clone https://github.com/cokice/japanese-analyzer.git
cd japanese-analyzer
cp .env.production.example .env.production   # 키 입력
docker compose up -d --build
```

## docker run 사용

```bash theme={null}
docker run -d \
  --name japanese-analyzer \
  --restart unless-stopped \
  -p 3002:3002 \
  -e DEEPSEEK_API_KEY="your_deepseek_api_key" \
  -e GEMINI_API_KEY="" \
  -e CODE="" \
  howenhowen/japanese-analyzer:latest
```

Umami가 필요하면 다음을 추가하세요.

```bash theme={null}
  -e NEXT_PUBLIC_UMAMI_SRC="https://cloud.umami.is/script.js" \
  -e NEXT_PUBLIC_UMAMI_WEBSITE_ID="your_umami_website_id" \
```

로그 보기:

```bash theme={null}
docker logs -f japanese-analyzer
```

## 최신 버전으로 업데이트

<Tabs>
  <Tab title="Docker Compose">
    ```bash theme={null}
    cd ~/japanese-analyzer
    docker compose pull
    docker compose up -d
    ```
  </Tab>

  <Tab title="docker run">
    새 이미지를 받고, 기존 컨테이너를 삭제한 다음, 원래 매개변수로 다시 실행하세요.

    ```bash theme={null}
    docker pull howenhowen/japanese-analyzer:latest
    docker rm -f japanese-analyzer
    # 위의 docker run 명령을 다시 실행
    ```

    <Warning>
      `docker rm -f`는 컨테이너를 강제로 삭제합니다. 실행하기 전에 컨테이너 이름을 확인하고 원래 실행 매개변수를 기록해 두세요.
    </Warning>
  </Tab>

  <Tab title="Vercel">
    저장소의 기본 브랜치에 푸시하면 Vercel이 자동으로 다시 배포합니다. Fork를 배포했다면 먼저 upstream 변경 사항을 동기화하세요.
  </Tab>
</Tabs>

## 도메인과 HTTPS 설정

컨테이너가 정상적으로 실행되면 도메인과 HTTPS를 추가할 수 있습니다.

<Steps>
  <Step title="도메인 연결">
    도메인의 A 레코드가 서버의 공인 IP를 가리키도록 설정하세요. 클라우드 보안 그룹과 시스템 방화벽에서 `80`과 `443` 포트를 여세요.
  </Step>

  <Step title="기존 웹 서버 확인">
    ```bash theme={null}
    command -v nginx caddy
    ```

    Nginx나 Caddy가 이미 있다면 그대로 사용하고, 새로 설치하지 마세요.
  </Step>

  <Step title="리버스 프록시 설정">
    <CodeGroup>
      ```caddyfile Caddy theme={null}
      your.domain.com {
          reverse_proxy 127.0.0.1:3002
      }
      ```

      ```nginx Nginx theme={null}
      server {
          listen 80;
          server_name your.domain.com;

          location / {
              proxy_pass http://127.0.0.1:3002;
              proxy_http_version 1.1;
              proxy_set_header Host $host;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_buffering off;
          }
      }
      ```
    </CodeGroup>

    Caddy는 Let's Encrypt 인증서를 자동으로 발급하고 갱신합니다. Nginx를 사용한다면 certbot으로 인증서를 발급하고 HTTP를 HTTPS로 리디렉션하세요.
  </Step>

  <Step title="확인">
    ```bash theme={null}
    curl -I https://your.domain.com
    ```

    정상 상태 코드가 반환되고 인증서가 유효하면 설정이 완료된 것입니다.
  </Step>
</Steps>

<Tip>
  Nginx에서 `proxy_buffering off`를 설정하면 스트리밍 출력이 버퍼링되어 한꺼번에 반환되는 문제를 막을 수 있습니다.
</Tip>

## 직접 수정한 버전 배포

이 프로젝트는 AGPL-3.0-only 라이선스를 따릅니다. 코드를 수정해 네트워크로 다른 사람에게 서비스를 제공한다면 사용자에게 수정 버전의 대응 소스 코드를 제공하고, 화면의 GitHub 소스 코드 링크가 실제 버전을 가리키도록 해야 합니다. 자세한 내용은 [라이선스](/ko/license)를 참고하세요.
