chore: 사내 Node 샘플 scaffold (new-project 템플릿)
podman 로컬개발 + Coolify(Dockerfile) 배포용 베이스. - Express 서버: /healthz, /db, /s3 연결 확인 - src/config.js 단일 진입점 → src/db.js(pg), src/s3.js(MinIO) - scripts/check-db.js, check-minio.js 연결 점검 - Dockerfile / compose.yaml / .dockerignore, 비밀값은 env 파일(gitignore)에서만 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
26
src/config.js
Normal file
26
src/config.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// 환경설정 — 모든 외부 연결정보는 환경변수에서만 읽는다(코드에 비밀값 금지).
|
||||
//
|
||||
// 값의 출처: 프로젝트 폴더의 .project-env (DB 본인 schema + S3). 프로젝트 폴더에 cd 하면
|
||||
// 로그인 셸이 자동 export → 여기 process.env 로 그대로 들어온다(별도 dotenv 불필요).
|
||||
// MinIO(S3): 사내 오브젝트 스토리지. endpoint는 API 호스트(minio.bokdev.in),
|
||||
// 콘솔(minioc.bokdev.in)이 아님에 주의.
|
||||
//
|
||||
// Coolify 배포 시에는 Coolify의 Environment Variables 화면에서 같은 키들을 채운다.
|
||||
|
||||
export const config = {
|
||||
port: parseInt(process.env.PORT || "3000", 10),
|
||||
|
||||
// Postgres — .project-env 의 DATABASE_URL. Coolify에선 본인 DB 접속정보를 넣을 것.
|
||||
databaseUrl: process.env.DATABASE_URL || "",
|
||||
|
||||
// MinIO / S3 호환
|
||||
s3: {
|
||||
endpoint: process.env.S3_ENDPOINT || "https://minio.bokdev.in",
|
||||
region: process.env.S3_REGION || "us-east-1",
|
||||
bucket: process.env.S3_BUCKET || "coolify-user-data",
|
||||
accessKeyId: process.env.S3_ACCESS_KEY_ID || "",
|
||||
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || "",
|
||||
// MinIO는 path-style 필요
|
||||
forcePathStyle: true,
|
||||
},
|
||||
};
|
||||
15
src/db.js
Normal file
15
src/db.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// Postgres 연결 풀. DATABASE_URL 한 줄로 접속(직원 전용 schema가 search_path에 고정됨).
|
||||
import pg from "pg";
|
||||
import { config } from "./config.js";
|
||||
|
||||
export const pool = new pg.Pool({
|
||||
connectionString: config.databaseUrl,
|
||||
max: 5,
|
||||
});
|
||||
|
||||
export async function pingDb() {
|
||||
const { rows } = await pool.query(
|
||||
"select current_user as user, current_schema as schema, now() as now"
|
||||
);
|
||||
return rows[0];
|
||||
}
|
||||
24
src/s3.js
Normal file
24
src/s3.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// MinIO(S3 호환) 클라이언트. 자격증명은 env에서만 읽는다.
|
||||
import { S3Client, ListObjectsV2Command, HeadBucketCommand } from "@aws-sdk/client-s3";
|
||||
import { config } from "./config.js";
|
||||
|
||||
export const s3 = new S3Client({
|
||||
endpoint: config.s3.endpoint,
|
||||
region: config.s3.region,
|
||||
forcePathStyle: config.s3.forcePathStyle,
|
||||
credentials: {
|
||||
accessKeyId: config.s3.accessKeyId,
|
||||
secretAccessKey: config.s3.secretAccessKey,
|
||||
},
|
||||
});
|
||||
|
||||
export async function pingS3() {
|
||||
await s3.send(new HeadBucketCommand({ Bucket: config.s3.bucket }));
|
||||
const out = await s3.send(
|
||||
new ListObjectsV2Command({ Bucket: config.s3.bucket, MaxKeys: 5 })
|
||||
);
|
||||
return {
|
||||
bucket: config.s3.bucket,
|
||||
sampleKeys: (out.Contents || []).map((o) => o.Key),
|
||||
};
|
||||
}
|
||||
33
src/server.js
Normal file
33
src/server.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// 최소 Express 서버 — /healthz, /db, /s3 로 연결 확인.
|
||||
import express from "express";
|
||||
import { config } from "./config.js";
|
||||
import { pingDb } from "./db.js";
|
||||
import { pingS3 } from "./s3.js";
|
||||
|
||||
const app = express();
|
||||
|
||||
app.get("/healthz", (_req, res) => res.json({ ok: true }));
|
||||
|
||||
app.get("/db", async (_req, res) => {
|
||||
try {
|
||||
res.json({ ok: true, ...(await pingDb()) });
|
||||
} catch (e) {
|
||||
res.status(500).json({ ok: false, error: String(e.message || e) });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/s3", async (_req, res) => {
|
||||
try {
|
||||
res.json({ ok: true, ...(await pingS3()) });
|
||||
} catch (e) {
|
||||
res.status(500).json({ ok: false, error: String(e.message || e) });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/", (_req, res) =>
|
||||
res.json({ name: "sample", endpoints: ["/healthz", "/db", "/s3"] })
|
||||
);
|
||||
|
||||
app.listen(config.port, "0.0.0.0", () => {
|
||||
console.log(`sample listening on :${config.port}`);
|
||||
});
|
||||
Reference in New Issue
Block a user