Backend는 Django를 쓰고 Dockerfile은 아래와 같다.
FROM python:3.8
WORKDIR /app
RUN pip install --upgrade pip
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
RUN chmod +x /app/entrypoint.sh
EXPOSE 8000
ENTRYPOINT ["/app/entrypoint.sh"]
문제
위의 도커파일을 기반으로 컨테이너를 만들었는데
$ docker run --name backend -p 8000:8000 --network net_v1 -v log:/app/log --rm backend
exec /app/entrypoint.sh: no such file or directory
exec /app/entrypoint.sh: no such file or directory 라는 에러와 함께 build가 중단되었다.
에러가 나는 부분에 집중하기 위해 볼륨 제거하고 에러가 나는 마지막 ENTRYPOINT 줄을 주석 처리하고 다시 build 했다.
FROM python:3.8
WORKDIR /app
RUN pip install --upgrade pip
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
RUN chmod +x /app/entrypoint.sh
EXPOSE 8000
# ENTRYPOINT ["/app/entrypoint.sh"]
그 후 컨테이너에 entrypoint.sh이 잘 COPY 되었는지 확인하기 위해 컨테이너를 생성할 때 -it 옵션으로 계속 컨테이너가 살아있게 한 후 다른 터미널을 열어서 컨테이너에 진입할 수 있게 했다.
docker run --name backend -p 8000:8000 --network net_v1 --rm -it backend
# 다른 터미널
docker exec -it backend /bin/bash
root@d29ac537d90f:/app ls
Dockerfile __pycache__ api entrypoint.sh hxbbq log manage.py requirements.txt
entrypoint.sh이 잘 존재한다.
가능한 원인 및 해결 방법
첫번째: 실행 권한 문제
분명 [8/8] RUN chmod +x /app/entrypoint.sh로 잘 실행되었다. 하지만 확인차원에서 컨테이너에 접근해서 권한을 확인해보자.
$ docker build -t backend .
=> [1/8] FROM docker.io/library/python:3.8@sha256:28e6af3c3bcf09f4a26b49d9bbbf677e234bdc478650 0.0s
=> CACHED [2/8] WORKDIR /app 0.0s
=> CACHED [3/8] RUN pip install --upgrade pip 0.0s
=> CACHED [4/8] COPY requirements.txt requirements.txt 0.0s
=> CACHED [5/8] RUN pip install -r requirements.txt 0.0s
=> [6/8] COPY . . 0.1s
=> [7/8] COPY entrypoint.sh ./ 0.1s
=> [8/8] RUN chmod +x /app/entrypoint.sh
ls -l 명령을 사용하여 실행 권한(rwxr-xr-x)이 있는지 확인하고, 없다면 chmod +x entrypoint.sh 로 권한을 부여한다.
root@3418921566f6:/app# ls -l
total 32
-rwxrwxrwx 1 root root 263 Nov 27 04:38 Dockerfile
drwxrwxrwx 2 root root 4096 Nov 27 01:31 __pycache__
drwxrwxrwx 5 root root 4096 Nov 27 01:31 api
-rwxrwxrwx 1 root root 304 Nov 27 04:29 entrypoint.sh
drwxrwxrwx 3 root root 4096 Nov 27 01:31 hxbbq
drwxrwxrwx 2 root root 4096 Nov 27 01:31 log
-rwxrwxrwx 1 root root 683 Nov 7 08:06 manage.py
-rwxrwxrwx 1 root root 151 Nov 27 01:24 requirements.txt
root@3418921566f6:/app#
실행권한에는 문제가 없는 것을 확인.
두번째: shebang 문제
* shebang은 sharp(#) + bang(!) 합성어 Unix계열 OS(리눅스, Mac)에서 스크립트(bash, python등등) 코드 최상단에서 해당 파일을 해석해줄 인터프리터의 절대경로를 지정한다. 출처: 파이썬 - 기본을 갈고 닦자!
entrypoint.sh에 shebang을 잘 썼는지 확인
#!/bin/bash
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.8/site-packages
python3 manage.py makemigrations
python3 manage.py migrate
세번째: 파일 형식과 줄바꿈
entrypoint.sh 파일이 윈도우에서 작성되었다면 줄바꿈 문자가 CRLF로 되어 있을 수 있다. 리눅스 환경에서는 LF 줄바꿈이 필요하다. 파일을 텍스트 편집기에서 열어서 줄바꿈 형식을 LF로 변경한다.
Visual Studio Code를 사용한 줄바꿈 변경 방법
파일 열기: entrypoint.sh 파일을 Visual Studio Code에서 연다.
우측 하단 확인: Visual Studio Code의 우측 하단에 현재 파일의 줄바꿈 형식과 인코딩이 표시된다.
줄바꿈 형식 변경: "CRLF"를 클릭하고, 나타나는 옵션 중 "LF"를 선택한다. 이렇게 하면 줄바꿈 형식이 LF로 변경된다.
파일 저장: 변경된 줄바꿈 형식으로 파일을 저장한다.
CRLF와 LF
LF (Line Feed)
- 표현: \n
- 사용되는 시스템: Unix 기반 시스템(예: Linux, macOS)
- 동작: LF는 문자열에서 새로운 줄을 시작하도록 지시한다. Unix 기반 시스템에서는 이 단일 문자만으로 줄바꿈을 나타낸다.
CRLF (Carriage Return + Line Feed)
- 표현: \r\n
- 사용되는 시스템: Windows 시스템
- 동작: CRLF는 두 개의 문자로 구성된다. Carriage Return(\\r)은 커서를 줄의 시작으로 옮기고, Line Feed(\\n)는 새로운 줄을 시작한다. Windows에서는 이 두 문자의 조합으로 줄바꿈을 나타낸다.
'practical' 카테고리의 다른 글
Docker 컨테이너 모범사례 (1) | 2023.11.19 |
---|---|
리눅스 chmod 명령어 (0) | 2023.11.06 |