Docker 를 사용하여 front 팀과 협업하기
운영도 안하는데 돈을 쓰는건 너무 아깝잖아요. docker 를 사용해봅시다.
1. Why Docker? 🐋
front 팀이 저희가 만든 WAS 를 사용할 수 있도록 해야 했습니다. 이를 위해 저에게는 여러 선택지가 있었습니다.
- 안쓰는 노트북을 사용하여 개인 서버를 구축한다.
- Qoddi 를 사용하여 프로젝트를 배포한다.
- AWS 를 사용하여 프로젝트를 배포한다.
- Docker 를 사용하여 front 팀이 이미지를 pull 받게 한다.
이 외에도 여러가지 방법이 있겠지만, 저는 제일 마지막 방법을 선택하기로 했습니다.
그 이유는 아래와 같습니다.
- 1 번의 경우 이전 프로젝트에서 해본적이 있는데, 구축은 어렵지 않으나 속도가 너무 느려서 front 팀이 답답해 했습니다.
- free tier 의 경우 프로젝트와 mysql 을 사용하면 끝이며, redis 를 사용하지 못합니다. Docker 로 프로젝트를 배포하는 것 또한 가능하지만, 비용이 들 가능성이 있습니다.
- 2 번과 같은 맥락으로 개발 초기단계에 서버 비용을 들이고 싶지 않았습니다.
이러한 이유를 종합하여 결국 만든 프로젝트를 image 로 말아 Docker hub 에 올리고, 이를 front 팀이 pull 받아 사용 하는 것으로 하였습니다. 전체 기능이 완성되고, version 을 매길 수 있게 되면 그 때 클라우드 서비스를 이용 해보려 합니다.
2. Dockerfile
Dockerfile 은 프로젝트를 Docker container 로 packaging 하기 위한 내용을 담고 있습니다.
저의 경우는 아래와 같이 작성 하였습니다.

1
2
3
FROM openjdk:17
COPY ./build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
2.1. FROM openjdk:17
- 이 Docker image 는 openjdk 버전 17을 기반으로 한다는 뜻입니다. 따라서 이 image 는 Java 17이 설치된 환경에서 시작됩니다.
- FROM 지시문은 Docker 이미지를 만들기 위한 기반 image 를 지정합니다.
2.2. COPY ./build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar
- 로컬 파일 시스템의 ./build/libs/backend-0.0.1-SNAPSHOT.jar 파일을 Docker image 내의 /app.jar 위치로 복사 한다는 뜻입니다.
- 애플리케이션의 실행 가능한 jar 파일을 container 안으로 가져옵니다.
2.3. ENTRYPOINT [“java”,”-jar”,”/app.jar”]
- ENTRYPOINT 지시문은 container 가 시작될 때 실행될 명령을 정의합니다.
- 여기서는 java -jar /app.jar 명령을 사용하여 /app.jar 파일을 실행합니다.
3. compose.yaml
Docker Compose 를 사용하여 다중 컨테이너 Docker 애플리케이션을 정의하고 관리하기 위한 설정 파일입니다.
저의 경우 mysql, spring app, redis 세개의 컨테이너가 존재합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
version: '3.8'
services:
mysql:
## 도커 허브에서 mysql 의 최신 image 를 사용합니다.
image: mysql:latest
## 재시작 정책입니다.
## mysql 이 실행되기 전, app 이 실행되면 실행오류가 발생합니다.
restart: always
env_file:
## 환경변수가 담겨있는 파일을 지정해줍니다.
docker.env
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
healthcheck:
## 서비스가 제대로 실행했는지 체크합니다.
test: ["CMD", "mysqladmin" ,"ping", "-h", "mysql"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:latest
restart: always
ports:
- "6379:6379"
volumes:
- redis-data:/data
app:
## 사용자 정의 image 를 사용 합니다.
image: sieun96/starbucks-clone-coding:0.0.1
ports:
- "8080:8080"
env_file:
docker.env
depends_on:
## spring app 이 의존하는 서비스를 적어주어야 합니다.
mysql:
condition: service_healthy
redis:
condition: service_started
volumes:
## 데이터를 저장합니다. 재실행해도 초기화 되지 않습니다.
mysql-data:
redis-data:
4. 환경변수 파일 작성
필요한 환경 변수를 key=value
로 작성 해주세요.
MYSQL_ROOT_PASSWORD=""
MYSQL_DATABASE=""
## application.yml 또한 똑같이 바꿔 줘야 합니다.
SPRING_DATASOURCE_URL: "jdbc:mysql://mysql:3306/{스키마명}?useSSL=false&allowPublicKeyRetrieval=true"
SPRING_DATASOURCE_USERNAME: ""
SPRING_DATASOURCE_PASSWORD: ""
SPRING_DATA_REDIS_HOST: "redis"
SPRING_DATA_REDIS_PORT: "6379"
...
5. Docker buildx 를 사용한 Multi-Architecture image build
이 과정은 필요에 의해 밟으면 됩니다. 만약 github actions 를 이용하여 이미지 배포 자동화가 되어있다면 할 필요 없습니다!
제 맥북(m1) 에서 만든 Docker image 를 실행할 때, 실행 하려는 컴퓨터의 하드웨어 아키텍쳐에 따라 실패할 수도, 성공할 수도 있습니다. 왜 그럴까요?
일반적인 방식으로 docker image 를 만들어 허브에 올리면 아래와 같이 나올거에요.

1
docker build -t {이미지 이름}:{태그} .
이를 윈도우 환경에서 pull 받아 실행하면 어떻게 될까요? 당연히 안되겠죠. 때문에 다양한 아키텍쳐를 고려해야 합니다. 프론트 팀원이 어떤 실행 환경을 가지고 있을지 모르니까요.
5.1. Buildx
buildx 를 사용하여 multi-architecture image 를 만들 수 있습니다.
5.1.1. Buildx 설치

1
docker buildx install
5.1.2. Builder 생성

1
docker buildx create --name {builder 이름} --use
5.1.3. Build

1
docker buildx build --platform {플랫폼1, 플랫폼2...} -t {도커허브 repository}:{tag} --push .
아래와 같이 플랫폼을 따로 지정하지 않으면 제 환경에 따른 이미지만 생성됩니다.

1
docker buildx build -t {도커허브 repository}:{tag} --push .
5.2. 결과
저의 경우, 윈도우 버전과 mac(m1) 환경에 맞춘 image 를 push 하였습니다.
6. front team 은 어떻게 사용해야 하나요? 🤔
6.1. Backend 팀에게 파일 받기
- compose.yaml
- 이때 각 환경에 맞는 이미지를 잘 지정해 주어야 합니다.
- 환경변수 (env 파일)
6.2. Docker Desktop 설치, 실행
6.3. Docker image pull
이때 이미지와 backend team 에게 받은 파일은 모두 같은 위치에 있어야 합니다.

1
docker pull {image repository}:{tag}
6.4. compose 파일 실행
- 윈도우의 경우 powershell 에서, 맥의 경우 terminal 에서 수행해주세요.
- compose 파일과 docker.env 파일이 존재하는 directory 에서 수행 해야 합니다.
- 이후에는 docker desktop 에서 수행해도 됩니다.

1
docker compose up
6.5. 결과 화면
성공했을 때 나타나는 문구입니다.
6.5.1. mac
2024-02-15T06:50:50.735673844Z . ____ _ __ _ _
2024-02-15T06:50:50.735682677Z /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2024-02-15T06:50:50.735684052Z ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2024-02-15T06:50:50.735685469Z \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2024-02-15T06:50:50.735686427Z ' |____| .__|_| |_|_| |_\__, | / / / /
2024-02-15T06:50:50.735687302Z =========|_|==============|___/=/_/_/_/
2024-02-15T06:50:50.736824469Z :: Spring Boot :: (v3.2.2)
2024-02-15T06:50:50.736849344Z
2024-02-15T06:50:50.843975094Z 2024-02-15T06:50:50.835Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : Starting BackendApplication v0.0.1-SNAPSHOT using Java 17.0.2 with PID 1 (/app.jar started by root in /)
2024-02-15T06:50:50.844967177Z 2024-02-15T06:50:50.844Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : No active profile set, falling back to 1 default profile: "default"
2024-02-15T06:50:51.751989803Z 2024-02-15T06:50:51.751Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2024-02-15T06:50:51.753829428Z 2024-02-15T06:50:51.753Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-02-15T06:50:52.021237053Z 2024-02-15T06:50:52.020Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 259 ms. Found 1 JPA repository interface.
2024-02-15T06:50:52.043135136Z 2024-02-15T06:50:52.042Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2024-02-15T06:50:52.044310803Z 2024-02 ...
...
2024-02-15T06:50:56.008Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ''
2024-02-15T06:50:56.029493013Z 2024-02-15T06:50:56.029Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : Started BackendApplication in 5.645 seconds (process running for 6.204)
6.5.2. window
[+] Running 20/20
✔ redis 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 27.4s
✔ e1caac4eb9d2 Pull complete 22.6s
✔ 7469c6c5b625 Pull complete 18.8s
✔ a3d1b68c4a62 Pull complete 19.8s
✔ 152cbe749752 Pull complete 20.4s
✔ 7218480dfba1 Pull complete 23.6s
✔ e61c48a0d344 Pull complete 21.5s
✔ 4f4fb700ef54 Pull complete 22.7s
✔ 82adb0efabd8 Pull complete 23.4s
✔ mysql 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 28.7s
✔ 81badc5f380f Pull complete 17.4s
✔ c490e5dd1a9d Pull complete 0.7s
✔ 87aeb61f1478 Pull complete 0.9s
✔ 1cacbea6ceda Pull complete 2.3s
✔ 1e72891ace67 Pull complete 1.8s
✔ 42b720363d36 Pull complete 2.6s
✔ 6b3b50f9990a Pull complete 19.0s
✔ 3811d52cfa61 Pull complete 3.5s
✔ 05bc7a0277d8 Pull complete 18.0s
✔ cc0abd25a274 Pull complete 18.2s
[+] Running 6/5
✔ Network desktop_default Created 0.3s
✔ Volume "desktop_redis-data" Created 0.1s
✔ Volume "desktop_mysql-data" Created 0.0s
✔ Container desktop-redis-1 Created 1.0s
✔ Container desktop-mysql-1 Created 1.0s
✔ Container desktop-app-1 Created
===========
2024-02-15T06:50:50.735673844Z . ____ _ __ _ _
2024-02-15T06:50:50.735682677Z /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2024-02-15T06:50:50.735684052Z ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2024-02-15T06:50:50.735685469Z \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2024-02-15T06:50:50.735686427Z ' |____| .__|_| |_|_| |_\__, | / / / /
2024-02-15T06:50:50.735687302Z =========|_|==============|___/=/_/_/_/
2024-02-15T06:50:50.736824469Z :: Spring Boot :: (v3.2.2)
2024-02-15T06:50:50.736849344Z
2024-02-15T06:50:50.843975094Z 2024-02-15T06:50:50.835Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : Starting BackendApplication v0.0.1-SNAPSHOT using Java 17.0.2 with PID 1 (/app.jar started by root in /)
2024-02-15T06:50:50.844967177Z 2024-02-15T06:50:50.844Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : No active profile set, falling back to 1 default profile: "default"
2024-02-15T06:50:51.751989803Z 2024-02-15T06:50:51.751Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2024-02-15T06:50:51.753829428Z 2024-02-15T06:50:51.753Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-02-15T06:50:52.021237053Z 2024-02-15T06:50:52.020Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 259 ms. Found 1 JPA repository interface.
2024-02-15T06:50:52.043135136Z 2024-02-15T06:50:52.042Z INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2024-02-15T06:50:52.044310803Z 2024-02 ...
...
2024-02-15T06:50:56.008Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ''
2024-02-15T06:50:56.029493013Z 2024-02-15T06:50:56.029Z INFO 1 --- [ main] c.starbucks.backend.BackendApplication : Started BackendApplication in 5.645 seconds (process running for 6.204)
6.5.3. docker desktop
컨테이너가 제대로 실행 된 경우, container 메뉴를 클릭했을 때 아래와 같이 나타납니다.