제 requirements.txt는 두 줄밖에 없습니다. 이것이 어떻게 모르는 사람들에게 39개의 제품을 판매했는지 알려드립니다.
요약
본 글은 디지털 제품을 여러 스톡 플랫폼에 판매하기 위한 자동화 파이프라인 구축 과정을 설명합니다. 이 시스템은 메타데이터 생성, 중복 게시 방지, PDF 변환 등의 복잡한 작업을 수행하며, 1 vCPU 환경에서도 안정적으로 작동하도록 의존성을 최소화하는 것이 핵심입니다.
핵심 포인트
- 핵심 기능 구현에 필요한 의존성은 Pillow와 reportlab 두 개로 극도로 제한됨.
- 플랫폼별 메타데이터 요구사항(CSV 헤더)이 달라 복잡한 처리가 필요함.
- 중복 게시 방지 및 이미 게시된 기록을 관리하는 원장 역할이 중요함.
- 저사양 환경에서 안정성을 확보하기 위해 의존성 최소화가 필수적임.
제 requirements.txt는 두 줄밖에 없습니다. 이것이 어떻게 모르는 사람들에게 39개의 제품을 판매했는지 알려드립니다.
저는 아직도 업로드 배치(upload batch)가 두 번 실행되던 밤을 기억합니다. Adobe Stock 계정에 경고 표시가 떠 있었고, output_final_v2라는 폴더 안에는 헤더가 일치하지 않는 3개의 CSV 파일이 놓여 있었습니다. 그리고 제가 이미 패키징했지만 게시했다는 것을 증명할 수 없는 39개의 제품들이 있었습니다. 저는 파이프라인(pipeline)을 구축하는 데 2주를 썼지만, 원장(ledger)을 만드는 데는 단 0분도 쓰지 않았습니다. 예술적인 부분은 괜찮았습니다. 하지만 배관(plumbing) 부분이 아니었습니다.
그날 밤의 경험 때문에 제가 결국 출하한 키트의 requirements.txt에는 정확히 두 줄만 들어갔습니다:
Pillow
reportlab
그게 전부입니다. 수십 개의 의존성(dependency)도, 프레임워크도, 클라우드 SDK도 아닙니다. 각각 단 하나의 작업만을 수행하는 두 패키지일 뿐이며, 나머지 모든 것은 표준 라이브러리(standard library) 위에서 작동합니다. 이 제약은 미적인 문제가 아니었습니다. GPU가 없는 1 vCPU, 2 GB 장비에서의 생존 문제였습니다.
문제는 결코 예술이 아니었다
예술을 만드는 것은 재미있는 부분이었습니다. 저를 실제로 지연시킨 네 가지 요소는 지루했습니다:
- 메타데이터(Metadata). Adobe는 5개 열의 CSV를 원하고, Vecteezy는 4개를 원하며, Dreamstime은 15개를 원합니다. 이들 중 어느 곳이든 잘못된 헤더가 있으면 즉시 거부되며, 200개 파일 배치에서 한 번의 거부는 힘든 오후를 만듭니다.
- 중복 게시(Double-posting). 배치를 두 번 실행하는 것은 계정에 경고 표시가 뜨는 가장 빠른 방법입니다. 이것이 제가 저지른 실수였습니다.
- 문서를 제품으로 변환하기. 콘텐츠는 가지고 있습니다. 하지만 누군가 돈을 지불할 만한 것처럼 보이게 만들어야 합니다.
- 패키징(Packaging). 실제 표지가 있는 zip 파일은 팔립니다. 아무것도 없는 파일은 그렇지 않습니다.
그래서 이 키트는 네 가지 스크립트로 구성되었고, 각각은 위에서 언급된 문제점 중 하나를 목표로 했습니다. make_metadata.py는 각 플랫폼이 요구하는 정확한 헤더만 작성하고 그 외에는 아무것도 쓰지 않습니다. upload_tracker.py는 이미 게시한 것을 기억하는 원장 역할을 하여, 재실행 시 절대 중복 게시되지 않게 합니다. md2pdf.py는 마크다운(Markdown) 파일을 제목, 표, 목록 및 링크가 포함된 스타일리시한 PDF로 변환합니다. pack_product.py는 파일들을 zip으로 묶고, 1280×720 커버와 600×600 썸네일을 렌더링합니다.
네 개의 스크립트 중 두 개는 아무것도 설치하지 않습니다. make_metadata.py와 upload_tracker.py는 표준 라이브러리만 사용합니다. 만약 메타데이터(metadata)와 추적(tracking)이 유일한 병목 지점이라면, 심지어 pip를 실행할 필요도 없습니다.
두 개의 의존성(dependencies)은 설계 결정이지 과시가 아니다
Pillow가 표지를 그리고, reportlab이 PDF를 작성합니다. 이것이 전체 의존성 범위(dependency surface)이며, 각 라이브러리가 필수적이기 때문에 존재합니다. 저는 argparse가 작동하기 때문에 CLI 프레임워크를 추가하지 않았습니다. 문자열 포매팅(string formatting)으로 충분하기 때문에 템플릿 엔진도 추가하지 않았습니다. 2GB RAM과 1 vCPU 환경에서는 모든 import가 각 서브프로세스마다 지불해야 하는 세금과 같습니다.
39개 제품과 856MB의 출력을 패키징한 파이프라인은 그 한계 내에서 실행되었습니다. 이 뒤에 있는 상위 프로젝트는 약 19,000줄의 파이프라인 코드와 300페이지 이상의 연구 자료로 구성되어 있으며, 이 모든 것이 같은 작은 장치에서 검증되었습니다. 이러한 크기 중 어느 것도 배포된 키트에는 포함되지 않았습니다. 이 키트는 네 개의 스크립트로 이루어져 있습니다. 연구 결과는 스크립트가 강제하는 규칙이 되었고, 그 규칙이야말로 사용자가 실제로 얻는 혜택입니다.
감자 컴퓨터에서도 작동하게 하는 습관들
1 vCPU와 2GB 환경에서 실제 워크로드를 실행하는 것은 기발한 코드에 관한 것이 아닙니다. 제가 힘든 과정을 거쳐 배워야 했던 몇 가지 습관들에 관한 것입니다:
- 단일 프로세스 처리. 단일 코어에서 이미지 작업을 병렬로 분산 처리하지 마십시오. 더 빨라지지 않습니다. 스와핑만 발생합니다.
- 항목 사이에 메모리 해제. 각 에셋 후에 gc.collect()를 호출하세요.
- 평균이 아닌 최대 RSS 측정. resource.getrusage(RUSAGE_SELF).ru_maxrss가 실제 한계를 알려줍니다. 평균값은 당신을 죽이는 급증(spike)을 숨깁니다.
- 무거운 렌더링 단계의 경우 서브프로세스당 하나의 파일만 사용하십시오. 그래야 메모리가 남아있지 않고 OS로 반환됩니다.
- 필요한 해상도에서 렌더링. 60dpi에서 미리보기를 검사하는 것이, 300dpi로 렌더링하고 왜 장치가 힘들어하는지 의아해하는 것보다 낫습니다.
이 중 어느 것도 특이한 것이 아닙니다. 단지 GPU가 있는 척하는 것을 그만두고 임대한 하나의 코어를 존중하기 시작했을 때 발생하는 일일 뿐입니다.
39개 제품이 잡동사니 서랍(junk drawer)이 되는 것을 막는 폴더 구조
고정된 구조가 없다면 카탈로그는 잡동사니 서랍(junk drawer)으로 변해버립니다. 이 키트는 하나의 구조를 가정합니다:
project/
assets/ 원시 출력물, 에셋당 파일 1개
output/ 제출 준비가 된 파일 + metadata.csv
...
research/ 폴더는 영원히 보존해야 합니다. 스크랩 로그와 메모는 다음 제품을 위한 원자재입니다. 이를 '정리'하기 위해 삭제하는 것이 이 프로젝트가 한 번 저지른 실수이며, 다시는 반복하지 않을 것입니다. 이는 제가 3주 후에 필요했던 폴더를 비우고 난 후 작성한 제 노트에서 직접 인용한 내용입니다.
실제로 39개 제품을 판매하게 만든 것들
스크립트 자체만이 아닙니다. 스크립트는 볼륨(volume)을 가능하게 했을 뿐입니다. 일관된 표지, 정확한 CSV 파일, 그리고 제가 중복 게시하지 않았음을 증명하는 원장 기록 덕분에 12개의 미완성 제품 대신 39개의 완성된 제품을 출하할 수 있었습니다. '낯선 사람들에게' 팔렸다는 부분이 중요합니다. 그 39개 제품 중 어느 것도 저를 아는 사람들에게 간 것이 아닙니다. 그것들은 썸네일을 발견하고, 클릭하여, 포장(packaging)이 제품처럼 보이고 메타데이터가 검열관들을 통과했기 때문에 구매한 사람들에게 갔습니다.
전체 파이프라인은 무료 스택 아래에 자리 잡고 있습니다: 작업을 예약하고 실패를 재시도하는 오케스트레이터(orchestrator), LLM 접근을 위한 로컬 프록시(proxy), 그리고 이 네 가지 스크립트가 제공하는 패키징 계층입니다. 이 키트는 12단계의 설정 가이드 없이 다른 사람에게 건넬 수 있는 부분인데, pip install -r requirements.txt 외에는 설정할 것이 없기 때문입니다.
만약 스크립트 자체를 원한다면, 39개 제품을 패키징하고 단일 코어 2GB 서버에서 실행되었던 바로 그 스크립트를 말합니다. '이렇게 하는 방법'으로 끝나는 튜토리얼이 아닙니다. 규칙까지 작성된 작동하는 도구들입니다.
디지털 자산 공장(digital asset factory) 받기
디지털 제품을 만들고 계신가요? 디지털 제품 판매자를 위한 무료 가이드 및 키트.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기