PH pullh
입문 블로그 / 배포를 한 번 해 보면 코드가 다르게 보인다
웹과 데이터 5분 Beginner

배포를 한 번 해 보면 코드가 다르게 보인다

로컬에서만 돌아가던 코드를 밖에 올려 보면, 파일 경로와 환경 변수, 실행 방식에 대한 감각이 달라진다.

첫 배포 커버 이미지

입문자는 종종 배포를 나중에 하는 일로 미룬다. 하지만 한 번이라도 직접 배포해 보면, 코드가 컴퓨터 안에서만 사는 것이 아니라는 사실을 훨씬 선명하게 이해하게 된다.

배포 경험은 취업용 장식이 아니라, 프로그램이 실제 환경에서 어떻게 실행되는지 배우는 수업에 가깝다.

그리고 이 수업의 내용은 배포 도구 사용법이 아니다. 내 컴퓨터가 조용히 대신해 주고 있던 것들이 무엇이었는지를 알게 되는 것이다.

배포는 현실 점검이다

로컬에서는 잘 되던 코드가 배포 후에 깨지는 경우가 많다. 파일 경로가 다르거나, 환경 변수가 빠졌거나, 실행 명령이 달라서다.

이 경험을 한 번 겪으면 내 컴퓨터에서는 되는데요라는 말이 왜 충분하지 않은지 몸으로 알게 된다.

가장 자주 깨지는 세 가지

처음 배포에서 만나는 실패는 대체로 세 종류다. 하나씩 보면 별것 아니지만, 처음에는 세 개가 한꺼번에 온다.

첫째는 경로다. 로컬에서 상대 경로로 파일을 열던 코드가 서버에서는 실행 위치가 달라 그대로 실패한다. 둘째는 비밀값이다. 내 컴퓨터에 있던 키 파일이나 셸 설정이 서버에는 없다. 셋째는 실행 명령이다. 에디터의 실행 버튼이 대신 해 주던 명령을 이제 내가 직접 적어야 한다.

BEFORE

API_KEY = "sk-live-9f2c..."
db = sqlite3.connect("data/app.db")
app.run(port=5000, debug=True)

로컬에서는 세 줄 다 동작한다. 서버에서는 세 줄 다 문제가 된다.

AFTER

import os
from pathlib import Path

BASE = Path(__file__).resolve().parent
API_KEY = os.environ["API_KEY"]
db = sqlite3.connect(BASE / "data" / "app.db")
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))

바뀐 것은 세 가지다. 경로의 기준을 파일 위치로 고정하고, 비밀값을 밖으로 빼고, 포트를 환경이 정하게 했다.

이 변화가 흥미로운 지점은, 배포를 위한 수정처럼 보이지만 사실 코드 품질이 함께 올라간다는 데 있다. 실행 위치에 의존하지 않는 코드, 설정과 로직이 분리된 코드는 로컬에서도 더 좋은 코드다. 배포는 그 구분을 강제로 하게 만드는 장치다.

미리 해 보는 실험

서버에 올리기 전에, 프로젝트 폴더가 아닌 다른 위치에서 실행해 보십시오. 거기서 깨지는 것들이 배포에서 깨질 것들과 거의 같습니다.

첫 배포 전에 점검할 것

  • 실행 명령이 문서로 정리돼 있는가
  • 필요한 환경 변수가 무엇인지 적혀 있는가
  • 포트 번호, 파일 경로, 비밀값을 코드에 하드코딩하지 않았는가
  • 디버그 모드가 켜진 채로 올라가지 않는가
  • 빈 폴더에 다시 받아서 실행했을 때 동작하는가
  • 배포 후 첫 화면 또는 첫 API 호출을 직접 확인했는가

깨졌을 때 볼 곳은 코드가 아니다

배포가 실패하면 반사적으로 코드를 다시 읽게 되는데, 대개 답은 다른 곳에 있다. 봐야 할 것은 빌드 로그와 실행 로그다. 로컬에서는 터미널에 바로 뜨던 에러가 서버에서는 로그 파일이나 대시보드 안에 들어가 있을 뿐, 내용은 같다.

그래서 첫 배포를 할 때 가장 먼저 익힐 것은 로그를 보는 방법이다. 어떤 명령으로, 어디를 보면 방금 실행의 출력이 나오는지. 이걸 모르면 화면에 502가 떴다는 사실 외에는 아무 정보도 없는 상태로 추측만 하게 된다. 로그를 열면 대개 로컬에서 보던 익숙한 트레이스백이 그대로 있다.

로그에도 아무것도 없다면 그건 프로그램이 시작조차 못 했다는 뜻이다. 그 경우 원인은 코드가 아니라 빌드나 실행 명령 쪽에 있다. 어느 단계까지 갔는지를 먼저 가르는 것이, 여기서도 범위를 좁히는 방법이다.

배포 이후에 생기는 새로운 질문들

한 번 올리고 나면 그전에는 떠오르지 않던 질문이 생긴다. 코드를 고쳤는데 왜 화면은 그대로인가. 두 사람이 동시에 접속하면 어떻게 되는가. 서버를 껐다 켜면 저장했던 데이터는 남아 있는가. 이 질문들은 책에서 읽으면 추상적이지만, 내 프로젝트에서 겪으면 하나하나가 구체적인 사건이다.

특히 세 번째 질문이 중요하다. 로컬에서 개발할 때는 컴퓨터를 껐다 켜도 파일이 그대로 있으니, 데이터가 어디에 사는지 신경 쓸 일이 없다. 그런데 배포 환경에서는 실행이 새로 시작될 때 파일 시스템이 초기화되는 경우가 흔하다. 이때 비로소 메모리에 담는 것과 파일에 쓰는 것과 데이터베이스에 넣는 것이 왜 다른 이야기인지 감각적으로 구분된다.

이런 질문은 순서를 만들어 준다는 점에서도 유용하다. 무엇을 다음에 공부해야 하는지 남에게 물을 필요 없이, 내 프로젝트가 다음 주제를 지정해 주기 때문이다. 배포가 학습 계획을 대신 짜 주는 셈이다.

배포가 먼저가 아닐 때

모든 프로젝트를 배포해야 하는 것은 아니다. 문법을 익히려고 만든 연습용 스크립트, 계산기 예제, 알고리즘 풀이 같은 것은 배포할 대상이 아니다. 이런 코드를 굳이 서버에 올리는 것은 배우는 것 없이 시간만 쓰는 일이다. 배포가 의미를 갖는 것은 다른 사람이 접속해서 쓸 수 있는 형태일 때다.

시점도 문제다. 기능이 하나도 없는 상태에서 인프라를 먼저 공부하기 시작하면, 도커와 CI 설정에 몇 주를 쓰고 정작 만들려던 것은 시작도 못 하는 경우가 흔하다. 첫 배포는 가장 단순한 방법이면 충분하다. 정적 호스팅이든 관리형 플랫폼이든, 명령 한두 개로 올라가는 쪽을 고르십시오. 직접 서버를 세우고 웹 서버를 설정하는 일은 나중에 필요해졌을 때 배우면 된다.

공개의 대가

배포는 주소가 생긴다는 뜻이고, 주소가 생기면 내가 모르는 요청이 들어옵니다. 디버그 화면, 관리자 경로, 커밋에 남은 키가 그대로 노출됩니다. 올리기 전에 그 세 가지만은 확인하십시오.

배포는 완성의 의식이 아니라, 코드가 실제 환경을 만나는 첫 순간이다.

웹과 데이터

더 볼 것

공개된 뒤에 챙겨야 할 것들은 첫 프로젝트의 보안 기본에 정리해 두었습니다. 요청과 응답이 오가는 구조 자체가 아직 흐릿하다면 웹사이트를 열면 벌어지는 일을 먼저 읽는 편이 순서상 편합니다.

이 글의 포인트

  • 배포를 한 번 해 보면 실행 환경 감각이 크게 좋아진다.
  • 경로, 비밀값, 실행 명령 세 가지가 가장 먼저 깨진다.
  • 배포를 위한 수정이 대개 코드 품질도 함께 올린다.
  • 실패했을 때 볼 곳은 코드가 아니라 로그다.
  • 연습용 스크립트까지 굳이 배포할 필요는 없다.

Next Read

첫 프로젝트에서 꼭 알아야 할 보안 감각

보안은 전문가의 전유물이 아니다. 초보자도 첫 프로젝트에서 반드시 지켜야 할 기본 수칙이 있다.