회사에서 사용했던 Dockerfile 정리. 전 개발자가 만든 것과 직접 한 것이 다 포함되어 있음.
계속 일하며 예전에 구성한 Dockerfile에서 문제점과 개선한 점을 여기에 기록하며 남길 예정.
이렇게 모두 Dockerize하면 전부 Kubernetes 위에 띄울 수 있어서 좋음.
Backend
Python
FastAPI
python:3.9-slim으로 python:3.9 대신 쓰면 slim인것처럼 이미지 크기가 매우 작아짐.
slim이라도 apt-get install을 통해 다른것들을 설치해줘야 한다면 결국 크기는 커져서 slim을 안쓰고 기본을 쓰는것도 해보길. (apt-get install 절차가 생략 가능 할 수 있음)
초기 FastAPI 배포 용 Dockerfile
FROM python:3.9-slim AS BUILD_IMAGE RUN mkdir /app WORKDIR /app ENV HOME /app COPY ./ ./ RUN apt-get update RUN apt-get install gcc default-libmysqlclient-dev -y RUN python -m venv venv SHELL ["/bin/bash", "-c"] ENV PATH "/app/venv/bin:$PATH" RUN echo "source /app/venv/bin/activate" >> .bashrc RUN /app/venv/bin/python -m pip install --upgrade pip RUN which python RUN pip install -e . CMD pop runserver
개선하기 → virtualenv folder 복사해서 그것만 사용하기
TODO.
pip install 한 후 uvicorn으로 실행
FROM python:3.10-slim AS BUILD_IMAGE # Setup env ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONFAULTHANDLER 1 #Install RUN mkdir /code WORKDIR /code COPY ./ ./ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt EXPOSE 8080 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
FROM python:3.10 WORKDIR /code COPY ./requirements.txt /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
DRF
위의 FastAPI에서 한 것과 비슷하다. pip install -e . 을 통해 설치하고 그 명령어를 통해 runserver 한다.
FROM python:3.9-slim EXPOSE 8000 RUN mkdir /app WORKDIR /app COPY ./ ./ RUN apt-get update \ && apt-get install gcc default-libmysqlclient-dev -y \ && apt-get install libpq-dev python-dev -y \ && python -m pip install --upgrade pip \ && pip install -e . --use-deprecated=legacy-resolver \ && apt-get purge gcc -y \ && apt-get autoremove -y \ && apt-get clean \ COPY ./app/admin/api ./app/core ./ CMD datepop admin.api runserver
새로운 프로젝트에서는 pip install로 바로 설치하고 gunicorn으로 바로 실행해봤음.
위와 어떤 차이가 있을까..? 위에서는 runserver 했을 때 결국 gunicorn 명령 실행하는 것은 동일함.
FROM python:3.10-slim EXPOSE 8000 COPY ./ ./code WORKDIR /code RUN pip install -r requirements.txt CMD ["gunicorn", "apps.asgi:application", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
Go
Echo
BUILD IMAGE에서 main.go를 빌드하고 빌드한걸 RUNTIME IMAGE에서 실행
################################################################################ # BUILD IMAGE # ################################################################################ FROM golang:1.16-alpine AS BUILD_IMAGE COPY [".", "/opt/source/"] WORKDIR /opt/source RUN apk add --no-cache build-base RUN GOOS=linux GOARCH=amd64 go build -a -ldflags="-w -s" -o /opt/bin/backend cmd/backend/main.go ################################################################################ # RUNTIME IMAGE # ################################################################################ FROM alpine:3.12 COPY --from=BUILD_IMAGE /opt/bin/backend /opt/bin/backend ENTRYPOINT ["/opt/bin/backend"]
FrontEnd
React
Github action에서 npm install을 한 후 docker build를 시킴. 그래서 도커내에서 npm install하는 영역은 없음. build 폴더만 옮긴 후 nginx를 통해 서버에 띄우기.
# nginx 이미지를 사용합니다. 뒤에 tag가 없으면 latest 를 사용합니다. FROM nginx # root 에 app 폴더를 생성 RUN mkdir /app # work dir 고정 WORKDIR /app # work dir 에 build 폴더 생성 /app/build RUN mkdir ./build # host pc의 현재경로의 build 폴더를 workdir 의 build 폴더로 복사 ADD ./build ./build # nginx 의 default.conf 를 삭제 RUN rm /etc/nginx/conf.d/default.conf # host pc 의 nginx.conf 를 아래 경로에 복사 COPY ./nginx.conf /etc/nginx/conf.d # 8080 포트 오픈 EXPOSE 8080 # container 실행 시 자동으로 실행할 command. nginx 시작함 CMD ["nginx", "-g", "daemon off;"]
Next.js
BUILD_IMAGE에서 npm install을 하고 RUNTIME_IMAGE에서는 npm run start 하며 Next.js 실행.
보통 Next.js는 클라우드에서 있는 서비스를 통해 배포 하는것 같은데 도커로 이렇게 배포가 되긴 하는데 이렇게 하는게 맞나?
FROM node:14 AS BUILD_IMAGE COPY [".", "/opt/source/"] WORKDIR /opt/source/ RUN npm install \ && npm run build \ && rm -rf node_modules \ && npm ci --production FROM node:14-slim COPY --from=BUILD_IMAGE /opt/source/package.json /opt/source/ COPY --from=BUILD_IMAGE /opt/source/public /opt/source/public COPY --from=BUILD_IMAGE /opt/source/node_modules /opt/source/node_modules COPY --from=BUILD_IMAGE /opt/source/build /opt/source/build COPY --from=BUILD_IMAGE /opt/source/next.config.js /opt/source/next.config.js ARG IRON_COOKIE_PASSWORD ENV IRON_COOKIE_PASSWORD ${IRON_COOKIE_PASSWORD} WORKDIR /opt/source/ CMD npm run start