Developer Inyong Kim’s Blog
Post Gallery
Post List
Table
Search

[1일차: C++ 개요, 환경 구축 및 기초 제어문 강의 대본]
1. C++ 언어 개요 및 게임 개발에서의 역할
슬라이드 1: 강의 오리엔테이션 및 과정 소개
[C++] 1. C++ 개요, 환경 구축 및 기초 제어문

1. 마이그레이션 전략 (Migration Strategy)
안전한 데이터 이관을 위한 순서: "스키마 먼저, 데이터는 나중에”
•
MySQL과 PostgreSQL 간 데이터 타입(DATETIME vs TIMESTAMP, TINYINT vs BOOLEAN 등) 차이로 인한 직접 마이그레이션 시 오류 발생 위험 존재.
•
단계별 전략:
1.
JPA 연동: Spring Boot 접속 정보를 PostgreSQL로 변경.
2.
스키마 자동 생성: 애플리케이션 실행을 통해 JPA(Hibernate)가 엔티티(@Entity)를 분석, PostgreSQL용 빈 테이블(스키마) 자동 생성 유도.
3.
데이터 적재: 완성된 빈 테이블에 기존 MySQL 데이터를 Export/Import 방식으로 이관.
해당 세션의 목표
•
OS 환경에 구애받지 않는 Docker 기반의 PostgreSQL 및 pgvector 환경 구축
•
기존 MySQL에 적재된 전시관(Exhibition) 및 작품(Production) 데이터의 손실 없는 이전
•
Spring Boot 백엔드와 새로운 DB의 JPA 연동 및 기존 API 정상 동작 검증
2. Spring Boot 백엔드 설정 변경 (Backend Configuration)
2.1 데이터베이스 의존성 교체
[Spring AI/RAG] 3. Backend MySQL→PostgreSQL 마이그레이션

1. 마이그레이션 배경 및 목표 (Background & Objective)
왜 PostgreSQL과 pgvector인가?
•
현재 가상 전시관 서비스는 관계형 데이터베이스인 MySQL을 기반으로 운영되고 있다.
•
하지만 향후 도입할 RAG 시스템은 문서를 임베딩한 고차원 배열인 '벡터(Vector)' 데이터를 저장하고, 벡터 간의 '코사인 유사도'를 밀리초 단위로 계산해 낼 수 있는 특수한 기능이 필요하다.
•
기존 MySQL 환경에서는 이러한 고속 벡터 연산이 매우 비효율적이거나 지원되지 않으므로, Spring AI 생태계에서 가장 널리 쓰이고 호환성이 뛰어난 PostgreSQL과 그 확장 프로그램인 pgvector로 데이터베이스를 전면 마이그레이션하기로 결정했다.
해당 세션의 목표
•
OS 환경에 구애받지 않는 Docker 기반의 PostgreSQL 및 pgvector 환경 구축
•
기존 MySQL에 적재된 전시관(Exhibition) 및 작품(Production) 데이터의 손실 없는 이전
•
Spring Boot 백엔드와 새로운 DB의 JPA 연동 및 기존 API 정상 동작 검증
2. 왜 Docker로 환경을 구축해야 하는가? (Why Docker?)
[Spring AI/RAG] 2. PostgreSQL + pgvector를 통한 Vector Database 환경 구축

1. 제안 배경 (Background)
현재 구현 단계의 한계 및 문제 인식
•
현재 가상 전시관(VExhibition)의 AI 도슨트 시스템은 작품의 짧은 설명(Description)과 LLM(대형 언어 모델)의 사전 학습된 내부 지식과 프롬프트 정의(Prompt Engineering)에만 의존하여 대본을 생성하고 있다. 이러한 구조는 다음과 같은 한계점을 지닌다.
◦
환각 현상(Hallucination): LLM이 작품의 의도나 작가의 배경에 대해 존재하지 않는 거짓 정보를 사실처럼 지어낼 위험성이 존재한다.
◦
전문성 및 정보의 깊이 부족: 단순한 텍스트 묘사를 넘어선 깊이 있는 미술사적 배경, 작가의 철학, 전시 기획 의도 등을 상세히 전달하기 어렵다.
◦
최신 데이터 반영의 한계: 전시회 라인업이 변경되거나 새로운 작품이 추가될 때마다 LLM을 미세 조정(Fine-tuning)하는 것은 비용과 시간 측면에서 비효율적이다.
RAG를 통한 AI 1차 고도화
•
신뢰할 수 있는 외부 지식(전시 도록, 미술사 문헌 등)을 검색하여 프롬프트에 제공하는 RAG(검색 증강 생성, Retrieval-Augmented Generation) 파이프라인을 도입하고자 한다.
2. 기대 효과 (Expected Benefits)
[Spring AI/RAG] 1. AI 서비스 고도화 개요와 핵심 용어 정리 (feat. LLM 활용 도슨트 사례)

1. Why React? Vite?
1. React란?
React
•
Node.js 기반 프레임워크
•
컴포넌트 기반 프론트엔드 프레임워크
•
가상 DOM 구현체를 통한 빠른 데이터 바인딩 및 페이지 로딩
•
선언적 UI(컴포넌트 모듈)와 JSX(JavaScript 기반 XML) 직관적인 코드(객체지향)
2. Vite란?
Vite
•
[React+vite] 1. 프로젝트 개발 환경 구축과 핵심 용어 정리

6일차: 최종 시스템 통합 및 데모 (FastAPI)
부제: 딥보이스/딥페이크 탐지 모델을 활용한 추론 API 서버 구축 및 전체 통합
Agenda: 6일차 학습 목표 및 일정 (8H)
•
모듈 1 (이론/실습): FastAPI 서버 환경 설정 및 프로젝트 구조 구성
◦
Python 환경 설정 및 FastAPI, Uvicorn, TensorFlow 라이브러리 설치
◦
models/ 폴더에 5일차 모델 파일 배치
•
모듈 2 (실습): 딥보이스 탐지 API 개발 (FastAPI)
◦
model_audio.h5 로드 및 추론 함수 구현
◦
/deepfake/audio 엔드포인트 구현 (음성 파일 수신 및 진위 판별)
•
모듈 3 (실습): 딥페이크 이미지 탐지 API 개발 (FastAPI)
◦
model_image.h5 로드 및 추론 함수 구현
◦
/deepfake/image 엔드포인트 구현 (이미지 파일 수신 및 진위 판별)
[AI딥페이크] 6. 딥페이크 탐지 프로젝트(2) - Inference API + Frontend + Backend → Docker 애플리케이션 통합

5일차: 딥페이크 탐지 앱 개발(1) 프로젝트
(슬라이드 1: 표지)
"안녕하십니까. 5일차 강의를 시작하겠습니다. 오늘은 '프로젝트를 통한 AI 역량강화 과정' 중 **'딥페이크 탐지 앱 개발(2) 프로젝트'**에 대해 다루겠습니다. 어제까지 만든 웹 애플리케이션의 뼈대에, 실제 지능을 불어넣는 AI 모델 파트를 집중적으로 학습하겠습니다."
부제: 데이터 전처리, 딥보이스 및 딥페이크 이미지 모델 분석과 훈련
Agenda: 5일차 학습 목표 및 일정
•
데이터 전처리: 개념 이해 및 딥페이크 탐지를 위한 기초 데이터 확보.
•
딥보이스 모델 분석: 음성 특징 학습 및 진위 판별 메커니즘 이해.
[AI딥페이크] 5. 딥페이크 탐지 프로젝트(1) - AI 모델 학습

4일차: 백엔드 프로그래밍 (NestJS)
부제: Node.js, TypeScript, NestJS 핵심 개념과 RESTful API 서버 구축
Agenda: 4일차 학습 목표 및 일정
1.
NestJS 이론 (1): 핵심 개념, 아키텍처 (DI, Module)
2.
NestJS 실습 (1): Nest CLI 환경 구축 및 프로젝트 생성 (Resource)
3.
NestJS 이론 (2): 데이터베이스와 ORM (TypeORM)
[AI딥페이크] 4. 백엔드 프로그래밍 언어 및 개발 환경 구축 (NestJS)

3일차 - 프론트엔드 개발: React 기초
부제: JavaScript 핵심 문법, React 컴포넌트, Hooks를 활용한 딥페이크 탐지 웹 UI 구현
Agenda: 3일차 학습 목표 및 일정
1.
JavaScript Core (이론): ES6+ 주요 문법, 비동기 처리 (Promise, async/await).
2.
React Core (이론): SPA, JSX, Component, Props, State 개념.
3.
실습 1 (환경 구축): React 개발 환경 구축 (Vite), 기본 컴포넌트 및 Props.
[AI딥페이크] 3. 프론트엔드 프로그래밍 언어 및 개발 환경 구축 (React)

2일차: 스마트시티 산업 동향 및 딥페이크 탐지 프로젝트 설계
부제: 딥페이크 탐지 기술의 스마트시티 적용 방안 모색 및 웹 서비스 기획
2일차 학습 목표 및 일정
1.
이론 (2H): 스마트시티 산업 동향 및 딥페이크 탐지 기술 적용 방안
2.
실습 (6H): 딥페이크 탐지 웹 애플리케이션 프로젝트 설계
•
목표 설정 (SMART) 및 기능 정의
•
시스템 아키텍처 및 UI/UX
•
데이터베이스 (ERD) 및 API 설계
3.
발표 및 피드백: 팀별 설계 내용 발표
[AI딥페이크] 2. 스마트시티 산업과 AI

1일차: AI 혁신과 스마트시티: 딥페이크 탐지 첫걸음
부제: AI 기본기, 스마트시티 적용, 그리고 딥페이크 문제의 이해
Agenda: 1일차 학습 목표 및 일정
1.
AI/DL 이론: AI, 머신러닝, 딥러닝 개념 및 차이점 이해
2.
실습 1 (환경): Colab 및 Python 데이터 분석 도구 (Numpy/Pandas) 활용
[AI딥페이크] 1. AI 및 스마트시티
1,2,3 장에서의 실습과 설명은 비전공, 웹개발 경험이 없는 대상을 위해 안내했지만, 이 과정도 다소 어렵게 느껴질 수 있는 왕초보들을 위한 AI 활용 방법이다.
1. AI에게 구성 만들도록 하기
•
Framer 홈페이지에서 Start with AI 선택

•
프로젝트 소개 페이지므로 Landing Page 선택 및 전송

•
알아서 에디터가 열리면서, 기본 레이아웃을 AI가 작성한다.

•
왼쪽 Ask Framer… 에서 원하는 것을 입력해보려고 한다.
◦
처음 입력한 정보는 다음과 같다.
나는 가상전시관 VEXPO라는 언리얼엔진 프로젝트를 개발했어
이것에 대한 프로젝트 소개 페이지로 구성해줘
프로젝트 설계 과정 이미지들과 레벨디자인 모습 내부/외부 여러 모습이 있고, 기능 구현에 대한 블루프린트 로직 정도의 이미지가 있어.
이걸 포함 할 수 있도록 준비해줘
새로운 페이지를 만들지말고 홈을 변경해줘
불필요한 연락하기, 회사 등은 제거해줘도 되
Shell
복사
•
실시간으로 AI가 페이지를 변경하기 시작한다.

[Framer] 4. AI Framer를 활용 웹사이트의 만들기(초심자추천)

1. 웹 서비스의 동작에 대해 이해하기
•
홈페이지는 우리가 보여주는 것 말고도 클릭해서 눌렀을때 동작하는 것들이 포함된다. 이 홈페이지의 예시로는 아래 사진과 같다.

•
우리는 강제로 우리 프로젝트 이미지를 넣긴했지만, 저렇게 프로젝트 메뉴로 이동하니 우리가 수정하지 못했던 부분들이 있는 것을 확인했다.
•
실제 홈페이지들의 동작은 단순히 이미지를 교체하는 정도로는 한계가 있고,
◦
이 홈페이지에 프로젝트나 프로젝트 정보, 사진 같은 것을 등록하고 홈페이지에서 보이도록 연결되어 있다. 이것을 콘텐츠 관리 시스템(Contents Management System)이 들어간 홈페이지라고 이해하면 된다.
◦
하지만 이것을 웹개발자의 경우 실제 코드로 이처럼 운영되도록 구성하지만, 초심자의 경우 코드로 적용하기 어려운 문제가 있다.
•
하지만 Framer에서는 이러한 복잡함을 간단히 페이지 구성을 통해 해결할 수 있다.
[Framer] 3. Framer를 활용 웹사이트의 콘텐츠를 바꿔보기 심화(콘텐츠관리시스템 CMS?)

1. Framer 회원가입
•
회원가입하기

•
구글로 간편 회원가입 하기

•
구글 회원 가입 진행, 알맞는 정보 입력하여 회원 가입 완료하기

•
회원가입 후 나타나는 메인 에디터 페이지

2. 테마 찾기
[Framer] 2. Framer를 활용 웹사이트 디자인과 배포해보기

1. Framer란 무엇인가?
Framer(프레이머)는 디자이너가 코딩 없이도 실제 작동하는 전문가 수준의 웹사이트를 만들 수 있도록 하는 혁신적인 웹 빌딩 플랫폼입니다.
과거에는 디자이너가 만든 시안을 개발자가 코드로 구현하는 방식이 일반적이었지만, Framer는 디자인과 개발 사이의 간극을 허물어 디자인 툴에서 작업하듯 웹사이트를 만들고 클릭 한 번으로 바로 인터넷에 게시(배포)할 수 있게 해줍니다.
쉽게 말해, "디자인 툴(Figma 등)의 자유도 + 웹 빌더(Wix, Squarespace 등)의 편리함 + 실제 웹 기술(React)의 강력함"을 합쳐놓은 도구라고 이해하시면 됩니다.
[Framer] 1. 초보, 비전공자를 위한 Framer로 홈페이지 만들기 소개
Python이란 무엇인가?
Python(파이썬)은 1991년 네덜란드의 프로그래머 귀도 반 로섬(Guido van Rossum)이 개발한 고급 프로그래밍 언어다. 'Monty Python's Flying Circus'라는 영국의 코미디 프로그램에서 이름을 따온 Python은 "간단하고 읽기 쉬운" 철학을 바탕으로 설계되었다.
Python의 핵심 특징
1. 간단하고 직관적인 문법
Python의 가장 큰 장점은 사람이 읽기 쉬운 문법이다. 다른 프로그래밍 언어에 비해 코드가 영어와 비슷하여 초보자도 쉽게 이해할 수 있다.
[Python] Python이란 무엇인가? - 프로그래밍 입문자를 위한
[Python] 0. Python 들어가기

수정 필요 부분
AuthModule
auth.module.ts
AuthModule 확인 필요
TypeError: Cannot read properties of undefined (reading 'challenge')

클라이언트 약식 소셜 로그인(OAuth)을 백엔드 서버 중심 인증방식으로 변경
•
보안 및 관례상 프로덕션 환경에서는 Credential 획득 및 관리를 백엔드에서 처리하는 것이 일반적인 관례이자 더 안전한 방식
•
따라서 이전 클라이언트 사이드로 Credential을 전달하던 약식 구현에서 백엔드 중앙집중식 구현으로 변경하고자 한다.
[OAuth2.0] Google Social Login 구현 - 백엔드 중앙 관리식 로직 구현

소셜 로그인은 모두 비슷한 과정
•
이전 카카오 로그인 구현과 결과적으로 동일한 과정을 거친다.
1.
인증 제공자(Provider)인 Google 디벨로퍼 콘솔에 접근해서 API 기능을 이용할 애플리케이션을 생성
2.
REST API 키 등 인증 키, 토큰 등을 받음
3.
해당 토큰과 함께 백엔드서버가 프로바이더 서버로 요청하는 중첩 구조를 만들게 됨
•
일반로그인 : 사용자 → 서버(서비스 서버) → 사용자
•
소셜로그인 : 사용자 → 서버(서비스 서버 → 프로바이더 서버 → 서비스 서버) → 사용자
•
실제 애플리케이션에서 구현하는 과정을 정리
[OAuth2.0] Google Social Login 구현 - 클라이언트 사이드 약식

문제 인식
HTTPS 배포를 통해 모든 서버들은 SSL을 통해 HTTPS 요청/응답을 받는 구조로 변경되고 있음
•
이 중 PixelStreaming을 하는 웹시그널링서버(WebRTC/Stun-Turn Server)가 동일한 도메인 인증서를 사용하면서 프론트엔드 서비스 내에 iFrame으로 PixelStreaming 화면을 임베딩 하는 부분의 오류가 발생
•
동일 오리진에 따른 문제
•
chrome-error://chromewebdata/:1 Refused to display 'https://metaverseacademy.site:8443/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

해결 방안 탐색
해결 시도
•
보안을 위하여 다른 사이트에서 로드할 때 허용 범위가 지정되어 있다.
•
호출하는 사이트(A 프로젝트)는 호출 당하는 사이트(B 프로젝트)에서 막은거라 할 수 있는 일은 없다.
•
호출 당하는 사이트(B 프로젝트)에서 X-Frame-Options 설정을 해준다.
◦
DENY: 시도하는 사이트에 관계없이 페이지를 프레임에 표시 X
◦
SAMEORIGIN: 페이지는 모든 조상 프레임이 페이지 자체와 동일한 출처인 경우에만 표시
•
호출당하는 입장인 B 프로젝트에서 응답 헤더에 X-Frame-Options를 세팅해서 보내주어야 한다.
•
httpResponse.setHeader("X-Frame-Options", "allow-from A프로젝트 IP주소:포트번호");
httpResponse.setHeader("X-Frame-Options", "allow-from http://localhost:8080");
Java
복사
해결 시도와 결과
호출 당하는 입장인 Pixel Streaming의 서버에서 헤더 추가 설정 필요
•
아래는 SignalingWebServer의 cirrus.js의 부분이다.
•
해당 서버 프로젝트는 helmet은 HTTP 헤더를 설정하여 앱을 일반적인 웹 취약점으로부터 보호하는 데 도움이 되는 Express.js 미들웨어를 사용하고 있는 것으로 파악되었다.
if (config.UseHTTPS) {
app.use(helmet());
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
//Setup http -> https redirect
console.log('Redirecting http->https');
app.use(function (req, res, next) {
if (!req.secure) {
if (req.get('Host')) {
var hostAddressParts = req.get('Host').split(':');
var hostAddress = hostAddressParts[0];
if (httpsPort != 443) {
hostAddress = `${hostAddress}:${httpsPort}`;
}
return res.redirect(['https://', hostAddress, req.originalUrl].join(''));
} else {
console.error(`unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`);
return res.status(400).send('Bad Request');
}
}
next();
});
}
JavaScript
복사
•
실제로 파라미터로 UseHttps boolean을 받는 것으로 보아 HTTPS 사용 시에만 helmet 적용: helmet 미들웨어는 config.UseHTTPS 가 true 일 때만 활성화되고 있다.
•
helmet 설정 변경으로 helmet() 호출 시에 frameguard 옵션을 명시적으로 설정하여 X-Frame-Options 헤더의 동작을 변경하고자 한다.
1.
첫번째로 해당 부분이 실질적으로 위 문제를 발생시키는지 확인하기 위하여 frameguard 옵션 자체를 비활성화 해본다.
if (config.UseHTTPS) {
app.use(helmet({
frameguard: false // frameguard 미들웨어 비활성화
}));
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
JavaScript
복사


•
이를 통해 해당 helmet 미들웨어가 해당 부분을 제어하고 있는 것으로 파악되었다.
2.
이 상태로는 보안상 취약점을 발생 시킬 수 있으므로 명시적으로 해당 도메인에 대한 출처 허용으로 스코프를 좁히고자 한다.
if (config.UseHTTPS) {
app.use(helmet({
frameguard: false // frameguard 미들웨어 비활성화
}));
app.use((req, res, next) => {
res.setHeader(
"Content-Security-Policy",
`frame-ancestors 'self' https://metaverseacademy.site:443 https://www.metaverseacademy.site:443;`
);
next();
});
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
...
JavaScript
복사
이렇게 헤더를 추가 설정해준다. 이후 모바일로도 문제 없이 실행되는 모습

Refused to display in a frame because it set 'X-Frame-Options' to 'sameorigin'.

도메인 구매 후, DNS 관리페이지 -> A Record 설정 -> 서버 외부 IP 연결
•
두개의 접근 주소 HTTP 일반 배포 상태 확인 (이후 → SSL 발급 후 HTTPS 보안 배포로 연결)

자체 서버(로컬) HTTPS 배포를 위한 WACS를 통한 자체 Let’s Encrypt 인증서 발급과 연결

샘플 모습
1.
프론트엔드의 파일 업로드 요청 시작

2.
백엔드 컨트롤러의 요청 흐름
a.
(백엔드) 컨트롤러 요청 도착 → (백엔드) 파일 서비스 전달

b.
(백엔드) 파일 서비스 → (NAS) 파일 저장 서버 컨트롤러로 요청

c.
(NAS) 파일 저장 컨트롤러 → NAS 파일 서비스 → NAS 스토리지 내 저장

d.
(백엔드) 파일 정보 및 NAS 정적 서빙 경로 데이터베이스 저장

3.
프론트엔드의 파일 데이터베이스 목록 조회 화면

4.
강의실의 시청 화면 진입 모습

5.
시청 화면 요청 시 NAS의 웹서버로부터 서빙되는 영상의 모습


백엔드서버→NAS API 파일 업로드→NAS 영상 서빙 뷰 페이지 반환까지의 구현 샘플

문제 인식
•
문제 상태 분석
◦
개발PC에서 SSH로 NAS에 접근(특정 계정의 세션 ex)citefred 유저로 SSH세션 생성됨)
◦
파일업로드 관련 애플리케이션 실행(npm run start) - 해당 유저의 세션에서 실행되고 있음
◦
개발PC의 SSH로 접속한 터미널을 종료 또는 만료로 종료 되면 NAS에서도 해당 세션을 종료 시키면서 파일업로드 애플리케이션도 함께 종료됨
해결 방안 탐색
•
특정 유저가 로그인하는 방식의 SSH 세션은 결국 해당 접속을 종료하면 세션이 종료되면서 관련 프로세스가 모두 종료됨
•
따라서, NAS가 계속하여 실행되는 root 유저로 접근하면 해결 할 수 있지만 root계정으로 터미널에 접근하는 것을 개방하는 것은 위험성이 있음
•
NAS 자체에서 제공하는 Docker를 통해 실행하면 root에서 실행하는것이므로 지속적인 프로세스를 유지 할 수 있음
NAS 내 파일업로드 애플리케이션의 특정 SSH에 종속된 세션 만료 문제 + Docker와 Host의 컨텍스트 인식 문제

NAS 파일 스토리지를 활용하기
•
NAS:
◦
역할: 대용량 스토리지로서 AWS S3의 스토리지 서비스 역할 대체
◦
Nginx:
▪
역할: NAS의 정적 파일을 서빙
▪
기능: AWS S3의 정적 파일 URL 제공 역할 대체
◦
NAS 내부 파일 서버 애플리케이션:
▪
역할: NestJS API로 파일 시스템 전용 서버
기능: 서비스 백엔드 서버의 파일 시스템(I/O) 기능이 독립화된 별도 서비스
▪
매개체 역할: NAS와 서비스 백엔드 서버 간의 파일 관련 매개체 역할 수행 (리버스 프록시)
•
서비스 백엔드 서버:
◦
역할: NestJS 기반의 서비스 관련 API 서버
◦
기능: 웹 애플리케이션의 기본적인 CRUD 기능 제공
◦
데이터 저장: 파일 경로를 데이터베이스에 URL Path 형태로 저장
•
서비스 프론트엔드 서버:
◦
역할: 웹 애플리케이션의 전체 뷰 페이지 렌더링 담당
◦
기능: 백엔드 API와 통신을 통한 동적 페이지 렌더링
파일 제공: 각종 파일은 백엔드로부터 전달받는 URL Path를 통해 제공
NAS 파일서버 구축과 웹서버(Nginx)를 통한 파일 서빙
Load more
Category
Search
Programming Study
Projects
Thoughts
Life
Tags
Search
citeFred All Copyright Reserved. 2025

