서버·SSH·도커 컨테이너 개념 정리: 첫 배포 전에 뚫어야 했던 것들

EC2 가상 서버, ssh 원격 접속과 pem 키, 도커 이미지와 컨테이너의 층위를 첫 운영 배포 전에 정리했다. 배포 전 커밋 해시 기록, 스크립트 먼저 읽기, CDN 캐시 함정까지.

조회 –
목차

회사 서비스의 운영 배포를 처음 맡게 됐다. 배포 자체는 "서버에 들어가서 이미 있는 배포 스크립트를 한 번 돌리는 것"인데, 그 한 줄 안의 단어를 하나도 몰랐다. 서버, ssh, 도커, 이미지, 컨테이너 — 전부 처음이라 실행 전에 개념부터 뚫었다.

뭐가 막혔나

  • "배포한다"가 물리적으로 무슨 일인지 그림이 안 그려졌다. 내 컴퓨터에서 빌드해서 올리는 건 줄 알았는데 아니었다.
  • ssh, 컨테이너, 이미지가 각각 뭔지 몰랐고, 도커 컨테이너가 곧 서버인 줄 알았다. 층위(물리 서버 → 가상 서버 → 도커 → 컨테이너)가 머릿속에 없었다.
  • 제일 찜찜했던 건 "내가 뭐 한 게 없는데 도커가 작동한다"는 것. 어디에 뭐가 설치돼 있고 누가 만들어둔 건지 모른 채 돌아가는 게 불안했다.

하나씩 질문해서 층을 쌓았다

배포 흐름 한 줄 — 내 컴퓨터에서 서버에 원격 접속해서, 서버가 스스로 최신 코드를 받아 빌드하고 새로 띄우게 하는 것. 빌드도 실행도 전부 서버 안에서 일어나고, 내 컴퓨터는 터미널로 구경만 한다.

서버 = 클라우드(AWS)에서 빌린 가상 컴퓨터(EC2 인스턴스). 사무실에 실물이 있는 게 아니라 데이터센터의 컴퓨터를 빌려 24시간 켜두는 것. 인프라 담당이 콘솔에서 만들었고, 그때 접속 열쇠(.pem 키)도 같이 발급됐다.

ssh = 남의 컴퓨터 터미널을 내 터미널처럼 쓰는 도구. ssh -i 키파일 계정@서버IP 이후 치는 명령은 내 맥이 아니라 서버에서 실행된다(ls 치면 서버 파일이 나온다). 비밀번호 대신 .pem 키로 신분을 증명하고, chmod 400으로 키를 잠가두지 않으면 ssh가 "열쇠 관리가 헐겁다"며 거부한다. 나가는 건 exit.

이미지와 컨테이너 — 도시락 비유가 잘 먹혔다.

  • 이미지 = 레시피(Dockerfile)대로 다 조리해서 밀봉한 팩. 앱 + 런타임 버전 + 패키지 + 빌드 결과물을 한 덩어리로 얼려둔 것. docker build가 조리 과정.
  • 컨테이너 = 그 팩을 뜯어서 실행 중인 상태. 이미지 하나로 여러 개 띄울 수 있다.
  • 배포 = 새 코드로 이미지를 새로 만들고, 기존 컨테이너를 내리고, 새 이미지로 다시 올리는 것. 이전 이미지가 남아 있으면 그게 곧 롤백 수단이다.
  • 왜 이렇게 하나: "내 맥에선 되는데 서버에선 안 돼"를 없애려고. 실행 환경이 이미지 안에 다 들어 있어서 어디서 띄워도 똑같이 돈다.

층위 — 컨테이너는 서버가 아니라 서버 안의 프로세스 하나다.

클라우드 물리 서버
 └ 가상 서버 (빌린 컴퓨터, Ubuntu)
    └ Docker (서버에 설치된 프로그램)
       └ 컨테이너 (우리 앱이 실행 중인 상태)

부엌(가상 서버)에 전자레인지(Docker)가 있고 그 안에 도시락(컨테이너)이 돌아가는 느낌.

"내가 안 만들었는데 왜 돌아가나"

각 조각의 주인이 다 따로 있었다.

  • Docker 프로그램: 서버 세팅 때 인프라 담당이 설치 (내 맥엔 없어도 됨)
  • Dockerfile: 저장소 안에 있고 프로젝트 만든 사람이 작성
  • 이미지/컨테이너: 서버의 배포 스크립트가 docker build/docker run으로 생성
  • 내 역할: 서버에 들어가 스크립트를 한 번 실행하고 결과를 보는 것

운영 안전장치로 배운 것들

  • 스테이징이 없으면 dev 머지 = 바로 운영. 그래서 실행 전에 지금 운영 중인 커밋 해시를 먼저 적어두고, 되돌릴 방법이 없으면 실행하지 않는다.
  • 배포 스크립트는 돌리기 전에 먼저 읽는다(1단계 = 읽기만). "아마 pull → build → 컨테이너 교체일 것"이라는 추측을 확인으로 바꾸는 단계.
  • docker ps로 배포 전/후를 비교해서 실제로 새 컨테이너로 바뀌었는지 확인.
  • 환경변수 파일(.env)은 저장소에 없고 서버에만 있다 — 빌드가 그걸 읽는지 확인해야 한다. 빠지면 빌드는 성공하는데 API 주소가 비어서 사이트가 깨진다.
  • 앞단에 CDN(Cloudflare)이 있으면 배포 직후 옛 화면이 보일 수 있다. 캐시지 배포 실패가 아니다 — ?cb=타임스탬프로 캐시를 우회해서 확인한다.

남길 것

  • "내가 뭐 한 게 없는데 돌아간다" = "무슨 일이 일어나는지 모른 채 운영을 건드린다". 이 찜찜함은 무시할 게 아니라 "실행 전에 읽기" 단계를 만들 신호였다.
  • 배포를 처음 배울 때 필요한 건 명령어 목록이 아니라 층위 그림이었다. 물리 서버 → 가상 서버 → 도커 → 컨테이너가 그려지자 나머지 질문이 스스로 풀렸다.
  • 성공 기준을 미리 문장으로 박아두는 것: 이번 건은 "화면 변화 없음 + 콘솔 에러와 특정 API 404 소멸"이 성공. 기준이 없으면 배포 후 뭘 봐야 할지 모른다.
  • 롤백 수단(이전 이미지, 이전 커밋 해시)을 실행 전에 확보하는 습관.

더 봐야 할 것

  • 배포 스크립트 실제 내용 읽기 (추측을 확인으로 바꾸기)
  • Dockerfile 문법 — 레시피에 실제로 뭐가 적혀 있는지
  • 무중단 배포 (지금 방식은 컨테이너를 내리고 올리는 사이 순단이 있는 것 아닌지)

사이트 내 검색

제목·태그·설명·본문으로 발행 글을 찾습니다