自分用めも

初心者ちっくなプログラムネタを中心に、自分用の覚え書きをメモっていくための場所です。

Docker-composeでNginx+Vue3の環境を構築するメモ

やりたいこと

Vueコンテナでbuildした成果物のdistディレクトリを
Nginxコンテナにマウントしたい

手順概略

  1. Vueアプリケーションをコーディングするための環境構築
    Vite(VueCliより高速なビルドツール)でアプリケーションの初期化を行う
  2. 完成後のgit clone準備
    作成したコードはそのままに、二回目以降のgit clone時はpackage-lock.jsonで必要なモジュールのみ再構築する

前提

ホストのディレクトリ・ファイル構成(初期状態)

  hoge/
    ├─frontend/
    │  ├─app/
    │  └─Dockerfile
    ├─logs
    │  ├─frontend
    │  └─web
    ├─web/
    │  ├─conf/
    │  │  └─nginx.conf
    │  └─Dockerfile
    └─docker-compose.yml

Docker関連ファイル

docker-compose.yml
services:
    # nginx
    web:
        container_name: web_container
        hostname: web_server
        build: ./web
        volumes:
            # ホスト:コンテナ
            - ./web/conf/nginx.conf:/etc/nginx/conf.d/default.conf
            - ./logs/web:/var/log/nginx
            - ./frontend/app/dist:/frontend
        ports:
            - "80:80"
        environment:
            TZ: Asia/Tokyo
    # Vue - TypeScript
    frontend:
        container_name: frontend_container
        hostname: frontend_server
        build: ./frontend
        volumes:
            - ./frontend/app:/app
            - ./logs/frontend:/logs
        # 起動状態を維持する(作業でbashログインするため)
        tty: true

※一箇所だけ存在しないディレクトリ(./frontend/app/dist)を指してますが、docker-compose実行時に作成されます。

web/Dockerfile
FROM nginx:alpine
web/conf/nginx.conf
server {
    # フロントエンド
    listen       80;
    server_name  localhost;

    access_log  /var/log/nginx/static_access.log  main;
    error_log  /var/log/nginx/static_error.log warn;

    add_header Cache-Control no-cache;

    location / {
        alias /frontend/;
    }
}
frontend/Dockerfile
FROM node:18-bullseye-slim

WORKDIR /app

ViteによるVueアプリ生成

ホスト側
# docker-composeでコンテナインスタンス化
docker-compose up -d
# frontendコンテナのbashにログイン
docker exec -it frontend_container /bin/bash
frontendコンテナ内

Dockerイメージの「node:18-bullseye-slim」にて、npmがインストール済み。
Viteの公式サイトに従う。

# WORKDIR(初期ディレクトリ)である/appからrootに移動する
cd ..
# Vueアプリ生成メニュー呼び出し
npm create vite@latest
# 準備済みのappディレクトリをプロジェクトとして指定する
✔ Project name: … app
✔ Target directory "app" is not empty. Remove existing files and continue? … yes
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript

cd app
# 生成されているpackage.jsonに従ってモジュールをインストールする
npm install
# buildでapp/dist下に最終的なHTML、js、cssを生成
npm run build

ここまでで静的なファイルが生成され、nginxから参照可能になる。
ブラウザからlocalhostでvueの初期ページが表示される。

buildした時点でpackage-lock.jsonが生成される。
gitにはnode_modulesを登録する必要はなく、次回以降のclone時は以下のDockerfileを使う。

FROM node:18-bullseye-slim

WORKDIR /app

COPY ./app/*.json ./
RUN npm install

# マウント後に実行される。一行のみ設定可能
#ENTRYPOINT npm run build

ENTRYPOINTを指定するとttyが無視され、コンテナが永続化されない。
本番ではそれで良いが開発時は永続化して欲しいので、コメントアウトしている。