💡 CLI가 까다롭다면 가상환경을 vscode에서 원격으로 열어서
그 안에 Docker 확장을 받아 사용합시다!
⚓ Docker 이미지를 빌드하는 데 사용되는 텍스트 파일
이미지를 빌드하는 데 필요한 모든 지침이 포함되어 있음
이 지침에는 기본 이미지, 설치할 소프트웨어, 실행할 명령, 환경 변수 설정 등이 포함
Dockerfile
을 이용하면 애플리케이션을 컨테이너화하고 배포하거나, 개발 환경을 설정하고 공유할 수 있음
또한, CI/CD 파이프라인을 자동화하고 이미지 빌드 및 배포 프로세스를 간소화할 수 있음
🔴 재현성
: Dockerfile을 사용하면 동일한 이미지를 여러 번 빌드할 수 있으며, 매번 동일한 결과를 얻을 수 있음
🔴 자동화
: Dockerfile을 사용하여 이미지 빌드 프로세스를 자동화할 수 있음
🔴 공유
: Dockerfile을 쉽게 공유하여 다른 사람들이 이미지를 빌드하고 사용하게 할 수 있음
🔴 버전 관리
: Dockerfile을 버전 관리 시스템에 저장하여 이미지 빌드 프로세스를 추적하고 변경 사항을 롤백할 수 있음
기본 이미지 지정
FROM <image> [: <tag>]
이미지 빌드 지침
… …
컨테이너 시작시 실행할 명령
CMD ["executeable", "param1", "param2"]
명령어 | 설명 |
---|---|
FROM | 베이스 이미지 지정 (필수) |
RUN | 쉘 명령어 실행 (패키지 설치 등) |
COPY | 호스트 파일/폴더를 이미지에 복사 |
ADD | 파일 복사 (압축 해제 등 추가 기능 포함) |
WORKDIR | 작업 디렉토리 설정 |
ENV | 환경 변수 설정 |
EXPOSE | 컨테이너에서 열 포트 지정 |
CMD | 컨테이너 시작 시 기본으로 실행할 명령어 지정 |
ENTRYPOINT | 컨테이너 시작 시 반드시 실행할 명령어 지정 |
LABEL | 이미지에 메타데이터(key-value) 추가 |
Dockerfile
지시문은 대문자로 작성
각 지시문은 한 줄에 하나씩 작성
#
문자를 사용하여 주석 추가
가능하면 레이어 수를 최소화하여 이미지 크기 최대한 축소
컨텍스트 크기를 최소화하여 빌드 시간 단축
캐시 가능한 레이어를 활용하여 빌드 속도 가속
레이어 수 최소화
가능한 한 명령어를 하나의 RUN 명령으로 결합하여 레이어 수 줄임
&&
연산자를 사용하여 여러 명령어를 하나의 RUN으로 묶음
불필요한 패키지 설치 및 임시
적절한 베이스 이미지 선택
대부분의 경우 Alpine 베이스 이미지 사용 시 이미지 크기를 최소화할 수 있음
특정 용도에 맞는 공식 베이스 이미지 선택 (예: Node.js용 node 이미지)
레이어 캐싱 활용
가능한 한 변경되지 않는 명령어를 Dockerfile의 상단에 배치하여 캐싱 최대화
자주 변경되는 명령어는 Dockerfile 하단에 배치
멀티스테이지 빌드 사용
빌드 단계와 실행 단계를 분리하여 불필요한 의존성 제거
결과물만 최종 이미지에 포함하여 이미지 크기 줄임
환경변수와 ARG
활용
ENV
명령어로 환경변수를 설정하여 Dockerfile을 유연하게 작성
ARG
명령어로 빌드 시간 변수를 설정하여 빌드 과정 최적화
불필요한 패키지 제거
apt-get install --no-install-recommends
옵션을 사용하여 불필요한 패키지 설치 방지
apt-get autoremove
및 rm -rf /var/lib/apt/lists/*
를 사용하여 임시 파일과 패키지 제거
최신 패키지와 업데이트 유지
항상 최신 패키지와 업데이트를 사용하여 보안 취약점 방지
apt-get update 및 apt-get upgrade
등의 명령어 사용
적절한 사용자와 권한 설정
최소 권한의 원칙을 따르고 루트 사용자 대신 비루트 사용자 사용
컨테이너 내부에서 필요한 최소한의 권한만 부여
Dockerignore
파일 사용
.dockerignore
파일을 사용하여 불필요한 파일이나 디렉토리를 제외하여 이미지 크기 최소화도커 이미지 생성시, 여러 단계의 빌드를 사용하여 이미지 크기를 최적화하는 기법
단일 Dockerfile 내에서 여러 FROM
지시문을 사용하여 여러 단계를 정의하고,
각 단계에서 필요한 파일과 의존성만을 포함하여 최종 이미지의 크기를 줄일 수 있음
이를 통해 개발 및 배포 프로세스를 효율적으로 관리할 수 있음
드라이버 | 특징 및 용도 |
---|---|
bridge | 도커의 기본 네트워크 드라이버로, 하나의 호스트 내에서 컨테이너 간 격리된 네트워크 제공. docker0 라는 가상 브리지를 통해 컨테이너 연결. 동일 브리지 네트워크 내에서는 통신 가능하나, 외부와 통신하려면 포트 매핑 필요. |
host | 컨테이너가 호스트의 네트워크 스택을 직접 사용. 격리가 없으며, 컨테이너가 호스트와 동일한 IP와 포트를 사용함. 성능이 중요한 경우에 사용하지만, 포트 충돌 및 보안상 주의 필요. |
none | 컨테이너에 네트워크 인터페이스를 할당하지 않음. 네트워크가 완전히 비활성화된 상태로 외부와의 통신이 필요 없는 특수 목적이나 커스텀 네트워크 드라이버와 함께 사용. |
overlay | 여러 도커 호스트 간 컨테이너 네트워크를 구성할 때 사용. 도커 스웜(Swarm) 등 클러스터 환경에서 컨테이너가 서로 다른 서버에 있어도 하나의 네트워크처럼 통신 가능. |
🖥 도커 네트워크 생성
# 도커 네트워크 생성
docker network create mynetwork
docker network ls
💡
docker network inspect [네트워크명]
으로 ip가 네트워크마다 다름을 확인할 수 있다.
🖥 도커 네트워크 활용 컨테이너 생성
# 네트워크 활용 컨테이너 생성
docker run -d --name mariadb01a \
-e MARIADB_ROOT_PASSWORD=bzeromo \
-e MARIADB_DATABASE=bzeromo \
-e MARIADB_USER=bzeromo \
-e MARIADB_PASSWORD=bzeromo \
--network mynetwork \
-p 4306:3306 mariadb:10.11.11
mariadb -u bzeromo -P 4306 -p bzeromo
🖥 도커 네트워크로 컨테이너끼리 연결
vi ~/vols/tomcat/html/index.jsp
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MariaDB Connection Test</title>
</head>
<body>
<%
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url = "jdbc:mariadb://mariadb01a:3306/bzeromo";
String id = "bzeromo";
String pw = "bzeromo";
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, id, pw);
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT NOW()");
if(rs.next()) {
out.println("DB 접속 성공! 현재 시간: " + rs.getString(1));
}
} catch(Exception e) {
out.println("DB 접속 실패: " + e.getMessage());
} finally {
if(rs != null) try { rs.close(); } catch(Exception e) {}
if(stmt != null) try { stmt.close(); } catch(Exception e) {}
if(conn != null) try { conn.close(); } catch(Exception e) {}
}
%>
</body>
</html>
mkdir -p ~/vols/tomcat/lib
cp ~/dockerfile/tomcat/mariadb*.jar ~/vols/tomcat/lib/
docker run -d --name tomcat01a \
--network mynetwork \
-v ~/vols/tomcat/html:/usr/local/tomcat/webapps/ROOT \
-p 9099:8080 \
tomcat:10.1.41-jdk17-temurin-jammy
docker cp ~/dockerfile/tomcat/mariadb*.jar \
tomcat01a:/usr/local/tomcat/lib/
docker restart tomcat01a
curl localhost:9099