단순 한두개 파일로 스크립트를 실행하는 경우라면 굳이 몰라도 되지만, 대규모 프로젝트를 실행할 때 우리는 필히 경로 지정에 신경을 써야 한다.
현재 fastapi, celery 기반 웹 API의 프로젝트 구조를 만들고 있다.
이는 필연적으로 대형 프로젝트가 될 수 밖에 없는데, 단순히 파일들이 난잡해지는 것을 떠나 다양한 실행 환경에서의 경로 설정도 꼬여버리기 쉽상이다.
더 좋은 해결 방법이 분명 있겠지만, 삽질한 경험을 기록해두고자 본 포스팅을 작성 한다.
docker_fastapi_celery
├── README.md
├── docker-compose.yml
├── docker_env_down.sh
├── docker_env_up.sh
├── local_uvicorn_run.sh
└── src
├── DockerfileCelery
├── DockerfileWebApi
├── app
│ ├── __init__.py
│ ├── controllers
│ ├── core
│ ├── crud
│ ├── db
│ ├── env
│ ├── main.py
│ ├── models
│ ├── schemas
│ └── worker.py
├── celery_job
├── requirements_celery.txt
└── requirements_webapi.txt
아직 파일들이 다 담기지 않았지만, 지금까지 만들어놓은 프로젝트 템플릿은 위와 같다.
리드미 (README.md)도커 컴포즈 (docker-compose.yml)도커 기반 환경 실행 및 종료 셸 스크립트 (docker_env_up/down.sh)로컬에서 uvicorn 기반 디버깅 환경 실행 셸 스크립트 (local_uvicorn_run.sh)Celery 관련 설정이 담긴 Dockerfile (DockerfileCelery)fastapi 관련 설정이 담긴 Dockerfile (DockerfileWebApi)각종 비즈니스 로직 및 db 세션 관련 파일/디렉토리 들 (app)셀러리 잡 관련 디렉토리 (celery_job)celery 및 rest api용 의존성 패키지 (requirements.txt)내 프로젝트의 루트 디렉토리는 docker_fastapi_celery이고, 실제 비즈니스 로직을 담당하는 *.py 파일들은 src 디렉토리 이하에 담겨있다.
즉, 프로젝트의 루트 디렉토리와 파이썬의 소스 디렉토리가 다른 것이다!!
따라서 여기서 일반적인 방법으로 어플리케이션을 실행하면 경로 지정 관련 오류를 마주하게 될 것이다.

docker-fastapi-celery에서 바라볼때 app은 src 디렉토리를 거쳐야 참조할 수 있기 때문에, app 모듈을 임포트 할 수 없다.
main.py를 실행시키면 당연히 실행시킬 main.py 가 없기에 위와 같은 에러가 발생한다. (main.py는, src/app/ 에 위치해있다.)결국 문제는 규모가 큰 프로젝트에서는 "소스코드 뿐만 아니라 셸스크립트나, 리드미 등 프로젝트 전체를 관리해야하는 루트 디렉토리"와 "소스코드 실행이 되는 파이썬의 소스 디렉토리"가 필연적으로 일치할 수 없기 때문에 발생한다.
우리는 이를 맞춰줘야한다.
아래의 과정을 통해 변경해주자.
PyCharm 설정 변경
PyCharm > Preferences > Project > Project Structure에서 Source 디렉토리를 설정할 수 있다. 파이썬 소스코드가 시적되는 기점으로 설정하자.
>>> 이 과정을 통해 PyCharm에서 직접 스크립트를 Run 할때 모듈을 찾지 못햇다는 오류를 피할 수 있다.
각종 실행 스크립트 조정
루트 디렉토리에서 실행할 uvicorn의 cli용 셸 스크립트 파일을 위와 같이 수정했다.
- app 디렉토리 이하의 main.py파일의 app 객체를 reload 조건으로 실행한다.uvicorn app.main:app --reload
- 이때 "소스 디렉토리"는 루트 디렉토리 기준 src 디렉토리 이하로 설정한다 --app-dir src/
- 환경변수 파일은 루트 디렉토리 기준 src>app>env 디렉토리의 local.env를 참조한다 --env-file ./src/app/env/local.env
REST API용 fastapi 프레임워크 컨테이너를 실행하는 Dockerfile은 다음과 같이 작성했다.
- 루트 디렉토리 이하 src 디렉토리는 컨테이너 생성시 루트 디렉토리에 복사해둔다. COPY ./src/app /app
- 이렇게 함으로써 소스코드에서 src 디렉토리를 거치지 않고 app 경로부터 import 하여도 app 모듈을 찾을 수 없다는 에러를 발생시키지 않는다.
로컬에서 uvicorn 을통한 어플리케이션 실행에 문제가 없다.
도커를 통한 실행도 문제가 없다.
PyCharm의 파이썬 소스 디렉토리를 src이하로 지정하였기 때문에, app 디렉토리를 모듈로써 임포트하는 from app import models 구문을 포함한 스크립트도 문제없이 run 할 수 있다.
파이참에서 루트 디렉토리와 파이썬 소스 디렉토리를 분리해, 도커 환경/로컬 환경/스크립트 실행 환경에서 Moduel Import 에러 없이 프로젝트 구조를 다룰 수 있도록 설정해보았다.