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

50일차 회고|Docker·AWS 배포·CI/CD|AI 오케스트레이션 개발자 국비지원

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

 

어느덧 국비지원 과정 50일차가 됐다.

이번 학습에서는 단순히 애플리케이션을 AWS에 올리는 것을 넘어 Docker로 서비스를 분리해 배포하고, AWS 인스턴스 간 네트워크를 연결하고, GitHub Actions를 이용해 CI/CD를 구성하는 과정을 집중적으로 다뤘다.

이전까지는 "애플리케이션을 어떻게 개발하는가"에 가까웠다면, 이번에는 개발한 결과물을 어떻게 안정적으로 배포하고 관리할 것인가에 대한 비중이 훨씬 커졌다.

특히 이번에는 개발(Development)뿐만 아니라 운영(Operations) 영역까지 직접 경험해보면서, 실제 서비스를 만들 때 왜 배포 환경과 자동화가 중요한지 조금 더 현실적으로 이해할 수 있었다.


1. 이번 학습에서 가장 크게 달라진 것

이번 학습에서 가장 인상적이었던 부분은 하나의 서버에서 모든 서비스를 실행하는 방식에서 벗어나 서비스를 역할별로 나누는 것이었다.

기존에는 Docker Compose 하나로 Frontend와 Backend를 함께 묶어 이미지화하고 배포하는 방식을 사용했다.

이번에는 이를 분리해서,

  • Frontend
  • Backend
  • Database
  • Redis

등을 각각 독립적으로 실행할 수 있도록 구성했다.

즉, 단순히 "Docker를 사용한다"가 아니라 각 서비스가 어디에서 실행되고 서로 어떻게 통신하는지를 직접 구성하는 단계로 넘어간 것이다.


2. Docker Compose로 서비스를 개별 배포하기

먼저 로컬 환경에서 Frontend와 Backend를 각각 Docker 이미지로 만들고 별도로 실행해봤다.

실행 중인 컨테이너는 docker ps로 확인하고, 현재 가지고 있는 이미지는 docker images로 확인했다.

여기서 새롭게 신경 쓰게 된 부분은 Docker Compose 파일의 이름을 명확하게 지정하는 것이었다.

기본적으로 docker compose up을 실행하면 기본 Compose 파일을 찾지만, 우리가 사용하는 파일이 compose-release.yml처럼 다른 이름이라면 해당 파일을 직접 지정해야 한다.

예를 들어 환경에 따라 다음과 같이 특정 Compose 파일을 지정해서 실행하거나 종료할 수 있다.

docker compose -f compose-release.yml up
docker compose -f compose-release.yml down

처음에는 docker compose down 정도면 되는 줄 알았는데, 실제로는 현재 어떤 Compose 파일을 기준으로 컨테이너를 실행했는지를 알고 있어야 했다.

또한 down을 실행했다고 이미지까지 사라지는 것은 아니었다.

컨테이너를 정리한 뒤 필요하지 않은 이미지까지 정리하려면 별도로 이미지 삭제 작업이 필요했다.

이 과정에서 Docker의 구조를 조금 더 명확하게 이해할 수 있었다.

이미지(Image) → 컨테이너(Container) → 실행 중인 서비스

컨테이너와 이미지는 같은 것이 아니며, 실행 중인 컨테이너를 내리는 것과 이미지 자체를 삭제하는 것도 별개의 작업이었다.


3. AWS에서 Frontend와 Backend를 분리하기

이번에는 로컬에서 테스트한 구조를 AWS 환경에서도 적용했다.

팀에서 여러 개의 EC2 인스턴스를 사용하고 있기 때문에 각각의 인스턴스에 역할을 부여할 수 있었다.

예를 들어 하나의 인스턴스에는 Frontend, 다른 인스턴스에는 Backend, 또 다른 인스턴스에는 Database나 Redis를 배치하는 방식이다.

이렇게 서비스를 분리하면 각 서버가 어떤 역할을 담당하는지 명확해진다.

하지만 여기서 새로운 문제가 생겼다.

서버가 분리되었으니 서로 통신할 방법이 필요했다.


4. Security Group과 포트의 관계

AWS에서 서버 간 통신을 구성하면서 Security Group의 Inbound Rule을 직접 설정했다.

예를 들어 Backend가 특정 포트로 요청을 받아야 한다면 해당 포트를 열어줘야 하고, Database나 Redis 역시 필요한 포트가 따로 있다.

이번 실습에서는 대표적으로 다음과 같은 포트를 사용했다.

서비스포트

Frontend 8000
PostgreSQL 5432
Redis 6379

중요했던 것은 무조건 모든 포트를 열어놓는 것이 아니라 필요한 포트와 접근 대상을 지정하는 것이었다.

예를 들어 Backend 서버가 Database에 접근해야 한다면 Database 쪽에서 Backend의 접근을 허용해야 한다.

이 과정을 직접 설정하면서 "서버가 연결되지 않는다"는 문제가 발생했을 때 단순히 코드만 볼 것이 아니라,

IP → 포트 → Security Group → 환경변수 → 실제 서비스 실행 상태

를 순서대로 확인해야 한다는 것을 배웠다.


5. Private IP와 Public IP

여기서 특히 헷갈렸던 부분이 Private IP와 Public IP의 차이였다.

같은 AWS 환경이라고 해서 모든 EC2가 동일한 네트워크에 있는 것은 아니었다.

팀별 인스턴스의 VPC 구성이 다를 수 있기 때문에 Private IP를 이용해 통신하려면 네트워크 구성 자체가 맞아야 한다.

반대로 서로 다른 VPC 환경에서는 단순히 Private IP를 입력한다고 통신할 수 있는 것이 아니었다.

이번 실습에서는 복잡한 VPC 연결을 추가로 구성하기보다 필요한 포트를 Security Group에서 허용하고 Public IP를 이용해 연결하는 방식도 경험했다.

그리고 이 과정에서 중요한 점을 하나 알게 됐다.

IP 주소를 알고 있다는 것과 실제로 해당 서버에 접근할 수 있다는 것은 다른 문제다.

IP가 정확하더라도 Security Group에서 해당 포트를 허용하지 않았다면 연결할 수 없다.

결국 AWS 배포에서 애플리케이션 코드뿐만 아니라 네트워크 구조까지 이해해야 한다는 것을 체감했다.


6. .env가 생각보다 중요했다

서비스를 분리하면서 환경변수의 중요성도 커졌다.

예를 들어 Frontend가 Backend를 호출해야 한다면 Backend의 주소가 필요하고, Backend는 Database와 Redis의 주소를 알아야 한다.

따라서 각각의 서비스에서 연결 대상 IP와 포트를 환경 설정으로 관리해야 했다.

특히 배포 과정에서 문제가 발생했을 때 무작정 코드를 수정하기보다는,

  1. 컨테이너 상태 확인
  2. 이미지 상태 확인
  3. 환경변수 확인
  4. IP와 포트 확인
  5. Security Group 확인
  6. 다시 Compose 실행

순으로 확인하는 접근이 필요했다.

이번 학습에서 개인적으로 중요하게 느낀 부분이다.

코드와 환경 설정을 분리해두면 동일한 애플리케이션을 다른 환경에 배포하기가 훨씬 쉬워진다.


7. CI를 직접 구성해보기

AWS에 배포하는 것까지 해봤다면 다음 단계는 CI(Continuous Integration, 지속적 통합)였다.

CI는 쉽게 말하면 개발자가 코드를 GitHub에 올렸을 때 자동으로 테스트와 빌드 등을 수행해 현재 코드에 문제가 없는지 확인하는 과정이다.

GitHub Actions를 이용해 Workflow를 구성했다.

구조는 대략 다음과 같다.

코드 수정
   ↓
Commit
   ↓
Push / Pull Request
   ↓
GitHub Actions
   ↓
Test
   ↓
Docker Build
   ↓
CI 통과

여기서 중요한 것은 단순히 Python 테스트만 하는 것이 아니었다.

Docker 이미지를 실제로 빌드해보면서 배포에 사용할 이미지가 정상적으로 생성되는지까지 확인했다.


8. 로컬 테스트가 먼저 필요한 이유

GitHub Actions에 올리기 전에 로컬에서 테스트 환경을 구성하는 과정도 진행했다.

가상환경을 만들고 테스트에 필요한 패키지를 설치한 뒤 테스트 프로그램을 실행했다.

예를 들어 pytest를 이용해 Backend 등의 테스트를 수행했다.

처음에는 테스트가 단순히 "코드가 실행되는지 확인하는 과정"이라고 생각했는데, 이번 학습을 통해 테스트의 역할을 조금 더 넓게 이해하게 됐다.

실제 프로젝트에서는 테스트해야 할 코드가 많기 때문에 모든 테스트를 사람이 직접 실행하는 것은 비효율적이다.

그래서 GitHub Actions를 이용해 코드가 변경될 때 자동으로 테스트를 수행하도록 만들 수 있다.


9. CI와 CD의 차이를 이해하다

이번 학습에서 가장 중요한 개념 중 하나였다.

CI와 CD는 비슷하게 들리지만 역할이 다르다.

CI

코드 변경
→ 테스트
→ 빌드
→ Docker 이미지 생성 확인

CD

CI 통과
→ 배포 작업
→ AWS 서버에 반영

즉, CI에서 문제가 있는 코드를 걸러낸 다음 CD를 통해 실제 서버에 배포하는 구조다.

왜 이렇게 해야 하는지도 직접 배포를 경험하면서 이해하게 됐다.

코드에 문제가 있는 상태에서 바로 AWS까지 배포해버리면 서버에서 오류가 발생하고, 그때부터는 네트워크 문제인지, 환경변수 문제인지, Docker 문제인지, 애플리케이션 문제인지 하나씩 확인해야 한다.

반대로 CI 단계에서 테스트와 Docker Build까지 통과했다면 적어도 배포하기 전에 확인할 수 있는 문제를 어느 정도 걸러낼 수 있다.

그래서 강의에서 강조한

CI를 통과한 뒤 CD로 넘어간다.

라는 흐름이 이해됐다.


10. Git Branch와 GitHub Actions 연결

CI가 언제 실행되는지도 직접 확인했다.

Main Branch에서만 작업하는 것이 아니라 개인 Branch를 만들어 코드를 수정하고 Commit과 Push를 진행했다.

그리고 Branch에서 변경사항을 Push하거나 다른 Branch의 변경사항을 Main으로 가져오는 과정에서 GitHub Actions가 어떻게 동작하는지 확인했다.

전체적인 협업 흐름을 정리하면 다음과 같다.

개인 Branch 생성
      ↓
코드 수정
      ↓
Commit
      ↓
Push
      ↓
CI 실행
      ↓
테스트 + Docker Build
      ↓
Main Branch로 반영
      ↓
CD
      ↓
AWS 배포

이제 Git을 단순히 "코드를 올리고 내려받는 도구"로 보는 것에서 조금 벗어나게 됐다.

Branch와 Pull Request, GitHub Actions가 연결되면 협업 과정 자체에 테스트와 검증을 넣을 수 있다는 것을 알게 됐다.


11. 모든 Push마다 CI를 돌리는 것이 좋은 것은 아니다

실습 과정에서 Push를 할 때마다 CI가 실행되는 것도 확인했다.

처음에는 자동으로 실행되니까 좋은 것처럼 느껴졌지만, 프로젝트 규모가 커지면 모든 Push마다 테스트와 빌드를 실행하는 것이 반드시 효율적인 것은 아니다.

그래서 어떤 이벤트에서 CI를 실행할지 Workflow에서 설정할 수 있다.

예를 들어 특정 Branch나 Pull Request를 기준으로 CI를 실행하도록 구성할 수 있다.

결국 자동화도 무조건 많이 하는 것이 아니라 언제 실행해야 효율적인지를 설계하는 것이 중요하다는 것을 배웠다.


12. 이번 학습에서 어려웠던 점

이번 학습에서 가장 어려웠던 부분은 역시 AWS 네트워크와 Docker, GitHub Actions가 한꺼번에 연결되는 과정이었다.

특히 서버가 분리되면서 하나의 문제가 발생해도 원인을 바로 특정하기 어려웠다.

예를 들어 Backend가 정상적으로 실행되고 있어도 Frontend에서 접근하지 못한다면,

  • Backend 컨테이너가 실행 중인지
  • Backend 포트가 맞는지
  • Backend IP가 맞는지
  • Security Group이 열려 있는지
  • .env가 올바른지
  • 서로 다른 VPC에 있는 것은 아닌지

등을 확인해야 한다.

그래서 이번에는 "코드를 수정해서 해결한다"보다 전체 시스템의 연결 구조를 먼저 확인하는 습관이 중요하다는 것을 알게 됐다.


13. 이번에 새롭게 이해한 것

이번 학습 전에는 Docker와 AWS 배포를 각각의 기술처럼 생각했다.

하지만 이번 과정을 거치면서 각각의 기술이 연결되어 있다는 것을 이해하게 됐다.

애플리케이션
      ↓
Docker 이미지
      ↓
Container
      ↓
AWS EC2
      ↓
Network / Security Group
      ↓
GitHub Actions
      ↓
CI
      ↓
CD
      ↓
자동 배포

결국 개발자가 만드는 것은 코드지만, 실제 서비스로 운영하려면 그 코드를 실행할 환경과 배포 과정까지 함께 생각해야 한다.

특히 이번에는 개발(Dev)뿐만 아니라 운영(Ops)의 영역을 직접 만져봤다는 점에서 이전 학습과 차이가 있었다.


14. 현재 나의 상태

현재는 단순히 Docker 명령어를 외워서 사용하는 수준에서 조금 더 나아가,

  • Docker Compose로 서비스를 실행할 수 있고
  • Frontend와 Backend를 분리해서 배포할 수 있고
  • AWS EC2에 Docker 기반 서비스를 올릴 수 있고
  • Security Group과 포트를 설정할 수 있고
  • .env를 이용해 서비스 간 연결 정보를 관리할 수 있고
  • GitHub Actions로 CI Workflow를 구성할 수 있고
  • 테스트와 Docker Build를 자동화하는 구조를 이해하는 단계까지 왔다.

다만 아직 네트워크 구성이나 CI/CD Workflow를 처음부터 혼자 설계하는 것에는 부족한 부분이 있다.

특히 AWS의 VPC, Security Group, Private/Public IP 관계는 반복해서 직접 구성해보면서 익힐 필요가 있다.


15. 앞으로 보완할 부분

다음 단계에서는 지금 배운 CI/CD를 실제 프로젝트에 적용해보는 것이 중요할 것 같다.

특히 단순히 예제를 따라가는 것에서 끝내지 않고,

코드 수정 → 테스트 → Docker Build → CI → AWS 배포

가 실제로 하나의 흐름으로 연결되는 경험을 더 해보고 싶다.

또한 AWS에서 여러 서비스를 분리해서 운영할 때 네트워크가 어떻게 구성되는지도 계속 복습해야겠다.

이번에는 실습 환경의 제약 때문에 Public IP를 이용한 연결도 사용했지만, 실제 운영 환경에서는 어떤 방식으로 Private Network를 구성하고 접근을 제한하는지도 추가로 공부할 필요가 있다.


16. 이번 50일차 회고

이번 학습을 통해 가장 크게 달라진 생각은 "배포 = 서버에 파일을 올리는 것"이 아니라는 것이다.

서비스를 여러 개로 나누면 각각의 실행 환경이 필요하고, 서로 통신하기 위한 IP와 포트가 필요하다. AWS에서는 Security Group과 VPC 같은 네트워크 구성까지 고려해야 한다.

그리고 여기서 한 단계 더 나아가면 개발자가 매번 직접 서버에 접속해서 배포하는 것이 아니라 GitHub Actions를 이용해 테스트와 빌드를 자동화하고, CI를 통과한 결과물을 CD를 통해 배포할 수 있다.

이번에는 Docker, AWS, Git, GitHub Actions를 각각 따로 배운 것이 아니라 하나의 배포 파이프라인으로 연결해서 경험했다는 점이 가장 의미 있었다.

아직 혼자서 복잡한 CICD 환경을 처음부터 구축할 정도는 아니지만, 적어도 이제는

"코드를 만들었다 → Docker로 실행한다 → AWS에 배포한다 → 테스트한다 → GitHub Actions로 자동화한다 → CI를 통과한 결과를 CD로 배포한다."

라는 전체적인 흐름을 볼 수 있게 됐다.

앞으로는 이 구조를 실제 프로젝트에 적용하면서 개발뿐 아니라 운영까지 고려할 수 있는 개발자가 되는 것을 목표로 해야겠다.


핵심 정리

  • Docker Compose를 이용한 Frontend / Backend 개별 배포
  • Docker 이미지와 컨테이너의 차이 이해
  • AWS EC2 인스턴스 역할 분리
  • Security Group과 Inbound Rule을 이용한 포트 관리
  • Private IP와 Public IP, VPC의 관계 이해
  • .env를 이용한 서비스 간 연결 정보 관리
  • GitHub Actions를 이용한 CI 구성
  • pytest를 활용한 테스트 자동화
  • Docker Image Build 검증
  • Branch / Commit / Push / Pull Request와 CI 연결
  • CI와 CD의 역할 차이 이해
  • CI → CD → AWS 배포로 이어지는 전체 흐름 경험

해시태그

#AI오케스트레이션 #AI에이전트 #Docker #DockerCompose #AWS #EC2 #GitHubActions #CICD #DevOps #개발자국비지원

댓글