초고속 빌드를 위한 Dockerfile 만들기

slowwalker2·2020년 5월 23일
0

개요

올해 회사서비스에서 쓰는 웹서버를 죄다 컨테이너화하는 일을 했다. 이건 나중에 포스팅할꺼다. 아무튼, 컨테이너화하는 과정에서 빌드시간이 걸려도 너~~무 걸리는 바람에 시간을 단축해본다고 고생한 일이 있었다. 그걸 좀 써보려 한다.

참고로 우리 서비스는 Ruby on Rails 로 만들어져있다. 이 서비스를 온전히 동작시키려면 필요한 라이브러리를 인스톨해야한다. 그리고 독자적으로 쓰여진 css/javscript를 브라우저가 읽을수 있게 변환하고 또 압축하는 과정을 거치게 된다. 그것이 빌드하는 과정에서 필요한 작업들이다.

빌드 환경

우리회사는 AWS에서 제공하는 서비스를 열라 많이 쓴다. 그래서 빌드환경도 AWS Codebuild 다. 얘는 로컬캐시, 커스텀캐시다 해서 여러 옵션을 제공해주긴하는데 솔직히 제대로 활용할만한게 못되더라.
한마디로 좀 짱났다.

문제점

크게 두가지 문제가 있었다.

  • bundle install 이 열라 느림
  • assets precompile 이 열라 느림

이거는 아무것도 없는 백지상태에서 작업을 하면 어쩔수 없는 것이다. 뭐가 좀 있는 상태에서 하면 변경된 부분만 처리를 하기때문에 효율적이다.
그래서 처음에는 AWS Codebuild 의 캐시기능을 사용해서 해결해보려 했지만 결과적으로 채용할 수 없음 이었다.

  • 도커 레이어캐시
  • 로컬캐시
  • 커스텀캐시

이 얘긴 나중에 자세히 적어보려 한다.

해결방법

Dockerfile, buildspec.yml 을 지지고 볶았다. 포인트는 아래와 같음.

  • 멀티스테이지 빌드
    • 도커 레이어가 무한대로 증식하는걸 방지하기 위함
  • Docker 의 BuildKit 사용하기
    • syntax=docker/dockerfile:experimental
    • buildspec.yml 에 DOCKER_BUILDKIT: "1" 설정을 추가해주쎄용.
    • 미미하지만 체감 가능한 정도의 빌드속도 개선
  • latest한 도커이미지 재활용
    • 캐시용 폴더의 심볼릭링크
      • latest한 도커이미지를 가져오는 단 하나의 이유

조잡하지만 적당히 이런 분위기로 작성했다. 느낌만 보셔요.

# syntax=docker/dockerfile:experimental // <-- 요거 중요
ARG 마지막_빌드_이미지 // <-- 요거 중요
ARG 진짜_베이스_이미지  // <-- 요거 중요

FROM ${마지막_빌드_이미지} AS 빌드 <-- 요거 중요
USER root
WORKDIR 워크디렉토리
RUN mv 워크디렉토리 워크디렉토리_무브 && \  // <-- 요거 중요
 "대충 github credential 보존을 위한 디렉토리 생성하는 커맨드"

COPY . ./

RUN "대충 필요한 폴더들 생성하는 커맨드" && \
  ln -s /.cache cache // <-- 요거 중요

RUN --mount=type=secret,id=github,mode=600,dst=/root/.ssh/id_rsa \
  "대충 번들인스톨하는 커맨드"

FROM ${진짜_베이스_이미지} AS application // <-- 요거 중요

RUN useradd 찐유저
COPY --from=빌드 --chown=찐유저:찐유저 워크디렉토리 워크디렉토리 
COPY --from=빌드 --chown=찐유저:찐유저 /usr/local/bundle/config /usr/local/bundle/config
COPY --from=빌드 --chown=찐유저:찐유저 /.cache /.cache // <-- 요거 중요

USER 찐유저

WORKDIR 워크디렉토리

ARG "대충 필요한 argument"
ARG AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

ENV "대충 필요한 environment"

RUN --mount=type=secret,id=github,mode=600,dst=/root/.ssh/id_rsa \
  "대충 혹시 몰라서 또 한번 번들인스톨하는 커맨드"

RUN "대충 assets 프리컴파일하는 커맨드"

ENTRYPOINT 엔드리포인트

EXPOSE 3000
CMD ["bin/rails", "server"]

assets on S3 사용시 주의점

assets on S3 을 사용중이라면 assets:precompile 시에 s3 에 액세스를 해야하는데, buildspec.yml에서 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 를 넘겨줘야만 액세스가 가능한 부분입니다.
이런 글이 있던데 전 안읽었어요.

결론

11분정도 걸리던 빌드가 3분대로 빨라졌습니당.

profile
띨띨함

0개의 댓글