Repository navigation
TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), Docker + GHCR 기반 Nginx 웹페이지 배포 실습, Nginx Dockerfile 이미지 GHCR에 Push & Render 배포] #71
Description
📌 바이브 코딩(Vibe Coding)
인공지능(AI)을 활용하여 자연어로 프로그램을 개발하는 새로운 방식
즉, 사용자가 원하는 기능을 일상적인 언어로 설명하면 AI가 이를 해석하여 실제로 동작하는 코드를 생성해주는 프로그래밍 패러다임
바이브 코딩의 장점
- 접근성 향상: 비전문가도 개발에 참여할 수 있어 창업자, 디자이너 등 다양한 분야에서 활용 가능하다.
- 생산성 증가: 반복적인 작업을 AI가 처리하여 개발 속도를 높인다.
- 창의성 촉진: 기술적인 제약 없이 아이디어를 자유롭게 구현할 수 있다.
바이브 코딩의 한계
- 정확성 문제: AI가 생성한 코드가 항상 정확하거나 최적화되어 있지 않을 수 있다.
- 의존성 증가: AI에 과도하게 의존하면 개발자의 기본 실력이 저하될 우려가 있다.
- 윤리적·법적 이슈: AI가 생성한 코드의 저작권 문제 등 법적 논란이 발생할 수 있다.
📌 Ollama
Llama 3, Mistral, Gemma 등 다양한 오픈소스 대형 언어 모델(LLM)을 로컬에서 실행할 수 있게 해주는 경량 프레임워크
개인 정보 보호, 비용 절감, 오프라인 환경에서의 AI 활용 등을 원하는 사용자에게 적합하다.
https://ollama.com/
Ollama 기본 사용법
- 모델 실행
예를 들어, Llama 3 모델을 실행하려면 :ollama run llama3
처음 실행 시 모델이 자동으로 다운로드된다. - 모델 목록 확인
로컬에 설치된 모델 목록을 확인하려면 :ollama list - 모델 정보 확인
특정 모델의 정보를 확인하려면 :ollama show [모델명] - 모델 제거
더 이상 사용하지 않는 모델을 제거하려면 :ollama rm [모델명]
주요 특징
- 다양한 모델 지원: Llama 3, Mistral, Gemma 등 다양한 오픈소스 LLM을 지원한다.
- 로컬 실행: 인터넷 연결 없이도 로컬에서 모델을 실행할 수 있다.
- REST API 제공: 다른 애플리케이션과의 통합을 위한 REST API를 제공한다.
- 모델 커스터마이징: 사용자 정의 프롬프트로 모델을 커스터마이징할 수 있다.
경량화 버전으로 실습해보기
Alpine Linux 기반으로 경량화된 Ollama Docker 이미지를 제공하는 비공식 프로젝트
https://github.com/alpine-docker/ollama
docker pull alpine/ollama
docker rm -f ollama
docker run -d -p 11434:11434 -v ~/.ollama/root/.ollama --name ollama alpine/ollama
docker exec -ti ollama ollama pull llama3.2포스트맨에서 확인해보기
{
"error": "model requires more system memory (3.4 GiB) than is available (2.9 GiB)"
}이렇게 뜬다면, Docker에 더 많은 메모리를 할당해야 한다.
본인은 rancher desktop을 사용하고 있어 preference -> Virtual Machine -> Memory (GB)를 6으로 늘려줬다.
메모리 설정 변경 후 아래 명령어로 기존 컨테이너를 다시 시작한다.
docker rm -f ollama
docker run -d -p 11434:11434 -v ~/.ollama/root/.ollama --name ollama alpine/ollama
docker exec -ti ollama ollama pull llama3.2
실습이 끝난 후에는 삭제하자!
docker ps # 실행중인 컨테이너 -> ID
docker rm -f {컨테이너 ID 앞 4자리}📌 랭체인(LangChain)
LangChain = LLM + 체인(chain) 구조로 구성된 AI 파이프라인 프레임워크
주요 목적:
- 단순한 질문-답변을 넘어서
- 검색, 계산, 문서 요약, DB 질의, API 호출 등 다양한 작업을 조합
- 이를 체인(chain) 으로 연결하여 복잡한 AI 앱을 구현
언어별 지원여부
| 언어 | 공식 지원 여부 | 설명 |
|---|---|---|
| Python | ✅ 지원 | 주력 플랫폼, 기능 가장 풍부 |
| JavaScript / TypeScript | ✅ 지원 | 웹/Node 기반 사용 가능 |
| Java | ❌ 미지원 | 직접 구현하거나 외부 연동 필요 |
LangChain4j 사용 (비공식 Java 프로젝트)
LangChain4j는 LangChain의 아이디어를 Java로 옮긴 비공식 프로젝트이다.
- 설치
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.25.0</version> <!-- 최신 버전 확인 필요 -->
</dependency>implementation 'dev.langchain4j:langchain4j:0.25.0'- 기본 예제 (OpenAI API 호출)
import dev.langchain4j.model.openai.OpenAiChatModel;
public class Example {
public static void main(String[] args) {
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey("YOUR_OPENAI_API_KEY")
.build();
String answer = model.generate("파이썬과 자바의 차이점은?");
System.out.println(answer);
}
}
3. 프롬프트 템플릿 사용
```java
import dev.langchain4j.*;
PromptTemplate template = PromptTemplate.from("Translate this to English: {{input}}");
String prompt = template.apply("안녕하세요");
System.out.println(prompt);- 메모리 대화 (챗봇 스타일)
import dev.langchain4j.*;
import dev.langchain4j.memory.*;
public class ChatBot {
public static void main(String[] args) {
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey("YOUR_KEY")
.build();
ChatLanguageModel chat = model.withMemory(memory);
System.out.println(chat.generate("안녕"));
System.out.println(chat.generate("내가 방금 뭐라고 했지?"));
}
}- 문서 기반 질의응답 (RAG)
import dev.langchain4j.retriever.*;
import dev.langchain4j.store.embedding.inmemory.*;
import dev.langchain4j.model.embedding.openai.*;
public class RagExample {
public static void main(String[] args) {
InMemoryEmbeddingStore<Document> store = new InMemoryEmbeddingStore<>();
OpenAiEmbeddingModel embedModel = OpenAiEmbeddingModel.builder()
.apiKey("YOUR_KEY")
.build();
store.add(Document.from("서울은 대한민국의 수도입니다."));
EmbeddingRetriever retriever = new EmbeddingRetriever(embedModel, store);
retriever.retrieve("대한민국 수도는?").forEach(System.out::println);
}
}📌 Docker + GHCR 기반 Nginx 웹페이지 배포 실습
1단계. GitHub Token 발급 및 Docker 로그인
목적: GHCR(GitHub Container Registry)에 push할 수 있는 권한 부여
- GitHub에서 토큰 생성
# 환경변수 등록
export GITHUB_TOKEN=ghp_abc123456
# 토큰 정상 확인
echo $GITHUB_TOKEN
# Docker 로그인
echo $GITHUB_TOKEN | docker login ghcr.io -u soheegit --password-stdin- GHCR은 반드시 소문자 사용자명만 허용한다 (soheegit ← OK)
2단계. Docker 이미지 pull → 태그 → GHCR에 push
목적: 공식 nginx 이미지를 GHCR에 내 소유 이미지로 업로드
docker pull nginx
docker tag nginx ghcr.io/soheegit/nginx:latest
docker push ghcr.io/soheegit/nginx
- GitHub > Packages에서 nginx 패키지가 생성된 것을 확인할 수 있음
3단계. GHCR에서 다시 pull 받아 웹서버 실행
목적: GHCR에 있는 이미지를 실제 서비스처럼 pull → run
docker rmi ghcr.io/soheegit/nginx:latest # 캐시 제거 (선택)
docker pull ghcr.io/soheegit/nginx:latest
docker run -d -p 9999:80 --name my-nginx ghcr.io/soheegit/nginx:latest- http://localhost:9999 접속 가능
4단계. 컨테이너 내부에 직접 HTML 파일 삽입 (임시 방식)
docker exec -it my-nginx /bin/bash
echo Hello GHCR! > /usr/share/nginx/html/index.html
exit- 정적 파일을 직접 넣었을 때 웹서버에서 보여지는 방식 실습
5단계. Volume 마운트를 사용한 웹 페이지 연결 (정식 방식)
목적: 로컬 폴더에 있는 HTML 파일을 컨테이너에 연동
mkdir -p ~/Development/workspace/docker/nginx
# 여기에 index.html 넣기 (예: VS Code에서 생성)
docker run -d -p 9988:80 -v ~/Development/workspace/docker/nginx:/usr/share/nginx/html --name my-nginx-volume ghcr.io/soheegit/nginx:latest6단계. 외부 접속용 localtunnel 실행
npm install -g localtunnel
lt --port 9988- 출력된 https://random-subdomain.loca.lt 주소로 인터넷 어디서든 접속 가능
7단계. 로그 확인 (누가 접속했는지 확인)
docker logs my-nginx-volume- 내 사이트에 들어온 사람들의 로그를 볼 수 있다.
📌 Nginx Dockerfile 이미지 GHCR에 Push & Render 배포
- 커스텀 index.html을 포함한 Nginx 이미지를 Dockerfile로 만들고
- GHCR(GitHub Container Registry)에 업로드한 뒤
- Render에서 pull하여 배포하는 전체 과정 실습
1. Dockerfile 작성
# base 이미지: nginx
FROM nginx
# index.html을 Nginx 기본 경로로 복사
COPY ./nginx/index.html /usr/share/nginx/html/index.html
# 포트 노출
EXPOSE 80
# nginx 실행
CMD ["nginx", "-g", "daemon off;"]- ./nginx/index.html 은 프로젝트 로컬 경로 기준
- Nginx 기본 웹 경로는 /usr/share/nginx/html/
2. Docker 이미지 빌드 및 테스트 실행
docker build -t my-nginx .
docker run -d -p 8899:80 --name my-nginx-dockerfile my-nginx- 브라우저에서 http://localhost:8899 접속하여 index.html 내용 확인
3. GHCR에 Push
docker tag my-nginx ghcr.io/soheegit/my-nginx:latest
docker push ghcr.io/soheegit/my-nginx:latest- ghcr.io/USERNAME/REPO_NAME:TAG 형식
- GHCR 로그인은 docker login ghcr.io 후 진행
4. 공개 이미지로 테스트 실행
docker run -d -p 8989:80 --name public-nginx-dockerfile ghcr.io/soheegit/my-nginx:latest- 외부에서도 GHCR에서 pull 가능 여부 테스트
5. 플랫폼 호환 이미지 (Render 용)
Render는 linux/amd64 기반이므로 플랫폼 명시하여 빌드:
docker build --platform linux/amd64 -t my-nginx:amd64 .
docker tag my-nginx:amd64 ghcr.io/soheegit/my-nginx:amd64
docker push ghcr.io/soheegit/my-nginx:amd646. Render 배포
- Render → New Web Service 선택
- Deploy from Docker Image 선택
- Image URL:
ghcr.io/soheegit/my-nginx:amd64- Port: 80
- 서비스 타입: Web Service (Public)

Activity
[-]TIL -2025-05-20 [바이브 코딩, Ollama][/-][+]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain)][/+][-]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain)][/-][+]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), GHCR 실습][/+][-]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), GHCR 실습][/-][+]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), docker nginx 실습][/+][-]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), docker nginx 실습][/-][+]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), Docker + GHCR 기반 Nginx 웹페이지 배포 실습][/+][-]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), Docker + GHCR 기반 Nginx 웹페이지 배포 실습][/-][+]TIL -2025-05-20 [바이브 코딩, Ollama, 랭체인(LangChain), Docker + GHCR 기반 Nginx 웹페이지 배포 실습, Nginx Dockerfile 이미지 GHCR에 Push & Render 배포][/+]s0ooo0k commentedon May 22, 2025
💯 정리를 정말 잘하시네요 !!! 수업 중에 놓친 부분이 있었는데 ㅎㅎ 덕분에 참고하겠습니다 ..