빌드 시크릿 (Build Secrets)
애플리케이션에 시크릿을 설정할 수 있지만, 이들은 런타임에만 사용할 수 있어요. 조금만 추가 작업을 하지 않으면 Docker 이미지를 빌드할 때는 사용할 수 없어요. 이 페이지에서는 Docker secrets를 이용해 빌드 시간에 시크릿을 사용하는 방법을 설명해요.
출처: 문서
본문
애플리케이션에 시크릿을 설정할 수 있지만, 이 값들은 *실행 시점(run-time)*에만 사용할 수 있어요. 조금만 추가 작업을 하지 않으면 Docker 이미지를 빌드할 때는 사용할 수 없죠.
빌드 시점에 시크릿을 사용할 수 있게 하려면 Docker secrets를 사용할 거예요.
과정은 2단계예요:
Dockerfile에 시크릿 마운트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)