컨테이너를 개발할 때 기본이 되는 이미지
도커 허브에는 다양한 베이스 이미지들이 등록되어 있다.
컨테이너를 만드는 등 일련의 작업들을 미리 선언함으로써 매번 해당 작업을 하지않고도 컨테이너 생성시 자동으로 등록된 작업이 실행된 후 컨테이너를 생성할 수 있는 파일
메뉴얼 작업을 기록한 Dockerfile 생성 (파일의 이름이 Dockerfile)하여 명령어로 빌드하면 이를 통해 도커 이미지가 생성된다.
예시
FROM alpine:latest # 베이스 이미지
RUN apk update && apk add figlet # 컨테이너에서 실행할 명령어
ADD ./message /message # 컨테이너에 추가할 파일, 현재 디렉토리의 message 파일을 컨테이너의 / 디렉토리에 배치
CMD cat /message | figlet # 컨테이너가 실행 된 후 실행할 명령어
| 명령어 | 설명 |
|---|---|
| COPY [원본][사본] | 컨테이너 내 파일을 컨테이너의 다른 곳에 복사 |
| ENV [변수]=[값] | 환경 변수 설정 |
| EXPOSE [포트] | 공개 포트 설정 |
| WORKDIR [경로] | 컨테이너 내에서 작업 디렉토리 지정, cd 같은 것 |
| MAINTAINER [이름] | 이미지에 대한 작성자 추가 |
여기서 잠깐, CMD와 ENTRYPOINT, ADD 와 COPY는 서로 비슷해 보이는데 차이가 뭘까? (클릭)
docker build --tag [docker ID][이미지이름]:[버전][도커파일 경로]
ex. docker buiild --tage rekv/fistdocerimage:1.0 .
[버전]과 [도커파일] 사이에 띄어쓰기가 잘 안보이므로 주의
docker images
docker run [이미지이름]:[버전]

url:8080/abc/test01로 접속하면 test01이라는 글자가 나오는 백엔드 프로젝트를 생성 후 bootJar 파일 빌드
FROM openjdk:17-ea-slim-buster
EXPOSE 8080
ADD ./build/libs/demo-0.0.1-SNAPSHOT.jar /app.jar
CMD java -jar /app.jar
Dockerfile을 생성하여 위의 스크립트를 작성

docker build --tag [사용자이름]/[이미지 이름]:[버전][Dockerfile 위치]
터미널에서 build 명령어를 이용하여 이미지 빌드

이미지가 생성된 모습

이미지를 컨테이너에서 실행한 다음 /abc/test01로 접속해보면 정상적으로 동작하는 걸 볼 수 있다.
Docker Hub는 Docker에서 관리하는 호스팅된 Docker 레지스트리
도커 허브(클릭)에서는 소프트웨어 공급업체, 오픈 소스 프로젝트 및 커뮤니티에서 제공하는 이미지 외에도 직접 만든 이미지도 등록이 가능하다.

docker push [docker ID]/[이미지 이름]:[버전]
도커 허브에 생성한 이미지를 push하는 명령어 (이미지 build가 선행되어야 한다.)

docker hub에 올라온 모습
백엔드 프로젝트와 프론트엔드 프로젝트를 각각 도커 이미지로 생성한 다음 허브에 업로드하여 도커 컴포즈로 3계층 아키텍처가 실행될 수 있게 설정하기
project-root/
│
├── backend/
│ ├── Dockerfile ✅ 백엔드용
│ └── (소스코드, JAR 등)
│
└── frontend/
│ ├── Dockerfile ✅ 프론트엔드용
│ ├── nginx/default.conf
│ └── (Vue/React 프로젝트, dist 폴더 등)
│
├── docker-compose.yml
참고로 프로젝트는 위의 그림과 같이 구성하는 게 터미널에서 명령어를 입력할 떄 편하다.
FROM nginx:latest
EXPOSE 80
ADD ./frotend/dist /usr/share/nginx/html
ADD ./frotend/nginx/default.conf /etc/nginx/conf.d/default.conf
앞선 docker-compose 실습에서는 베이스 이미지를 이용해 container를 동작시켰으므로 설정 및 배포될 파일을 docker-compose.yaml에서 지정했으나, 이제는 내가 만든 이미지를 등록하여 컨테이너에 올릴 것이므로 필요한 설정을 추가한다.
백엔드도 프론트엔드와 마찬가지로 배포할 빌드 파일을 이미지에 등록한다.
FROM openjdk:17-ea-slim-buster
EXPOSE 8080
ADD ./backend/build/libs/[빌드 파일].jar:/app.jar"
CMD java -jar /app.jar
ENV DB_URL=jdbc:mariadb://db:3306/test
ENV DB_USER=test
ENV DB_PASSWORD=qwer1234
🌟여기서 잠깐, 환경변수(ENV)의 DB_URL을 보면 ip 주소가 아닌 db라고 적혀있다. 이는 docker-compose.yaml에서 함께 작성되어 실행될 db라는 이름의 컨테이너로 알아서 연결이 된다.
도커 컴포즈 정리(클릭)를 참고하여 작성
version: "3"
services:
frontend:
image: [프론트엔드 이미지]:[버전]
ports:
- 80:80
backend:
image: [백엔드 이미지]:[버전]
ports:
- 8080:8080
depends_on:
- db
db:
image: mariadb:latest
ports:
- 3306:3306
volumes:
- ./db:/var/lib/mysql
environment:
- MARIADB_ROOT_PASSWORD=qwer1234
- MARIADB_DATABASE=test
- MARIADB_USER=test
- MARIADB_PASSWORD=qwer1234

그런데 실습을 하는 도중 localhost의 3306포트는 이미 다른 DB 실습 프로그램이 실행되고 있어, 나는 3307 포트로 db를 실행시켰다. 그래서 당연히 백엔드 도커 이미지도 db:3307로 연결해야 한다고 생각하고 3307을 적었는데, 연결이 되지 않았다.
이는 같은 compose 네트워크를 통해 해당 컨테이너에 직접 접근하는 경우이므로, 로컬에서 실행시킨 포트가 아닌 컨테이너 포트를 지정해야하기 떄문이었다.
✅ 정리
| 접속 위치 | DB_URL 값 | 포트 |
|---|---|---|
| 같은 Compose 네트워크의 백엔드 컨테이너 | jdbc:mariadb://db:3306/web | Container Port |
| 외부 서버나 로컬 호스트에서 접속 | jdbc:mariadb://localhost:3307/web | Local Port |
| 외부 네트워크 서버에서 접속 | jdbc:mariadb://<서버IP>:3307/web | Local Port |