현재 재직중인 회사는 고객사에 솔루션 형태로 서비스를 제공하고있다. 해당 솔루션은 OS 환경에 매우 의존적이라 고객사의 OS 환경을 미리 전달받아 내부에서 런타임 환경을 구성하고 테스트를 진행한 뒤 고객사에 배포를 하고 있다. 그렇기에 Docker를 매우 자주 사용하는데 나를 제외한 다양한 개발자들이 다같이 테스트를 하다보니 Docker Image와 Container가 정리되지 않은 상태로 매우 많이 생성되어 있어 호스트 PC의 리소스도 불필요하게 많이 사용하고 있어서 이번에 정리해보고자 한다.
Podman을 사용하고 안된다면 Docker를 사용할 경우 rootless 모드를 사용빌드용 Docker 이미지와 고객사 테스트용 Docker 이미지를 분리FROM centos:8.4.2105
RUN /usr/bin/sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*
RUN /usr/bin/sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*
# install centos package
RUN yum install -y {packages}
# install CUDA toolkit
...
# user arguments
ARG username
ARG userid
ARG groupname
ARG groupid
# create user with specified uid & gid
RUN groupadd -g $groupid $groupname
RUN useradd -u $userid -g $groupname -m $username -s /bin/bash
RUN usermod -aG wheel $username
RUN echo "$username ALL=NOPASSWD: ALL" > /etc/sudoers.d/$username
# create directories
RUN mkdir /app
RUN chown $username:$groupname -R /app
WORKDIR /app
# add environments
...
USER $username:$groupname
ARG IMAGE_TAG
FROM rockylinux/rockylinux:8.${IMAGE_TAG}-minimal
ADD ./amazon-corretto-8-x64-linux-jdk.tar.gz /usr/lib/jvm/
RUN microdnf install -y glibc-langpack-ko \
&& microdnf clean all
ENV LANG ko_KR.utf8
ENV LC_ALL ko_KR.utf8
# java 환경 설정
ENV JAVA_HOME /usr/lib/jvm/amazon-corretto-8.432.06.1-linux-x64
ENV PATH $PATH:${JAVA_HOME}/bin
ARG WORKDIR=/app
ENV WORKDIR=${WORKDIR}
RUN mkdir -p ${WORKDIR}
WORKDIR ${WORKDIR}
#ARG DEPLOY_DIR=deploy
#COPY ${DEPLOY_DIR}/. ${WORKDIR}/
ARG USE_GPU=false
RUN if [[ "${USE_GPU,,}" == "true" ]]; then \
...
fi
#!/usr/bin/env bash
function check_var() {
if [ -z "$1" ]; then
echo "Not allowed empty input"
exit 1
fi
}
CUR_DIR="$( cd "$( dirname "$0" )" && pwd -P )"
DIR_LIST=($(find "$CUR_DIR" -maxdepth 1 -mindepth 1 -type d -exec basename {} \;))
MESSAGE="Please select build docker type: "
select TYPE_DIR in "${DIR_LIST[@]}"
do
echo "Selected docker type: $TYPE_DIR"
break
done
DIR_LIST=($(find "$CUR_DIR/$TYPE_DIR" -maxdepth 1 -mindepth 1 -type d -exec basename {} \;))
MESSAGE="Please select build docker image: "
select DOCKER_DIR in "${DIR_LIST[@]}"
do
echo "Selected docker: $DOCKER_DIR"
break
done
if [ -z "$DOCKER_DIR" ]; then
echo "Invalid docker image, please retry it"
exit 1
fi
CONFIG_YML_FILE="$TYPE_DIR/config.yml"
# YAML 파일에서 선택한 키($DOCKER_DIR)가 있는지 확인하고 값 가져오기
VALUES=$(awk -v key="$DOCKER_DIR" '
$0 ~ "^" key ":" { flag=1; next }
/^[[:space:]]*-/ && flag { print $2 }
/^[^[:space:]]/ && flag { exit }
' "$CONFIG_YML_FILE")
if [ -n "$VALUES" ]; then
echo "Current support your selected image detail(lower) tag"
echo "$VALUES" | tr '\n' ' '
echo
read -p "Enter the tag of docker image TAG : " IMAGE_TAG
TAG_EXIST=false
if echo "$VALUES" | grep -wq "$IMAGE_TAG"; then
echo "The tag '$IMAGE_TAG' is valid."
TAG_EXIST=true
else
echo "Not supported tag '$IMAGE_TAG'. validating tag."
fi
fi
FULL_IMAGE_NAME="${DOCKER_DIR//_/:}"
if [ -n "$IMAGE_TAG" ]; then
FULL_IMAGE_NAME="$FULL_IMAGE_NAME.$IMAGE_TAG"
fi
echo "Your build docker image name: $FULL_IMAGE_NAME"
# 도커 허브에 이미지가 존재하는지 검증
if ! docker manifest inspect "$FULL_IMAGE_NAME" >/dev/null 2>&1; then
echo "❌ ERROR: Docker Hub에 존재하지 않는 이미지 태그입니다: $FULL_IMAGE_NAME"
exit 1
fi
while true; do
read -p "Do you use it for personal purposes? (y, n)(q: quit task): " use_personal
case $use_personal in
[yY])
FOR_PERSONAL=true
break
;;
[nN])
FOR_PERSONAL=false
break
;;
[qQ])
echo "Canceled docker image creation operation."
exit 1
;;
*)
echo "Invalid input, try again"
;;
esac
done
if $FOR_PERSONAL ; then
USER_NAME=$(id -un)
USER_ID=$(id -u)
GROUP_NAME=$(id -gn)
GROUP_ID=$(id -g)
else
read -p "Enter user name: " USER_NAME
check_var $USER_NAME
read -p "Enter user id: " USER_ID
check_var $USER_ID
read -p "Enter group name: " GROUP_NAME
check_var $GROUP_NAME
read -p "Enter group id: " GROUP_ID
check_var $GROUP_ID
fi
read -p "Enter the tag of docker image name : " IMAGE_NAME
# 생성하려는 이미지 명이 기존에 존재하는지 체크
if docker images --format "{{.Repository}}:{{.Tag}}" | grep -wq "$IMAGE_NAME"; then
echo "The Docker image name you entered already exists: $IMAGE_NAME"
echo "Please try again with another image name"
exit 1
fi
# 이미지 빌드
docker build -t $IMAGE_NAME \
--build-arg USER_NAME=$USER_NAME \
--build-arg USER_ID=$USER_ID \
--build-arg GROUP_NAME=$GROUP_NAME \
--build-arg GROUP_ID=$GROUP_ID \
--build-arg IMAGE_TAG=$IMAGE_TAG \
$TYPE_DIR/$DOCKER_DIR
# 이미지가 정상적으로 생성되었을 경우
# 생성한 이미지의 태그가 기존에 존재하지 않을 경우 추가
if [ $? -eq 0 ]; then
if [ "$TAG_EXIST" = false ]; then
echo "Process completed successfully. Adding new tag: $IMAGE_TAG"
# VALUES에 추가
VALUES="${VALUES} $IMAGE_TAG"
# config.yml 파일 업데이트
TMP_FILE=$(mktemp)
awk -v key="$DOCKER_DIR" -v new_value="$IMAGE_TAG" '
BEGIN {
flag = 0
}
{
if ($0 ~ "^" key ":") {
flag = 1
print $0
next
}
if (flag == 1 && /^[[:space:]]*-/) {
print $0
} else if (flag == 1 && /^[^[:space:]]/) {
print " - " new_value
flag = 0
print $0
} else {
print $0
}
}
' "$CONFIG_YML_FILE" > "$TMP_FILE"
mv "$TMP_FILE" "$CONFIG_YML_FILE"
echo "Updated config.yml with new tag: $IMAGE_TAG"
fi
fi
docker compose를 이용해 테스트 환경을 구성해보도록 해봐야겠다.