====== Docker Image Build ====== [[:docker|Docker]] Image Build 하기 및 올리기 ===== 주의할 점 ===== * 최종 프로세스실행 사용자를 ''root''로 두지말고 다른 것으로 변경하는 것이 좋다. * 그렇지 않으면 Docker Container의 프로세스가 뚫리면 Host 운영체제의 ''root'' 권한이 뚫리게 된다. * 항상 동일한 ''Dockerfile''에 대해 동일한 build 결과가 나오게 하지 않으면 새로운 버그 등에 직면할 수 있다. * ''FROM''을 명시할 때 ''latest''를 사용하지 말고 특정 버전 번호 태그까지 명시한다. * Timezone 을 명확히 맞춘다. * multi stage build로 최소 용량이 될 수 있게 한다. * 내 경험상 [[linux:alpine|Alpine Linux]] 은 JDK와 각종 문제를 일으켰다. 그냥 [[linux:debian|Debian Linux]], [[linux:rhel|RHEL - RedHat Enterprise Linux and derivations]] 계열의 이미지를 사용하는게 더 잘 작동했다. see [[java:openjdk:docker|OpenJdk Docker]] ===== 한 컨테이너에서 다중 프로세스 실행 ===== * [[https://docs.docker.com/engine/admin/using_supervisord/|Use Supervisor with Docker]] * [[https://blog.codeship.com/using-honcho-create-multi-process-docker-container/|Using Honcho to Create a Multi-Process Docker Container]] ===== 용량 줄이기 ===== * Dockerfile 의 각 ''RUN'' 명령은 그 하나하나가 이미지로 구워지는데, ''RUN'' 명령에서 대용량 데이터를 저장했다가 그 다음 ''RUN'' 명령에서 그 파일을 지우더라도 이미지 용량을 줄어들지 않는다. * 따라서 ''RUN'' 명령 한 줄에 용량을 줄이는 명령까지 죽 나열 해야만 한다. ''yum clean all''(다운로드한 패키지 캐시 삭제) 처럼. RUN yum update -y && \ yum instal .... && \ yum clean all * ''apt-get''은 ''apt-get clean'' * ''apk''는 ''apk cache clean'' 인데, [[linux:alpine|Alpine Linux]] Docker 부모 이미지들은 기본적으로 cache를 비활성화해서 이 명령을 실행하지 않아도 상관없는 듯. 혹은 ''rm -rf /var/cache/apk/*'' ===== 실행 사용자 변경 ===== * 기본적으로 root 사용자로 ENTRYPOINT, CMD 의 명령이 실행되는데 이 경우 보안상 문제가 될 수 있다. Docker 컨테이너가 해킹당하면 ''root'' 권한이 host 까지 권한을 행사할 수도 있음. * 따라서 항상 non-root 권한으로 명령을 실행할 수 있도록 해야 한다. # alpine linux 사용자 추가 RUN adduser -D -h /home/worker worker USER worker ===== COPY와 ADD chown ===== * Docker 17.x 이후부터 ''ADD'', ''COPY''시에 ''chown''지정 가능 COPY --chown=: ===== ENTRYPOINT ===== * run/start 후 docker 컨테이너 내부에서 실행할 스크립트 * [[http://pyrasis.com/book/DockerForTheReallyImpatient/Chapter07/06|PYRASIS.COM: 가장 빨리 만나는 Docker 7장 - 6. ENTRYPOINT]] ===== Timezone 보정 ===== from [[http://serverfault.com/questions/683605/docker-container-time-timezone-will-not-reflect-changes|Docker Container time & timezone (will not reflect changes)]] ENV TZ=Asia/Seoul RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone * ''tzdata'' 패키지 없을 경우 미리 설치할 것. * [[linux:alpine|Alpine Linux]] 도 참조. ===== LANG ===== * **UTF-8**로 인코딩 설정 필요. ENV LANG=ko_KR.UTF-8 ===== JAVA JMX ===== ''JMX_PORT''를 ''...port, ...rmi.port'' 두 군데 지정해주고, ''hostname''에 Host의 IP를 지정해준다. -Dcom.sun.management.jmxremote=true \ -Dcom.sun.management.jmxremote.port=$JMX_PORT \ -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false \ -Djava.rmi.server.hostname=$HOST_IP" docker 실행시 ''JMX_PORT''를 ''-p''로 노출시킨다. ===== Latest 올리기 ===== Local에 있는 빌드에 버전이 있는 tag 와 :latest 태그를 함께 만들고 둘 다 push 하면 된다. tag가 달라도 이미 push 된 데이터가 있으면, 중복 Push하지 않기 때문에 데이터가 중복저장되거나 하지는 않는다. docker build --tag my/name:customversion . docker tag my/name:customversion my/name:customversion docker tag my/name:customversion my/name:latest docker push my/name:customversion dpcler push my/name:latest ===== Multi Stage Build ===== * [[https://docs.docker.com/engine/userguide/eng-image/multistage-build/|Docker Multi Stage Build]] * 소스에서 바이너리를 빌드 한 뒤에 실제로 필요한 바이너리만 최종 Docker 이미지로 만들거나 할 수 있는 방식 ===== 참조 ===== * [[https://www.baeldung.com/ops/dockerfile-git-strategies|Dockerfile Strategies for Git | Baeldung]] * * [[https://dev.to/karanpratapsingh|Top 5 Docker Best Practices - DEV Community]]