Dockerとnginxを使用してアプリをデプロイする

## はじめに

本記事では、Docker と Nginx を使ってデモアプリをデプロイする手順を解説します。この手順に沿って進めることで、初心者でも基本仕組みの理解を深めることができます。

## 前提条件

すでに Docker がインストールされていることを前提としています。ターミナルで以下のコマンドを実行して、お使いの Docker のバージョンを確認することができます。

```bash
docker -v

# 出力例
# Docker version 27.4.1, build b9d17ea
```

## 基本操作

### Docker イメージの取得

まず、Docker Hub から最新の nginx の Docker イメージを取得します。

```bash
docker pull nginx
# または
docker pull nginx:latest
```

取得済みのイメージは `docker images` コマンドで確認できます。

```bash
docker images

# 出力例
# REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
# nginx               latest              1530d85bdba6        2 months ago        197MB
```

### nginx コンテナを実行する

取得したイメージを使用して、コンテナを作成・実行します。

```bash
docker run --name my-nginx -d -p 8080:80 nginx:latest
```

各オプションの説明：
- `-d`: デタッチドモード
- `-p 8080:80`: ホストマシンの8080ポートをコンテナの80ポートにマッピング
- `--name my-nginx`: コンテナに名前を付ける（後で管理しやすくするため）
- `nginx:latest`: 使用するイメージ名

> デタッチドモード( detached mode ) でコンテナを起動すると、ターミナルはコンテナの標準出力に接続されず、コマンド実行後すぐにプロンプトに戻ります。つまり、コンテナはバックグラウンドで動作し続け、ユーザーは同じターミナルで他の作業を続けることができます。

起動後、実行中のコンテナは `docker ps` コマンドで確認できます。

```bash
docker ps
```

### ローカルIPアドレスの確認

Mac でプライベート IP アドレスを確認するには：

```bash
ipconfig getifaddr en0
# 出力例: 172.16.0.93
```

ブラウザで以下のURLにアクセスすると、デフォルトの nginx ページが表示されます。
👉 http://localhost:8080
👉 http://172.16.0.93:8080/

### コンテナの停止

注意：イメージ名ではなくコンテナ名（`--name` オプションで指定した名前）です。

```bash
docker stop <容器名/容器ID>
# 例: docker stop my-nginx

# 実行完了したら、容器名を出力します。
# 例: my-nginx
```
コンテナが停止したことを確認するには：

```bash
docker ps
```

停止したコンテナは表示されなくなり、ブラウザを更新すると、先ほどまで表示されていたページにアクセスできなくなります。

## アプリのデプロイ

### Viteでアプリ新規作成

```bash
npm create vite@latest

# （必要に応じて調整してください）
# プロンプトに従って設定：

◇  Project name:
│  docker-nginx-demo
│
◇  Select a framework:
│  Vanilla
│
◇  Select a variant:
│  TypeScript

# プロジェクトに移動してパッケージをインストールし、サーバーを起動：
cd docker-nginx-demo
npm install
npm run dev
```

### プロジェクトの編集

`main.ts` ファイルを適当に変更してみます：

```typescript
import './style.css'

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
  <div>
    <h1>Hello Docker & Nginx (gen)</h1>
  </div>
`
```

ブラウザで `http://localhost:5173/` にアクセスし、変更が反映されているかを確認。

### Docker 設定の追加

ルートのディレクトリに `Dockerfile` を作成します：

```dockerfile
# ステップ1: Viteアプリのビルド
FROM node:18-alpine AS builder

WORKDIR /app

# 必要なファイルのみコピー
COPY package.json package-lock.json* ./
RUN npm install

COPY . .
RUN npm run build

# ステップ2: nginxを使用してビルド出力を配信
FROM nginx:alpine

# デフォルトのnginx設定を削除
RUN rm /etc/nginx/conf.d/default.conf

# カスタムnginx設定をコピー
COPY nginx/docker.nginx.conf /etc/nginx/conf.d/default.conf

# ビルド出力をNginxの公開フォルダにコピー
COPY --from=builder /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
```

次に、`nginx/docker.nginx.conf` ファイルを作成します：

```nginx
server {
  listen 80;
  server_name localhost;

  root /usr/share/nginx/html;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html;
  }
}
```

### Dockerコンテナのビルドと実行

ルートのディレクトリで以下のコマンドを実行します：

```bash
# プロジェクトのルートから
docker build -t docker-nginx-demo .

# ポート8080で実行:
docker run -p 8080:80 docker-nginx-demo
# または、デタッチドモードで実行:
docker run -d -p 8080:80 docker-nginx-demo
```

冒頭の操作と同様に、下記URLにアクセスすると、デプロイしたアプリケーションが表示されます：
👉 http://localhost:8080
👉 http://172.16.0.93:8080/

## 実行中のアプリの停止

通常で`docker run -p 8080:80 <--name>` 実行した場合は、`Ctrl + C` で停止できます。

デタッチドモード`-d`で実行した場合：

```bash
# コンテナIDまたは名前を確認
docker ps
# 停止
docker stop <容器名/容器ID>
```

## コード変更後の再デプロイ

```bash
# Viteプロジェクトとdockerイメージの再ビルド
docker build -t docker-nginx-demo .

# 古いコンテナを停止（実行中の場合）
docker ps
docker stop <容器名/容器ID>

# 新しいコンテナを実行
docker run -d -p 8080:80 docker-nginx-demo
```

## docker-compose の使い方

`docker-compose.yml` は、複数の Docker コンテナを定義・管理するための YAML 設定ファイルです。メリットは：
> 長い docker run コマンドの入力を避けられる
ビルド/実行を簡単に管理できる
複数のサービス（フロントエンド、バックエンド、インフラ）を管理できる
チーム間に設定を共有できる

プロジェクトのルートに `docker-compose.yml` を作成します：

```yaml
services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    container_name: vite-nginx-app
```

実行：

```bash
# 起動のみ（ビルドなし）
docker-compose up

# 起動とビルド
docker-compose up --build
```

停止と削除：

```bash
docker-compose down
```

## 終わり

最後までお読みいただき、ありがとうございました。