お久しぶりでございます。
今回はdjangoのSECRET_KEYをいかにdockerコンテナ内に公開せずにビルドするか四苦八苦して、どうにか環境変数を載せない方法見つけたので紹介したい。
ただshellのところとか個人的に未熟部分なので、ベストプラクティスあれば教えてちょ。
導入部分
dockerのコンテナ内でENVって使う機会多いと思いますが、
ただこのENV、セキュア的に公開できる情報のみしかdockerfileには保存できないと思うんですね。
#alpine使うことが多い
FROM alpine:3.15
ENV hogehoge=fuga
/ # env
hogehoge=fuga
#貴様みているな!
そのまんま書き込むやつはいねーよとツッコミきそうですが・・・。まぁ、待てや。
ではどうするか
最初思いついたのは、k8sのようにsecretとかないのかなと思ったら、dockerコマンドのsecretが使えるということをここ{:target="_blank"}で詳しく書いていただけていたので、参考にさせていただきました。
準備するのは、dockerfileと.envとshellファイル、できればdocker engineは最新のものにしておいてね?
以下のディレクトリに置いておきました。
- /directory
- .env
- Dockerfile
- build.sh
.env
DJANGO_SECRET_KEY=hogehoge
build.sh
build用のシェル
#!/usr/bin/env bash
cd "$(dirname $0)" || exit
image_name=test/test-django
image_tag=1.0
container_name=test-django
# ここでenvファイルを一時的な環境変数にしている。source .envで動きそうだが、試したらダメだった。
export $(cat .env || grep -v ^# | xargs)
# --secretというのが今回の重要なポイント
docker build . --progress=plain --secret id=django_env,env=DJANGO_SECRET_KEY --ssh default -t ${image_name}:${image_tag} -f directory/Dockerfile
docker tag ${image_name}:${image_tag} ${image_name}:latest
Dockerfile
FROM alpine:3.15
# 省略 django入れて
# このRUNの間DJANGO_SECRET_KEYは使える
RUN --mount=type=secret,id=django_env export DJANGO_SECRET_KEY=$(cat /run/secrets/django_env) \
&& python3 ./manage.py collectstatic --noinput --settings=test-django.settings
一応、このコードでできる、はず。(若干コードを省略しているので、うまくやっていただければ!)
Dockerfileとdockerコマンドでid=django_env が使うところのキーとなっている、そしてrunディレクトリのsecretsの中にdjango_envという一時ファイルが一時的にできるようだ。
(一応、コンテナ内で確認した。)
Dockerfileもそうだが、build.shとかわざわざexportして渡している点お気づきかもしれないが、
もうすこしスマートな書き方あるんじゃない?
安心してください。
私もTOTEMO思っている。
個人的には、export DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY
ぐらいで終わりたかった。
なかなか思った通りにならず何度かやりつつ、今の完成形(私の中での)ができる。
終わりに
ここ一年ISMS、PMS関連でセキュアなことに関わってきたが、こんなにも漏洩リスクや漏洩予防する技術があるんだなとOJTを通して勉強できる現職には感謝している。
ベンチャーでもISMSにちかいシステムを構築しておいてもいいかもね?と日々思います。