這邊說明如何 build docker image 到 ECR 上面,因為 image 上面可能有些敏感資訊不能丟到 public docker hub 上面所以就會使用 --build-arg
的方式把參數的部分帶入到 dockerfile 的變數,並且透過 makefile 的部分把 docker command 的部分串再一起,所以就是透過 makefile 的部分把 argument 的部分一起丟進去 env,然後把 variable 的部分也帶進去
以下是一個簡單的範例來測試 mlflow 的部分,首先是 dockerfile
的部分,可以清楚地看得出來 ENV 的部分則透過 Argument 的部分傳進去
dockerfile 其實就是只專注在 build docker image 的部分,而這邊還是提醒一下 敏感的資訊不要丟到 dockerfile 上面,因為 dockerfile 可能會跟 share to colleague , 因為別人也要相同的環境不然怎麼做事
?
File: dockerfile
FROM python:3.8
LABEL maintainer="birdtasi@gmail.com"
ARG ACCESS_KEY_ID
ARG SECRET_ACCESS_KEY
ARG ML_USER
ARG ML_PASSWORD
ARG ML_ENDPOINT
ARG S3_BUCKET_NAME
ENV AWS_ACCESS_KEY_ID=$ACCESS_KEY_ID
ENV AWS_SECRET_ACCESS_KEY=$SECRET_ACCESS_KEY
ENV DB_USER=$ML_USER
ENV DB_PASSWORD=$ML_PASSWORD
ENV DB_ENDPOINT=$ML_ENDPOINT
ENV DB_NAME=ML_DB
ENV S3_BUCKET_NAME=$S3_BUCKET_NAME
RUN apt-get update -y \
&& apt-get install -y build-essential \
&& apt-get install -y libpq-dev \
&& apt-get install -y supervisor \
&& apt-get install -y awscli
RUN pip install mlflow>=1.0 \
&& pip install boto3 \
&& pip install psycopg2 \
&& pip install cloudpickle
EXPOSE 5000
RUN mkdir -p /app
WORKDIR /app
CMD ["/bin/sh"]
前面就是用 ARG 的部分來接受 command 下的 argument ,然後再帶入到 ENV 設置為環境變數,而當成是需要使用這些變數的時候在使用
File: Makefile
DOCKER_USERNAME ?= hugo
APP_NAME ?= my_app
TAG ?= latest
AWS_ECR_ACCOUNT_ID = XXXXXXXX
AWS_ACCESS_KEY_ID = XXXXXXXXX
AWS_SECRET_ACCESS_KEY = XXXXXXXXX
AWS_ECR_REGION = us-east-2
ML_USER=XXXXXXXXX
ML_PASSWORD=XXXXXXXXX
ML_ENDPOINT=XXXXXXXXX
DOCKER_REGISTRY = ${AWS_ECR_ACCOUNT_ID}.dkr.ecr.${AWS_ECR_REGION}.amazonaws.com
docker/build:
docker build -f dockerfile -t ${APP_NAME}:${TAG} \
--build-arg AWS_KEY_ID=${AWS_ACCESS_KEY_ID} \
--build-arg AWS_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
--build-arg ML_USER=${ML_USER} \
--build-arg ML_PASSWORD=${ML_PASSWORD} \
--build-arg ML_ENDPOINT=${ML_ENDPOINT} \
--build-arg AWS_REGION=${AWS_ECR_REGION} .
docker/tag: docker/build
docker tag ${APP_NAME}:${TAG} $(DOCKER_REGISTRY)/$(APP_NAME):$(TAG)
docker/push: docker/tag
aws ecr get-login-password --region $(AWS_ECR_REGION) | docker login --username AWS --password-stdin $(DOCKER_REGISTRY)
docker push $(DOCKER_REGISTRY)/$(APP_NAME):$(TAG)
docker/vrun:
docker run -it --rm -p 8080:8080 -v ./:. ${APP_NAME}:${TAG} bash
docker/run:
docker run -it --rm -p 8080:8080 ${APP_NAME}:${TAG} bash
前面的部分都是在使用變數的部分可以直接寫在這裡或者寫到其他的資料夾,在用 read 的方式來讀取變數名稱,也可以設定為環境變數。這樣可以減少變數曝光的風險
另外 docker/tag
後面還有一個 docker/build
的部分,這個意思就是 在執行 docker/tag 之前會先執行 docker/build
如果我要把 image build 在 tag 然後 push 到 aws ecr 的時候,透過 makefile 在這個同個資料夾下直接下
make docker/push
依據上面的指令,就可以直接把 image push to aws ecr
另外這邊還有示範在執行docker run 的時候,可以直接用 docker/vrun 就可以順便把資料夾一起 mount 到指定的路徑了,這樣就可以不用打一大串的 commnad