Skip to content

Instantly share code, notes, and snippets.

@ThinaticSystem
Last active April 16, 2024 16:05
Show Gist options
  • Save ThinaticSystem/94197491c10eccaa186dcc0a7f2367f5 to your computer and use it in GitHub Desktop.
Save ThinaticSystem/94197491c10eccaa186dcc0a7f2367f5 to your computer and use it in GitHub Desktop.
Monorepo with Devcontainer
// ${localWorkspaceFolder}/frontend/.dockerignore
node_modules
.next

単一のDevcontainerコンテナでモノレポなプロジェクトを扱うやつ

といいつつも「Devcontainter + 各プロジェクトのコンテナ」みたいな感じになった
Devcontainer要る?

Containers

devcontainer

開発作業 (コーディング、git、テスト実行等)用のコンテナ
VSCodeから接続されるワークスペースを持つ

workspace/
├─ .devcontainer/
├─ frontend/

workspace/をDevcontainerのworkspaceFolderとして設定する

frontend-dev

next devを実行し続けるコンテナ

app/
├─ node_modules/
├─ src/

app/${localWorkspaceFolder}/frontend/をボリュームマウントする

アスキーアート生やすのに使ったやつ

https://ascii-tree-generator.com/

# ${localWorkspaceFolder}/.devcontainer/compose.yaml
services:
devcontainer:
image: mcr.microsoft.com/devcontainers/base:ubuntu-22.04
volumes:
- ..:/workspace:cached
command: sleep infinity # 何かしら実行させないとすぐ寝ちゃうので。寝ちゃわないようにsleepって紛らわしいかも。
frontend-dev:
build: # frontendディレクトリー内のDockerfileに記載のdevelopmentステージを指定
context: ../frontend
target: development
volumes:
- ../frontend:/app:cached # ${localWorkspaceFolder}/frontend/をapp/にマウントする
ports:
- 3000:3000 # ホスト側のlocalhostへフォワードする
// ${localWorkspaceFolder}/.devcontainer/devcontainer.json
{
"name": "Web App",
"dockerComposeFile": "compose.yaml", // ./compose.yaml
"service": "devcontainer", // VSCodeが接続するコンテナのサービスを指定
"runServices": [ // compose.yamlに記載のサービスのうち立ち上げたいサービスを指定
"devcontainer",
"frontend-dev"
],
"workspaceFolder": "/workspace" // ${localWorkspaceFolder}/をdevcontainerの/workspaceにマウントする
}
# ${localWorkspaceFolder}/frontend/Dockerfile
# [ubuntu-base]
FROM ubuntu:22.04 AS ubuntu-base
# [nodejs-provider]
FROM node:20-slim AS nodejs-provider
RUN --mount=type=cache,target=~/.npm \
npm install -g npm@10.5.2
# [ubuntu-nodejs]
FROM ubuntu-base AS ubuntu-nodejs
# Node.js
COPY --from=nodejs-provider \
/usr/local/include/ /usr/local/include/
COPY --from=nodejs-provider \
/usr/local/lib/ /usr/local/lib/
COPY --from=nodejs-provider \
/usr/local/bin/ /usr/local/bin/
# [dependencies-provider]
FROM ubuntu-nodejs AS dependencies-provider
# catalog
COPY package.json package-lock.json /app/
# Install
WORKDIR /app/
RUN --mount=type=cache,target=~/.npm \
npm ci --include dev
# [build-provider]
FROM ubuntu-nodejs AS build-provider
# dependencies
COPY --from=dependencies-provider \
/app/node_modules/ /app/node_modules/
# sources
COPY . /app/
# Build
WORKDIR /app/
RUN npm run build
# ------------ #
# [production] #
# ------------ #
FROM ubuntu-nodejs AS production
# built
COPY --from=build-provider \
/app/package.json /app/
COPY --from=build-provider \
/app/.next/ /app/.next/
# PM2
RUN \
--mount=type=cache,target=~/.npm \
npm install --global pm2
# Start
WORKDIR /app/
ENTRYPOINT pm2 start npm --name "nextjs" -- start
EXPOSE 3000
# ------------- #
# [development] # <- 本題はここ
# ------------- #
FROM ubuntu-nodejs AS development
# dependencies
# ENTRYPOINTのタイミングで/app/ディレクトリーがホストの内容で上書きされちゃうので
# node_modulesはまだ/app/の中には入れず、ENTRYPOINTのタイミングで別のフォルダからコピーなりシンボリックリンクを作るなりする。
COPY --from=dependencies-provider \
/app/node_modules/ /var/lib/development/node_modules/
# Start
WORKDIR /app/
ENTRYPOINT rm -r /app/node_modules \ # シンボリックリンク作るときにホストからマウントされてきたnode_modulesが邪魔になるため消す。Volumeマウントで特定のディレクトリーを除外する方法調べたけどなんか……なの。
&& ln -s /var/lib/development/node_modules/ /app/node_modules \
&& npm run dev
EXPOSE 3000
// ${localWorkspaceFolder}/frontend/next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
webpackDevMiddleware: (config) => { // volumeオプションをconsistentとかに変えても変更検知できなかったので
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
};
export default nextConfig;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment