본문 바로가기
AI 오케스트레이션 캠프/일차별 회고

45일차 회고|Docker Compose·MCP HTTP·Docker Hub|AI 오케스트레이션 개발자 국비지원

by 랩보다 AI 더 잘해지기 2026. 9. 11.
728x90

 

오늘은 지금까지 배웠던 Docker, MCP, Backend/Frontend 분리, 환경변수 관리를 실제 실행 가능한 형태로 연결해보는 날이었다.

오전에는 AI 산업의 흐름과 Physical AI에 대한 이야기를 시작으로, AI Factory와 DevOps/MLOps를 살펴봤다. 이후에는 Docker Compose로 여러 서비스를 묶어 실행하는 방법을 실습했고, 오후에는 PostgreSQL 재구성 → Multi-LLM 실행 → Docker Hub 이미지 공유 → MCP 서버 HTTP 전환 → 4개 컨테이너 구성까지 이어졌다.

단순히 Docker 명령어 몇 개를 외우는 것보다, 지금까지 배운 기술들이 하나의 서비스로 어떻게 연결되는지를 이해하는 데 의미가 있었던 하루였다.


1. 오늘 배운 내용

오늘 가장 크게 배운 것은 애플리케이션을 여러 개의 서비스로 나누고, Docker를 이용해 하나의 실행 환경으로 구성하는 방법이었다.

기존에는 로컬 환경에서 Python 가상환경을 만들고 필요한 패키지를 설치한 뒤 Backend나 Streamlit을 직접 실행했다면, Docker를 사용하면 필요한 실행 환경 자체를 이미지로 만들 수 있다.

여기에 Docker Compose를 사용하면 여러 컨테이너를 한 번에 관리할 수 있다.

오늘 실습에서는 다음과 같은 구조를 계속 확인했다.

Frontend
   ↓
Backend
   ↓
MCP Server
   ├── Travel MCP
   └── Policy MCP

특히 마지막 실습에서는 Frontend, Backend, Travel MCP, Policy MCP를 각각 컨테이너로 구성하고 서로 HTTP로 연결했다.


2. AI Factory와 DevOps/MLOps

첫 시간에는 코딩보다는 AI 산업의 큰 흐름에 대한 내용을 들었다.

LLM이 발전하면서 GPU와 HBM, 데이터센터와 같은 AI 인프라의 중요성이 커지고 있고, 앞으로는 화면 안에서 동작하는 AI를 넘어 실제 물리적인 환경에서 움직이는 Physical AI가 중요해질 수 있다는 내용이었다.

Physical AI는 쉽게 말하면 AI가 로봇과 같은 물리적인 장치에 들어가 주변 환경을 인식하고 실제 행동까지 수행하는 것이다.

특히 로봇이 단순히 걷고 뛰는 것보다 실제 공장에서 물건을 집고 옮기는 것처럼 현실 세계에서 정확하게 작업하는 능력이 중요하다는 부분이 인상적이었다.

이후에는 AI Factory, DevOps, MLOps를 연결해서 설명했다.

  • AI Factory: AI 모델을 학습하고 서비스하기 위한 대규모 컴퓨팅 인프라
  • DevOps: 개발(Development)과 운영(Operations)을 연결하는 방식
  • MLOps: 머신러닝 모델의 개발부터 테스트, 배포, 운영까지 관리하는 방식

지금까지는 코드를 작성하고 실행하는 것에 집중했다면, 실제 서비스에서는 작성한 코드를 어떻게 배포하고 계속 운영할 것인가도 중요하다는 것을 다시 생각하게 됐다.


3. Docker Compose로 여러 서비스를 묶어보기

오전 실습에서는 Docker Compose를 사용했다.

Docker Compose는 여러 개의 Docker 컨테이너를 하나의 설정 파일로 관리할 수 있게 해주는 도구다.

예를 들어 Frontend와 Backend를 각각 별도의 컨테이너로 만들고 다음과 같이 실행할 수 있다.

docker-compose.yml

services:
  backend:
    ...

  frontend:
    ...

여기서 중요한 점은 Frontend와 Backend를 굳이 하나의 거대한 컨테이너에 넣을 필요가 없다는 것이었다.

서비스를 분리하면 각각 독립적으로 수정하거나 확장하기 쉬워진다.

또한 Docker Compose에서는 컨테이너끼리 통신할 때 서로의 IP 주소를 직접 입력하기보다 서비스 이름을 이용해서 접근할 수 있다.

이 부분은 팀 프로젝트에서 여러 서버와 서비스를 연결할 때도 중요한 개념이라고 느꼈다.


.env와 .venv는 다르다

오늘 다시 확실하게 구분하게 된 것도 있다.

.env

는 API Key나 DB 접속 정보처럼 실행 환경에서 필요한 환경변수를 저장하는 파일이고,

.venv

는 Python 패키지를 독립적으로 관리하기 위한 가상환경이다.

이 둘은 이름이 비슷해 보이지만 역할이 완전히 다르다.

특히 .env에는 API Key 같은 민감한 정보가 들어갈 수 있기 때문에 Git에 그대로 올리면 안 된다.

Docker 이미지에도 불필요한 환경파일이 들어가지 않도록 .dockerignore를 사용할 수 있다는 것도 함께 배웠다.

.dockerignore는 Git의 .gitignore와 비슷하게 Docker 이미지 빌드 과정에서 제외할 파일을 지정하는 역할을 한다.


4. Docker Compose 설정을 검증하는 방법

Docker Compose 설정 파일은 YAML 형식으로 작성한다.

YAML은 JSON과 비슷하게 데이터를 구조화해서 표현하지만, 중괄호나 쉼표 등을 많이 사용하지 않아 설정 파일을 작성하기 편하다.

오늘은 작성한 Compose 파일이 정상적인지도 직접 확인했다.

docker compose config --quiet

정상적인 설정이라면 별도의 출력 없이 통과하고, 일부러 services 같은 필수 구조를 제거했을 때는 설정 오류가 발생했다.

이 과정을 통해 단순히 docker compose up부터 실행하기보다 실행 전에 설정 자체가 올바른지 검증할 수 있다는 것을 알게 됐다.


5. PostgreSQL과 Multi-LLM 실행

이후에는 PostgreSQL 환경을 다시 구성하고 DB 초기화 과정도 진행했다.

Docker 환경에서는 기존에 사용하던 로컬 IP나 접속 주소가 그대로 적용되지 않을 수 있기 때문에, Compose에서 정의한 서비스 구조에 맞게 DB 연결 정보를 수정해야 했다.

또한 초기 SQL 파일을 이용해서 서비스에서 필요한 테이블을 생성했다.

DB가 제대로 준비되어야 Backend가 정상적으로 동작할 수 있기 때문에, 지금까지 배운 Backend ↔ DB 연결도 다시 확인할 수 있었다.

그다음에는 Multi-LLM 환경을 실행했다.

오늘 실습에서는 GPT, Gemini와 함께 Ollama를 이용한 로컬 LLM도 다뤘다.

Ollama는 로컬 컴퓨터에서 오픈소스 LLM을 실행할 수 있도록 해주는 도구다.

이를 통해 하나의 애플리케이션에서 여러 모델을 사용할 수 있고, 모델마다 답변의 속도나 결과가 다를 수 있다는 점도 직접 확인했다.


6. Dockerfile과 Docker Compose의 차이

오늘 헷갈리기 쉬웠던 개념도 정리했다.

Dockerfile

하나의 서비스가 실행될 수 있는 이미지를 어떻게 만들 것인지 정의한다.

Python 환경
↓
필요한 패키지 설치
↓
소스 코드 복사
↓
실행 명령

Docker Compose

그렇게 만들어진 여러 서비스를 어떻게 연결하고 실행할 것인지 정의한다.

즉,

Dockerfile = 하나의 서비스 이미지를 만드는 설명서

Docker Compose = 여러 서비스를 함께 운영하기 위한 구성도

라고 이해하면 훨씬 쉬웠다.


7. Docker Hub에 이미지 올려보기

오후에는 Docker Hub도 실습했다.

Docker Hub는 쉽게 말하면 Docker 이미지를 저장하고 공유할 수 있는 저장소다.

GitHub가 소스 코드를 저장하고 공유하는 곳이라면, Docker Hub는 만들어진 Docker 이미지를 저장하고 공유하는 곳이라고 이해할 수 있었다.

전체적인 흐름은 다음과 같았다.

Dockerfile
   ↓
이미지 Build
   ↓
Tag
   ↓
Docker Hub Push

여기서 각각의 명령어가 하는 역할도 구분했다.

  • build → 이미지 만들기
  • tag → 이미지에 저장소/버전 이름 붙이기
  • push → Docker Hub에 업로드
  • pull → Docker Hub에서 이미지 다운로드
  • up → 컨테이너 생성 및 실행
  • -f → 사용할 Compose 파일 지정

특히 pull과 up을 구분하는 것이 중요했다.

pull
= 이미지를 가져온다.

up
= 가져온 이미지를 이용해서 컨테이너를 실행한다.

처음에는 Docker 명령어가 비슷해 보여서 헷갈렸는데, 역할을 흐름으로 생각하니 조금씩 정리가 됐다.


8. MCP 서버를 STDIO에서 HTTP로 변경

오늘 오후 후반부에는 지금까지 배웠던 MCP를 Docker 환경에서 실행하기 위한 작업도 진행했다.

기존 Policy MCP 서버는 STDIO 방식으로 실행할 수 있었는데, Docker 컨테이너끼리 통신할 수 있도록 HTTP 방식도 사용할 수 있게 수정했다.

환경변수를 이용해서 transport 방식을 선택하도록 구성했다.

MCP_TRANSPORT = os.getenv("MCP_TRANSPORT", "stdio")

그리고 HTTP 방식에서는 Policy MCP가 별도의 HTTP 서버로 실행되도록 구성했다.

실제로 STDIO 방식과 HTTP 방식을 각각 확인했고, 호텔 정책 조회 기능이 정상적으로 동작하는 것도 검증했다.


9. Backend에서 MCP 서버를 HTTP로 연결

다음 단계에서는 Backend가 Policy MCP 서버의 HTTP 주소를 환경변수로 받을 수 있도록 수정했다.

핵심은 다음과 같은 구조였다.

Backend
   ↓
TRAVEL_MCP_URL
POLICY_MCP_URL
   ↓
Travel MCP / Policy MCP

로컬 환경에서는

http://127.0.0.1:8011/mcp

형태로 연결하고, Docker Compose 환경에서는 컨테이너 간 통신을 위해 서비스 이름을 이용하는 방식으로 구성했다.

기존 STDIO 방식도 URL을 비워두면 사용할 수 있도록 fallback을 남겨두었다.

실제로 Travel MCP와 Policy MCP를 HTTP로 연결한 뒤 날씨 조회, 호텔 검색, 호텔 정책 조회까지 정상적으로 확인했다.

이 부분은 오늘 실습 중에서 특히 의미가 있었다.

단순히 MCP 서버 하나를 실행하는 것에서 끝나는 것이 아니라,

Backend가 MCP를 연결하고 → MCP가 Tool을 제공하고 → 결과가 다시 사용자에게 전달되는 전체 흐름

을 Docker 환경으로 확장했기 때문이다.


10. 4개의 Docker 컨테이너로 구성하기

이후에는 서비스를 각각 Docker 이미지로 만들기 위해 Dockerfile도 분리했다.

구성은 다음과 같았다.

Frontend
 └─ Dockerfile

Backend
 └─ Dockerfile

Travel MCP
 └─ Dockerfile.travel

Policy MCP
 └─ Dockerfile.policy

그리고 Docker Compose에서 네 서비스를 연결했다.

Frontend
   ↓
Backend
   ↓
Travel MCP
Policy MCP

Compose에서는 각 서비스의 build, image, environment, ports, healthcheck, depends_on 등을 정의했다.

결과적으로 4개의 컨테이너가 정상적으로 실행되고 Health 상태도 정상인 것을 확인했다.

또한 실제 요청을 보내서

날씨 조회
   ↓
호텔 검색
   ↓
호텔 정책 조회
   ↓
최종 답변

까지 이어지는 End-to-End 테스트도 성공했다.


11. .env를 서버별로 분리하고 Docker Hub까지 연결

오늘 직접 진행한 작업 중 하나는 .env를 서비스별로 나누는 것이었다.

Backend에는 API Key 등 필요한 환경변수를 넣고, 각각의 서비스가 필요한 환경 설정을 별도로 관리하는 형태로 정리했다.

그리고 .env가 Docker 이미지 안에 포함되지 않았는지도 확인했다.

마지막으로 Frontend, Backend, Travel MCP, Policy MCP 4개의 Docker 이미지를 Docker Hub에 업로드했고, 다른 환경에서 실행할 수 있도록 배포용 ZIP과 실행 가이드도 만들었다.

다만 Docker Hub에 올린 이미지를 완전히 새로운 환경에서 다시 pull → up하여 최종 배포까지 검증하는 단계는 이후 작업으로 남아 있었다.


12. 오늘 새롭게 이해한 점

오늘 가장 크게 달라진 부분은 Docker를 단순히 "프로그램을 실행하는 도구"로 생각하지 않게 된 것이다.

처음에는 Docker를 사용하면 Python이나 라이브러리를 설치하지 않아도 된다는 정도로 이해했다.

하지만 오늘 여러 서비스를 직접 연결해보면서 Docker의 역할을 조금 더 구체적으로 이해하게 됐다.

소스 코드
   ↓
Dockerfile
   ↓
Docker Image
   ↓
Docker Hub
   ↓
다른 환경에서 Pull
   ↓
Docker Compose
   ↓
여러 Container 실행
   ↓
실제 서비스

결국 Docker는 단순히 개발자의 컴퓨터에서 프로그램을 실행하는 것을 넘어 "내가 만든 프로그램이 다른 환경에서도 같은 방식으로 실행될 수 있도록 실행 환경을 함께 묶어주는 방법"이라고 이해하게 됐다.

그리고 MCP 역시 단순히 Tool을 만드는 기술이라고만 생각했는데, 오늘 HTTP와 Docker를 연결하면서 여러 서버와 서비스 사이에서 AI Agent가 사용할 기능을 연결하는 구조라는 점이 더 명확해졌다.


13. 아직 복습이 필요한 부분

오늘 배운 내용은 양이 많아서 아직 명령어나 설정을 모두 외웠다고 하기는 어렵다.

특히 다음 부분은 다시 복습해야 할 것 같다.

① Dockerfile과 Compose의 관계

둘의 역할은 구분할 수 있지만 실제 YAML 설정을 처음부터 작성하려면 아직 익숙하지 않다.

② Docker 네트워크

컨테이너가 서로의 서비스 이름을 통해 통신하는 원리를 조금 더 공부할 필요가 있다.

③ .env와 보안

환경변수를 분리하는 것은 이해했지만 실제 프로젝트에서 어떤 값까지 .env로 분리하고, 어떤 방식으로 배포 환경에서 관리하는지는 더 공부해야 한다.

④ MCP HTTP 통신

STDIO와 HTTP 방식의 차이는 이해했지만, MCP의 통신 구조 자체를 더 깊게 이해할 필요가 있다.

⑤ Docker Hub 배포 과정

build → tag → push → pull → up의 흐름은 이해했지만 실제 서버 환경에서 직접 배포하는 경험은 아직 부족하다.


14. 오늘의 회고

45일차는 지금까지 배운 기술들을 "실행 가능한 서비스 구조"로 연결해본 날이었다.

처음에는 Git, Python, Backend, DB, MCP, Docker처럼 각각의 기술을 따로 배우는 느낌이 강했다.

그런데 오늘은 이 기술들이 하나의 흐름으로 연결됐다.

Frontend
   ↓
Backend
   ↓
MCP
   ↓
Tool
   ↓
DB / 외부 데이터

그리고 이 전체 서비스를 Docker로 묶고,

Dockerfile
   ↓
Image
   ↓
Docker Hub
   ↓
Compose
   ↓
Container

형태로 다른 환경에서도 실행할 수 있도록 만드는 과정까지 경험했다.

특히 최근 미니프로젝트에서 Frontend와 Backend, MCP, DB가 서로 연결되는 구조를 계속 접했던 만큼 오늘 내용이 이전보다 훨씬 현실적으로 느껴졌다.

아직 Docker나 MCP 설정을 혼자 처음부터 작성할 수 있을 정도로 익숙한 단계는 아니다. 하지만 각 기술이 왜 필요한지, 서로 어떤 관계로 연결되는지는 예전보다 훨씬 명확하게 볼 수 있게 됐다.

앞으로 AWS와 멀티 에이전트 학습으로 넘어가게 되면 결국 중요한 것은 개별 기술 하나를 외우는 것이 아니라,

AI Agent가 어떤 Tool을 사용하고, 각 서비스가 어떻게 연결되며, 그것을 실제 환경에 어떻게 배포하고 운영할 것인가

를 이해하는 것이라고 생각한다.

45일차는 그 전체적인 그림을 한 번 더 연결해서 볼 수 있었던 하루였다.


핵심 정리

  • Docker → 애플리케이션 실행 환경을 컨테이너로 묶어 관리
  • Dockerfile → 하나의 Docker 이미지를 만드는 방법 정의
  • Docker Compose → 여러 서비스를 연결하고 함께 실행
  • Docker Hub → Docker 이미지 저장 및 공유
  • .env → 환경변수와 민감한 설정을 별도로 관리
  • .dockerignore → Docker 이미지에 불필요한 파일이 포함되지 않도록 제외
  • MCP HTTP → MCP 서버를 HTTP 방식으로 연결
  • Multi-LLM → 여러 LLM을 하나의 애플리케이션에서 활용
  • AI Factory / DevOps / MLOps → AI 서비스를 실제 운영 환경까지 연결하는 관점

댓글