Phase 7. 배포 환경 구성 작업 진행
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.next
|
||||||
|
.pnpm-store
|
||||||
|
.turbo
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
.claude
|
||||||
|
coverage
|
||||||
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
README.md
|
||||||
|
docs
|
||||||
@@ -3,3 +3,15 @@ DATABASE_URL="mysql://USER:PASSWORD@127.0.0.1:3306/chocomae"
|
|||||||
AUTH_SECRET="replace-with-local-secret"
|
AUTH_SECRET="replace-with-local-secret"
|
||||||
NEXTAUTH_SECRET="replace-with-local-secret"
|
NEXTAUTH_SECRET="replace-with-local-secret"
|
||||||
NEXTAUTH_URL="http://localhost:3001"
|
NEXTAUTH_URL="http://localhost:3001"
|
||||||
|
|
||||||
|
# Production example (.env.production)
|
||||||
|
# DATABASE_URL="mysql://USER:PASSWORD@AWS_EC2_HOST:3306/chocomae"
|
||||||
|
# AUTH_SECRET="replace-with-production-secret"
|
||||||
|
# NEXTAUTH_SECRET="replace-with-production-secret"
|
||||||
|
# NEXTAUTH_URL="http://NAS_HOST_OR_DOMAIN:3001"
|
||||||
|
|
||||||
|
# Stage example (.env.stage)
|
||||||
|
# DATABASE_URL="mysql://USER:PASSWORD@STAGE_DB_HOST:3306/chocomae"
|
||||||
|
# AUTH_SECRET="replace-with-stage-secret"
|
||||||
|
# NEXTAUTH_SECRET="replace-with-stage-secret"
|
||||||
|
# NEXTAUTH_URL="http://STAGE_HOST_OR_DOMAIN:3001"
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
FROM node:22-alpine AS base
|
||||||
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
|
RUN corepack enable
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
FROM base AS deps
|
||||||
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
ENV DATABASE_URL="mysql://build:build@127.0.0.1:3306/chocomae"
|
||||||
|
ENV AUTH_SECRET="build-time-placeholder"
|
||||||
|
ENV NEXTAUTH_SECRET="build-time-placeholder"
|
||||||
|
ENV NEXTAUTH_URL="http://localhost:3000"
|
||||||
|
RUN pnpm prisma generate
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
FROM node:22-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV HOSTNAME=0.0.0.0
|
||||||
|
ENV PORT=3000
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
services:
|
||||||
|
choco-admin:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: choco-admin:latest
|
||||||
|
container_name: choco-admin
|
||||||
|
ports:
|
||||||
|
- "3001:3000"
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-.env.production}
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3000
|
||||||
|
HOSTNAME: 0.0.0.0
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# choco-admin Deployment
|
||||||
|
|
||||||
|
## 1. Production Environment
|
||||||
|
|
||||||
|
Create `.env.production` on the production host. Do not commit it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DATABASE_URL="mysql://CHCOCO_ADMIN_USER:PASSWORD@AWS_EC2_HOST:3306/chocomae"
|
||||||
|
AUTH_SECRET="replace-with-production-secret"
|
||||||
|
NEXTAUTH_SECRET="replace-with-production-secret"
|
||||||
|
NEXTAUTH_URL="http://NAS_HOST_OR_DOMAIN:3001"
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `.env.stage` on the stage host with the same keys and stage-specific values.
|
||||||
|
|
||||||
|
`AUTH_SECRET` and `NEXTAUTH_SECRET` should use the same strong random value per environment for Auth.js compatibility.
|
||||||
|
|
||||||
|
## 2. Synology Container Manager
|
||||||
|
|
||||||
|
1. Copy the repository to the NAS.
|
||||||
|
2. Place `.env.production` in the repository root on the NAS.
|
||||||
|
3. In Container Manager, create a project from `docker-compose.yml`.
|
||||||
|
4. Build and start the project.
|
||||||
|
5. Open `http://NAS_HOST_OR_DOMAIN:3001/login`.
|
||||||
|
|
||||||
|
Equivalent CLI command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
The Docker build uses placeholder build-time environment variables only so Next.js can compile without committing secrets. Runtime values are read from `.env.production` by default.
|
||||||
|
|
||||||
|
To run with stage settings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ENV_FILE=.env.stage docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. AWS EC2 Security Group
|
||||||
|
|
||||||
|
Allow MariaDB only from the Synology NAS public IP.
|
||||||
|
|
||||||
|
- Type: `MYSQL/Aurora`
|
||||||
|
- Protocol: `TCP`
|
||||||
|
- Port: `3306`
|
||||||
|
- Source: `NAS_PUBLIC_IP/32`
|
||||||
|
- Description: `choco-admin Synology NAS`
|
||||||
|
|
||||||
|
Do not open `3306` to `0.0.0.0/0`.
|
||||||
|
|
||||||
|
## 4. Read-Only Rehearsal
|
||||||
|
|
||||||
|
Before enabling approval/rejection operations against production DB:
|
||||||
|
|
||||||
|
1. Create or use a DB account with read-only permissions.
|
||||||
|
2. Set `DATABASE_URL` in `.env.production` to that read-only account.
|
||||||
|
3. Start the container.
|
||||||
|
4. Verify login, maestro list, extension request list, and upgrade request list.
|
||||||
|
5. Switch to the production write-capable choco-admin DB account only after read screens work.
|
||||||
|
|
||||||
|
## 5. Smoke Checks
|
||||||
|
|
||||||
|
After container start:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
docker compose logs -f choco-admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify these routes in the browser:
|
||||||
|
|
||||||
|
- `/login`
|
||||||
|
- `/maestros`
|
||||||
|
- `/extension-requests`
|
||||||
|
- `/upgrade-requests`
|
||||||
@@ -346,11 +346,11 @@ choco-admin/
|
|||||||
|
|
||||||
### Phase 7. 배포 환경 구성
|
### Phase 7. 배포 환경 구성
|
||||||
|
|
||||||
- [ ] Dockerfile (프로덕션용 pnpm 빌드)
|
- [x] Dockerfile (프로덕션용 pnpm 빌드)
|
||||||
- [ ] `docker-compose.yml` (Synology NAS Container Manager용)
|
- [x] `docker-compose.yml` (Synology NAS Container Manager용)
|
||||||
- [ ] AWS EC2 보안그룹 인바운드 설정 (NAS IP → 3306 허용)
|
- [ ] AWS EC2 보안그룹 인바운드 설정 (NAS IP → 3306 허용) — `docs/deployment.md`에 절차 문서화
|
||||||
- [ ] Synology NAS에서 컨테이너 실행 테스트
|
- [ ] Synology NAS에서 컨테이너 실행 테스트 — `docs/deployment.md`에 절차 문서화
|
||||||
- [ ] 운영 DB read-only 리허설 후 변경 기능 활성화
|
- [ ] 운영 DB read-only 리허설 후 변경 기능 활성화 — `docs/deployment.md`에 절차 문서화
|
||||||
|
|
||||||
### Phase 8. 검증 및 안정화
|
### Phase 8. 검증 및 안정화
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
output: "standalone",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "choco-admin",
|
"name": "choco-admin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"packageManager": "pnpm@10.29.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --port 3001",
|
"dev": "next dev --port 3001",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
|
|||||||
Reference in New Issue
Block a user