본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

빌드 시크릿 (Build Secrets)

원문 보기 위키 갱신

애플리케이션에 시크릿을 설정할 수 있지만, 이들은 런타임에만 사용할 수 있어요. 조금만 추가 작업을 하지 않으면 Docker 이미지를 빌드할 때는 사용할 수 없어요. 이 페이지에서는 Docker secrets를 이용해 빌드 시간에 시크릿을 사용하는 방법을 설명해요.

출처: 문서

본문

애플리케이션에 시크릿을 설정할 수 있지만, 이 값들은 *실행 시점(run-time)*에만 사용할 수 있어요. 조금만 추가 작업을 하지 않으면 Docker 이미지를 빌드할 때는 사용할 수 없죠.

빌드 시점에 시크릿을 사용할 수 있게 하려면 Docker secrets를 사용할 거예요.

과정은 2단계예요:

  1. Dockerfile에 시크릿 마운트
  2. fly deploy를 실행할 때 그 시크릿의 값 제공

시크릿 마운트하기

RUN 문 안에서 Dockerfile에 시크릿을 마운트해요:

# 참고: 여러 시크릿을 마운트할 수 있어요
RUN --mount=type=secret,id=MY_SUPER_SECRET \
    MY_SUPER_SECRET="$(cat /run/secrets/MY_SUPER_SECRET)" some_command \
    && more_commands_maybe

docker build를 실행하면 새 파일이 생성돼요. 시크릿은 /run/secrets 디렉터리에 저장되어요. 파일 이름은 시크릿을 마운트할 때 전달한 id예요. 그 파일의 내용은 시크릿의 값을 담고 있어요.

시크릿을 두 개 이상 마운트하려면 각각에 대해 --mount 줄을 추가해요:

RUN --mount=type=secret,id=SECRET_ONE \
    --mount=type=secret,id=SECRET_TWO \
    SECRET_ONE="$(cat /run/secrets/SECRET_ONE)" \
    SECRET_TWO="$(cat /run/secrets/SECRET_TWO)" some_command

--mount 지시어는 셸 명령이 아니에요. 그래서 명령을 이어붙일 때 흔히 보던 것처럼 뒤에 &&를 붙일 필요가 없어요.

시크릿 값

fly deploy를 실행할 때 마운트된 시크릿의 값을 제공해야 해요:

fly deploy \
    --build-secret MY_SUPER_SECRET=some_value

시크릿을 두 개 이상 전달하려면 --build-secret 플래그를 반복하세요:

fly deploy \
    --build-secret SECRET_ONE=value_one \
    --build-secret SECRET_TWO=value_two

빌드 시크릿 로컬에서 테스트하기

(Fly.io에 배포하기 전에) 로컬에서 Docker 빌드를 테스트하고 싶다면, 명령은 대략 이렇게 생겼어요:

echo -n "secret_value" > mysecret.txt

docker build --secret id=MY_SUPER_SECRET,src=mysecret.txt .

임시 Machine을 사용해 빌드 시크릿 포함 자동화하기

위 방법은 시크릿 값에 접근할 수 있고 그 값을 명령줄에서 제공할 수 있어야 해요. 이것이 문제가 된다면, fly console 명령으로 임시(ephemeral) Machine을 만들어 배포를 수행하는 방법도 있어요.

그 용도로 사용할 수 있는 Dockerfile 예시:

# syntax = docker/dockerfile:1

FROM flyio/flyctl:latest as flyio
FROM debian:bullseye-slim

RUN apt-get update; apt-get install -y ca-certificates jq

COPY <<"EOF" /srv/deploy.sh
#!/bin/bash
deploy=(flyctl deploy)
touch /srv/.secrets

while read -r secret; do
  echo "export ${secret}=${!secret}" >> /srv/.secrets
  deploy+=(--build-secret "${secret}=${!secret}")
done < <(flyctl secrets list --json | jq -r ".[].name")

deploy+=(--build-secret "ALL_SECRETS=$(base64 --wrap=0 /srv/.secrets)")
${deploy[@]}
EOF

RUN chmod +x /srv/deploy.sh

COPY --from=flyio /flyctl /usr/bin

WORKDIR /build
COPY . .

이 Dockerfile에 담긴 deploy.sh 스크립트는 각 시크릿을 개별적으로 제공할 뿐 아니라, 모든 시크릿을 한 번에 설정하는 스크립트도 함께 묶어줘요. Dockerfile에서 다음과 같이 모든 빌드 시크릿을 한 번에 설정할 수 있어요:

RUN --mount=type=secret,id=ALL_SECRETS \
    eval "$(base64 -d /run/secrets/ALL_SECRETS)" && \
    some_command

빌더 Dockerfile의 이름이 Dockerfile.builder라고 가정하면, 다음 명령으로 임시 Machine을 실행할 수 있어요:

flyctl console --dockerfile Dockerfile.builder -C "/srv/deploy.sh" --env=FLY_API_TOKEN=$(fly auth token)

더 알아보기 (Learn more)