Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/devfactory-homepage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: ๐Ÿš€ DevFactory Homepage Deploy
run-name: ๐Ÿš€ Deploying to Production by @${{ github.actor }}

on:
push:
branches:
- main
paths:
- 'platform/**'
- '.github/workflows/devfactory-homepage.yml'
workflow_dispatch:

# ๊ฐ™์€ ๋ธŒ๋žœ์น˜ ๋™์‹œ ์‹คํ–‰ ์‹œ ์ด์ „ ์žก ์ทจ์†Œ(๊ฒฝ์Ÿ ๋ฐฐํฌ ๋ฐฉ์ง€)
concurrency:
group: DevFactory-homepage-${{ github.ref }}
cancel-in-progress: true

jobs:
deploy-prod:
if: github.ref_name == 'main'
name: ๐Ÿš€ Deploy DF-platform (Production)
runs-on: oracle
environment: platform
defaults:
run:
working-directory: ./platform
steps:
- uses: actions/checkout@v4

- name: Write .env (prod)
run: |
cat > .env <<'EOF'
APP_HOST=${{ vars.APP_HOST }}
DATABASE_URL=${{ secrets.DATABASE_URL }}
EOF

- name: Build & up (prod)
run: |
set -euxo pipefail
docker compose -p df-platform-main config -q
docker compose -p df-platform-main down --remove-orphans
docker compose -p df-platform-main up -d --build --remove-orphans
docker image prune -f --filter "label=org.pseudolab.project=devfactory-platform"
6 changes: 3 additions & 3 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Highlight activities of DevFactory ๐Ÿค—
<tr>
<td align="center" width="200" valign="top">
<b>Soohyun Kim</b><br>
<img src="docs/imgs/members/soohyun.png" height="180px"><br>
<img src="platform/frontend/public/members/soohyun.png" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-TPM-94A3B8">
<img src="https://img.shields.io/badge/-INFRA-94A3B8"><br>
Expand All @@ -76,7 +76,7 @@ Highlight activities of DevFactory ๐Ÿค—
</td>
<td align="center" width="200" valign="top">
<b>Yesin Kim</b><br>
<img src="docs/imgs/members/yesin.jpg" height="180px"><br>
<img src="platform/frontend/public/members/yesin.jpg" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-BE-0891B2"><br>
<img src="https://img.shields.io/badge/-10th-DAA520">
Expand All @@ -86,7 +86,7 @@ Highlight activities of DevFactory ๐Ÿค—
</td>
<td align="center" width="200" valign="top">
<b>Seungkyu Kim</b><br>
<img src="docs/imgs/members/seungkyu.jpg" height="180px"><br>
<img src="platform/frontend/public/members/seungkyu.jpg" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-FE-60A5FA"><br>
<img src="https://img.shields.io/badge/-10th-DAA520">
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
## ๐ŸŒŸ ํ”„๋กœ์ ํŠธ
DevFactory์˜ ์ฃผ์š” ํ™œ๋™ ๋‚ด์—ญ์ž…๋‹ˆ๋‹ค ๐Ÿค—
* **๐Ÿณ ๊ธฐ์ˆ  ํŠœํ† ๋ฆฌ์–ผ (Tutorials)**
* Docker, Git, LLM ๋“ฑ ์‹ค์Šต ์ค‘์‹ฌ์˜ ์ฝ˜ํ…์ธ ์™€ ์˜คํ”„๋ผ์ธ ์›Œํฌ์ˆ์„ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค.
* Docker, Git, LLM ๋“ฑ ์‹ค์Šต ์ค‘์‹ฌ์˜ ์˜จ๋ผ์ธ ์ฝ˜ํ…์ธ ์™€ ์˜คํ”„๋ผ์ธ ์›Œํฌ์ˆ์„ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค.
* [๐Ÿ”— ํŠœํ† ๋ฆฌ์–ผ ๋ณด๊ธฐ](https://pseudo-lab.github.io/DevFactory/intro.html)

* **๐ŸŽฎ ๋„คํŠธ์›Œํ‚น ํ”„๋กœ๊ทธ๋žจ (BINGO)**
Expand All @@ -60,7 +60,7 @@ DevFactory์˜ ์ฃผ์š” ํ™œ๋™ ๋‚ด์—ญ์ž…๋‹ˆ๋‹ค ๐Ÿค—
<tr>
<td align="center" width="200" valign="top">
<b>๊น€์ˆ˜ํ˜„</b><br>
<img src="docs/imgs/members/soohyun.png" height="180px"><br>
<img src="platform/frontend/public/members/soohyun.png" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-TPM-94A3B8">
<img src="https://img.shields.io/badge/-INFRA-94A3B8"><br>
Expand All @@ -71,7 +71,7 @@ DevFactory์˜ ์ฃผ์š” ํ™œ๋™ ๋‚ด์—ญ์ž…๋‹ˆ๋‹ค ๐Ÿค—
</td>
<td align="center" width="200" valign="top">
<b>๊น€์˜ˆ์‹ </b><br>
<img src="docs/imgs/members/yesin.jpg" height="180px"><br>
<img src="platform/frontend/public/members/yesin.jpg" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-BE-0891B2"><br>
<img src="https://img.shields.io/badge/-10th-DAA520">
Expand All @@ -81,7 +81,7 @@ DevFactory์˜ ์ฃผ์š” ํ™œ๋™ ๋‚ด์—ญ์ž…๋‹ˆ๋‹ค ๐Ÿค—
</td>
<td align="center" width="200" valign="top">
<b>๊น€์Šน๊ทœ</b><br>
<img src="docs/imgs/members/seungkyu.jpg" height="180px"><br>
<img src="platform/frontend/public/members/seungkyu.jpg" height="180px"><br>
<img src="https://img.shields.io/badge/-Builder-3776AB">
<img src="https://img.shields.io/badge/-FE-60A5FA"><br>
<img src="https://img.shields.io/badge/-10th-DAA520">
Expand Down
5 changes: 5 additions & 0 deletions platform/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Domain Setting
APP_HOST=your-domain.com

# Database Setting
DATABASE_URL=postgresql://user:pass@devfactory-postgres:5432/dbname
5 changes: 5 additions & 0 deletions platform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
node_modules/
dist/
build/
.DS_Store
66 changes: 66 additions & 0 deletions platform/PLATFORM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# DevFactory Unified Platform

์†Œ๊ฐœ ํŽ˜์ด์ง€์™€ ๋ฐฑ์—”๋“œ API๊ฐ€ ํ†ตํ•ฉ๋œ DevFactory์˜ ๋ฉ”์ธ ํ”Œ๋žซํผ ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.
๋ณธ ์„ค์ •์€ **Traefik ์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ**๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋ฒ„ ํ™˜๊ฒฝ์„ ์ „์ œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

### 1. Production Build
๋กœ์ปฌ ๋˜๋Š” ์„œ๋ฒ„์—์„œ ํ”„๋ก ํŠธ์—”๋“œ ์—์…‹์„ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.
```bash
cd platform/frontend
npm install
npm run build
```
๊ฒฐ๊ณผ๋ฌผ์€ `platform/frontend/dist` ๋””๋ ‰ํ† ๋ฆฌ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

### 2. Deployment Options

#### Option A: Static Hosting (GitHub Pages / Vercel)
๋‹จ์ˆœ ์›น ํŽ˜์ด์ง€(Frontend)๋งŒ ๋ฐฐํฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
1. `platform/frontend`์—์„œ `npm run build`๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
2. `dist` ํด๋” ๋‚ด์˜ ํŒŒ์ผ๋“ค์„ ๋ฐฐํฌ ์„œ๋น„์Šค์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
> **์ฐธ๊ณ **: ์ด ๋ฐฉ์‹์œผ๋กœ๋Š” ์ž์ฒด DB ๋ฐฉ๋ฌธ์ž ์ถ”์  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

#### Option B: Unified Platform (Full-Stack / Docker)
๋ฐฉ๋ฌธ์ž ์ถ”์  ๊ธฐ๋Šฅ์„ ํฌํ•จํ•œ ์ „์ฒด ํ”Œ๋žซํผ ๋ฐฐํฌ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. **(๊ถŒ์žฅ)**

### 3. Environment Setup
`platform` ๋””๋ ‰ํ† ๋ฆฌ ๋ฃจํŠธ์— `.env` ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์„œ๋ฒ„ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
```bash
# .env ํŒŒ์ผ ์˜ˆ์‹œ
APP_HOST=intro.pseudolab-devfactory.com

# Database
DATABASE_URL=postgresql://user:pass@devfactory-postgres:5432/dbname
```

### 3. Traefik ๊ธฐ๋ฐ˜ ๋ฐฐํฌ
Docker Compose๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
```bash
cd platform
# ์ „์ฒด ์„œ๋น„์Šค ๋นŒ๋“œ ๋ฐ ์‹คํ–‰
docker-compose up -d --build
```

#### ๋ฐฐํฌ ํ™•์ธ
- **Frontend (Web)**: `https://<APP_HOST>`
- **Backend (API)**: `https://<APP_HOST>/api/health`

### 4. Database Schema
์‚ฌ์šฉ ์ค‘์ธ `logging.access_log` ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
```sql
CREATE TABLE logging.access_log (
id SERIAL PRIMARY KEY,
ts TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
path TEXT NOT NULL,
method TEXT NOT NULL,
status INTEGER NOT NULL,
latency_ms INTEGER,
ip_hash TEXT,
user_agent TEXT,
referrer TEXT
);
```

### 5. Verification
- Traefik ๋Œ€์‹œ๋ณด๋“œ์—์„œ `df-platform` ๊ด€๋ จ ๋ผ์šฐํ„ฐ๊ฐ€ ํ™œ์„ฑํ™”๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.
- ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์ดํŠธ ์ ‘์† ์‹œ HTTPS ์ƒ์‹œ ์—ฐ๊ฒฐ ๋ฐ ๋ฐฉ๋ฌธ ๊ธฐ๋ก ์ ์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
43 changes: 43 additions & 0 deletions platform/docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
services:
# Development Overrides with Traefik Support
frontend:
build:
context: ./frontend
target: build-stage
image: devfactory-frontend:dev
command: npm run dev -- --host 0.0.0.0
volumes:
- ./frontend:/app
- /app/node_modules
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.routers.df-platform-web.rule=Host(`${APP_HOST}`)
- traefik.http.routers.df-platform-web.entrypoints=websecure
- traefik.http.routers.df-platform-web.tls=true
- traefik.http.routers.df-platform-web.tls.certresolver=le
- traefik.http.services.df-platform-web.loadbalancer.server.port=5173
# HTTP โ†’ HTTPS redirect (re-adding to ensure full functionality)
- traefik.http.routers.df-platform-web-http.rule=Host(`${APP_HOST}`)
- traefik.http.routers.df-platform-web-http.entrypoints=web
- traefik.http.routers.df-platform-web-http.middlewares=redirect-to-https@file
- traefik.http.routers.df-platform-web-http.service=df-platform-web

server:
command: npm run dev
volumes:
- ./server:/app
- /app/node_modules
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.routers.df-platform-api.rule=Host(`${APP_HOST}`) && PathPrefix(`/api`)
- traefik.http.routers.df-platform-api.entrypoints=websecure
- traefik.http.routers.df-platform-api.tls=true
- traefik.http.routers.df-platform-api.tls.certresolver=le
- traefik.http.services.df-platform-api.loadbalancer.server.port=3000
# HTTP โ†’ HTTPS redirect
- traefik.http.routers.df-platform-api-http.rule=Host(`${APP_HOST}`) && PathPrefix(`/api`)
- traefik.http.routers.df-platform-api-http.entrypoints=web
- traefik.http.routers.df-platform-api-http.middlewares=redirect-to-https@file
- traefik.http.routers.df-platform-api-http.service=df-platform-api
61 changes: 61 additions & 0 deletions platform/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
services:
# Frontend static server (Nginx)
frontend:
build:
context: ./frontend
labels:
- "org.pseudolab.project=devfactory-platform"
container_name: devfactory-frontend
restart: unless-stopped
networks:
- traefik
- internal
labels:
- traefik.enable=true
- traefik.docker.network=traefik
# --- Traefik Router (frontend) ---
- traefik.http.routers.df-platform-web.rule=Host(`${APP_HOST}`)
- traefik.http.routers.df-platform-web.entrypoints=websecure
- traefik.http.routers.df-platform-web.tls=true
- traefik.http.routers.df-platform-web.tls.certresolver=le
- traefik.http.services.df-platform-web.loadbalancer.server.port=80
# HTTP โ†’ HTTPS redirect
- traefik.http.routers.df-platform-web-http.rule=Host(`${APP_HOST}`)
- traefik.http.routers.df-platform-web-http.entrypoints=web
- traefik.http.routers.df-platform-web-http.middlewares=redirect-to-https@file
- traefik.http.routers.df-platform-web-http.service=df-platform-web

# Backend API server
server:
build:
context: ./server
labels:
- "org.pseudolab.project=devfactory-platform"
container_name: devfactory-api
restart: unless-stopped
environment:
- DATABASE_URL=${DATABASE_URL}
- PORT=3000
networks:
- traefik
- internal
labels:
- traefik.enable=true
- traefik.docker.network=traefik
# --- Traefik Router (backend) ---
- traefik.http.routers.df-platform-api.rule=Host(`${APP_HOST}`) && PathPrefix(`/api`)
- traefik.http.routers.df-platform-api.entrypoints=websecure
- traefik.http.routers.df-platform-api.tls=true
- traefik.http.routers.df-platform-api.tls.certresolver=le
- traefik.http.services.df-platform-api.loadbalancer.server.port=3000
# HTTP โ†’ HTTPS redirect
- traefik.http.routers.df-platform-api-http.rule=Host(`${APP_HOST}`) && PathPrefix(`/api`)
- traefik.http.routers.df-platform-api-http.entrypoints=web
- traefik.http.routers.df-platform-api-http.middlewares=redirect-to-https@file
- traefik.http.routers.df-platform-api-http.service=df-platform-api

networks:
traefik:
external: true
internal:
driver: bridge
23 changes: 23 additions & 0 deletions platform/frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Stage 1: Build stage
FROM node:20-alpine as build-stage

WORKDIR /app

# Copy package files and install dependencies
COPY package*.json ./
RUN npm install

# Copy project files and build
COPY . .
RUN npm run build

# Stage 2: Serve stage
FROM nginx:stable-alpine as production-stage

# Copy built assets from build-stage to nginx
COPY --from=build-stage /app/dist /usr/share/nginx/html

# Expose port 80
EXPOSE 80

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