Search

[Infra]01.도커 - 애플리케이션 서비스 동작(local) ← 쪼개야할듯

Publish Date
2024/12/02 → 2024/12/06
Tags
Status
Done
1 more property
Context
Table of Content
도커를 통해서 애플리케이션을 동작해보자. 필요한 과정은 다음과 같다:
1.
환경설정: 애플리케이션이 실행되는 데 필요한 기본적인 설정(환경변수, 네트워크 등)을 준비
2.
소스코드 빌드: 애플리케이션을 배포 가능한 형태(정적 파일 또는 실행 가능한 코드)로 컴파일
3.
도커 이미지 빌드: 애플리케이션의 실행 환경을 포함한 도커 이미지를 생성
4.
도커 컴포즈 실행: 여러 컨테이너를 관리하고 의존성을 고려하여 실행한다.
Q&A
소스코드 빌드 과정이 필요한 이유는?
도커 이미지를 빌드하는 이유는?
도커 대신 도커 컴포즈를 사용하는 이유는?

1. 도커 네트워크 생성 및 관리하기

도커 컨테이너 간 통신을 원활히 하기 위해서 같은 네트워크 상에서 동작하도록 설정해야한다. 도커 네트워크를 생성하고 확인하는 과정을 살펴보자. coupon-network 네트워크를 통해 애플리케이션 서비스의 컨테이너들(coupon-mysql, coupon-redis, coupon-api, coupon-consumer, kakaoshop-be, kakaoshop-fe) 사이 통신을 확인해보자.

네트워크 생성

컨테이너들 서로 통신할 수 있는 네트워크를 생성한다.
docker network create [네트워크이름] docker network create coupon-network
Java
복사
Tip: 흔히 실수하기 쉬운 부분이 docker create network ~ 라고 생각이 든다. 이는 네트워크 생서이 아닌 이미지를 생성하려는 명령이다. 도커 네트워크를 생성할 때는 “네트워크를 / 생성하자 /이름은 [네트워크이름] 이다” 라고 순서를 기억하자.

네트워크 생성 확인

생성된 네트워크를 확인하고 네트워크의 상세 정보를 조회한다.
docker network ls docker network inspect [네트워크이름] docker network inspect coupon-network
Java
복사
컨테이너 연결 전 상태
inspect 명령어를 통해 네트워크의 상세정보를 조회하면, Containers 항목에 연결된 컨테이너가 아무것도 없다.
컨테이너 연결 후 상태
컨테이너를 네트워크에 연결하면 해당 네트워크 안에 컨테이너 정보를 확인할 수 있다.

네트워크 삭제

네트워크를 삭제하려면 다음 명령어를 사용한다.
docker network rm [NETWORK ID 혹은 이름] docker network rm coupon-network 혹은 docker network rm daaac81c31c8
Java
복사
Note:
네트워크에 연결된 컨테이너를 먼저 분리해야 네트워크 삭제 가능
네트워크 ID를 입력할 때 앞 3-4자리만 입력해도 된다. (예: docekr network rm daaa)

2. coupon-DB

쿠폰 서비스를 위한 데이터베이스를 도커 환경에서 설정하고 초기화하는 방법을 진행한다. 스키마와 초기 데이터를 준비하고 이를 컨테이너 실행 시 자동으로 적용되도록 설정한다.

1)구조 및 환경설정

coupon-project/ ├── coupon-DB/ │ ├── backup │ │ ├── 05-user30000.sql │ │ ├── coupon.sql │ │ └── shop.sql │ ├── init-scripts │ │ ├── 01-schema.sql │ │ ├── 02-user.sql │ │ ├── 03-coupon.sql │ │ └── 04-product.sql │ └── docker-compose.yml // 개별 도커컴포즈
SQL
복사
init-scripts
초기화 SQL 스크립트 저장 디렉토리
01-schema.sql
데이터 베이스 스키마 정의 (8개 테이블 생성)
02-user.sql
기본 사용자 데이터 삽입
03-coupon.sql
쿠폰 데이터 삽입
04-product.sql
제품 및 주문 데이터 삽입
05-user30000.sql
대량 사용자 데이터 삽입 프로지서 (개별적 실행)

2) 도커 컴포즈 실행 및 확인

docker-compose.yml
--- services: coupon-redis: image: redis:7.2-alpine container_name: coupon-redis networks: - coupon-network ports: - 6379:6379 command: redis-server --port 6379 coupon-mysql: image: ubuntu/mysql:edge container_name: coupon-mysql networks: - coupon-network ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORD=1234 - MYSQL_DATABASE=coupon - MYSQL_USER=abcd - MYSQL_PASSWORD=1234 - TZ=UTC volumes: - ./init-scripts:/docker-entrypoint-initdb.d # 디렉토리의 모든 스크립트 매핑 command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --explicit_defaults_for_timestamp=1 networks: coupon-network: name: coupon-network # 명시적으로 네트워크 이름 설정 external: true # Compose가 해당 네트워크를 외부 네트워크로 인식하도록 설정
Java
복사
주요설정
networks: 쿠폰 서비스 간 네트워크 통신 설정한다.
ports:
외부에서 접속 가능하게 포트포워딩 설정
외부에서 localhost:3306으로 MySQL에 접근 가능
environment: 환경변수 설정 옵션
MYSQL_ROOT_PASSWORD
(필수)MySQL 루트 사용자 비밀번호 설정. 설정하지 않으면 MySQL 컨테이너는 실행되지 않는다.
MYSQL_DATABASE
초기화 시 생성할 데이터베이스 이름 지정
MYSQL_USER
생성 할 MySQL 사용자 이름을 설정
MYSQL_PASSWORD
위에 지정한 사용자의 비밀번호를 설정
TZ(TimeZone)
컨테이너 타임존 설정. 설정하지 않으면 컨테이너의 기본 시간대 UTC로 설정된다.
volumes:
도커 볼륨이란 데이터를 저장하고 공유하기 위한 스토리지이다.
호스트(내컴)의 init-script/ 디렉토리에 있는 SQL 파일들을 컨테이너의 docker-entrypoint-initdb.d디렉토리에 매핑한다.
이로 인해 컨테이너가 시작될 때 해당 SQL 파일들이 자동으로 실행된다.
// 이부분 그림 추가하면 좀 더 설명하기 쉬울듯 TODO
command: MySQL 기본 문자셋 설정, 데이터 중에 한글 인코딩이 필요하기때문에 지정함 99_[ISSUE]DB - 한글 인코딩 (해결완료)✅

컨테이너 실행

docker-compose up -d docker ps -a
Java
복사

컨테이너 실행 확인

MySQL

확인방법1: 컨테이너 내부
> docker logs coupon-mysql > docker exec -it coupon-mysql /bin/bash # mysql -u abcd -p Enter password: 1234 mysql> show databases; mysql> use coupon; mysql> show tables;
Java
복사
쿠폰서비스 테이블 : 2개
카카오쇼핑 적용 후 테이블 : 총8개
Tip: MySQL 원격접속 명령어 사용하기
mysql -h <호스트명> -P <포트번호> -u <사용자명> -p mysql -h coupon-mysql -P 3306 -u abcd -p
SQL
복사
-h: 접속할 MySQL서버의 호스트명 또는 IP주소를 지정
IP주소: 192.168.x.x
호스트명: example.com, localhost, 컨테이너이름
확인방법2: DBMS 도구로 연결
DB관리도구 (예: DBeaver, DataGrip)에서 MySQL 서버에 연결하여 확인한다.
Host
- localhost - url or IP - coupon-mysql 컨테이너이름) 환경, 상황 별로 다르니 확인
Port
3306
User
abcd
Password
1234

Redis

확인방법 1: 컨테이너 내부
❯ docker exec -it coupon-redis redis-cli -p 6379 127.0.0.1:6379> ping PONG 127.0.0.1:6379> set a 1 127.0.0.1:6379> get a "1"
Java
복사
확인방법2: DBMS 도구로 연결
DB관리도구 (예: DBeaver, DataGrip)에서 Redis 서버에 연결하여 확인한다.
Host
- localhost - url or IP - coupon-redis (컨테이너이름) 환경, 상황 별로 다르니 확인
Port
6379

3. Coupon-BE  

1)구조 및 환경설정

coupon-project/ ├── coupon-BE/ │ ├── coupon-api/ │ │ └── src/main/resource/ │ │ └── applicaion-docker.yml │ ├── coupon-consumer/ │ │ └── src/main/resource/ │ │ └── applicaion-docker.yml │ ├── coupon-core/ │ │ └── src/main/resource/ │ │ └── applicaion-docker.yml │ ├── Dockerfile-couponAPI │ ├── Dockerfile-couponConsumer │ └── docker-compose.yml // 개별 도커컴포즈
SQL
복사

환경설정

coupon-core / application-docker.yml
coupon-api / application-docker.yml ← CHECK
coupon-consumer / applicaion-docker.yml ← CHECK

특징 설명

1.
프로파일 기반 설정 활성화
on-profile: docker 설정을 통해 도커 환경에서만 적용되는 설정을 활성화한다.
2.
MySQL과 Redis 컨테이너 이름 참조
컨테이너 이름(coupon-mysql, coupon-redis)을 참조하여 도커 내에서 통신 가능하다.
이는 같은 네트워크에 연결된 컨테이너들 간의 통신에서만 유효하다.
Q&A
Q. 컨테이너 이름 참조 시, 외부 접속은 불가한가요?
Q. coupon-core에서 공통 설정을 정의하면, coupon-api와 coupon-consumer에서 DB 환경설정을 생략할 수 있나요?
Q. 환경설정 시 profile 설정하면, applicaion.yml 없어도 되나요?

2)도커 이미지 생성 및 빌드

(1) 소스코드 빌드하기

(2)도커 이미지 빌드하기

3)도커 컴포즈 실행 및 확인

docker-compose.yml
--- services: coupon-api: image: coupon-api:latest build: context: . dockerfile: ./Dockerfile-couponAPI container_name: coupon-api networks: - coupon-network ports: - "8081:8081" environment: - SPRING_PROFILES_ACTIVE=docker - SPRING_DATASOURCE_URL=jdbc:mysql://coupon-mysql:3306/coupon - SPRING_DATASOURCE_USERNAME=abcd - SPRING_DATASOURCE_PASSWORD=1234 - SPRING_DATA_REDIS_HOST=coupon-redis - SPRING_DATA_REDIS_PORT=6379 coupon-consumer: image: coupon-consumer:latest build: context: . dockerfile: ./Dockerfile-couponConsumer container_name: coupon-consumer networks: - coupon-network ports: - "8082:8082" environment: - SPRING_PROFILES_ACTIVE=docker - SPRING_DATASOURCE_URL=jdbc:mysql://coupon-mysql:3306/coupon - SPRING_DATASOURCE_USERNAME=abcd - SPRING_DATASOURCE_PASSWORD=1234 - SPRING_DATA_REDIS_HOST=coupon-redis - SPRING_DATA_REDIS_PORT=6379 networks: coupon-network: name: coupon-network # 명시적으로 네트워크 이름 설정 external: true # Compose가 해당 네트워크를 외부 네트워크로 인식하도록 설정
Java
복사
실행 및 확인
docker-compose up -d --build docker ps -a
Java
복사

4. kakaoshop-BE

1)구조 및 환경설정

coupon-project/ ├── kakaoshop-BE/ │ │ └── src/main/resource/ │ │ └── applicaion-docker.yml │ ├── docker-compose.yml // 개별 도커컴포즈 │ └── Dockerfile
SQL
복사

환경설정

applicaion-docker.yml

2)도커 이미지 생성 및 빌드

(1) 소스코드 빌드하기

(2) 도커 이미지 빌드하기

3)도커 컴포즈 실행 및 확인

docker-compose.yml
--- services: kakao-be: image: kakao-be:latest build: context: . dockerfile: ./Dockerfile container_name: kakao-be networks: - coupon-network ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=docker - SPRING_DATASOURCE_URL=jdbc:mysql://coupon-mysql:3306/coupon - SPRING_DATASOURCE_USERNAME=abcd - SPRING_DATASOURCE_PASSWORD=1234 networks: coupon-network: name: coupon-network # 명시적으로 네트워크 이름 설정 external: true # Compose가 해당 네트워크를 외부 네트워크로 인식하도록 설정
Java
복사
실행 및 확인
docker-compose up -d --build docker ps -a
Java
복사

5. kakaoshop-FE

1)구조 및 환경설정

├── kakaoshop-FE/ │ ├── .env # 환경변수 파일 │ ├── package.json # 프로젝트 의존성 및 스크립트 관리 │ ├── default.conf # Nginx 설정 파일 │ ├── docker-compose.yml # 도커 컴포즈 파일 │ └── Dockerfile # 도커 빌드 및 실행을 위한 설정
SQL
복사

환결설정

.env
.env파일은 환경 변수를 정의하여 애플리케이션에서 사용할 API URL 등을 설정
# env.docker REACT_APP_SHOP_API_URL=http://kakao-be:8080 REACT_APP_COUPON_API_URL=http://coupon-api:8081
Java
복사
설명
REACT_APP_SHOP_API_URL:
쇼핑몰 백엔드 API의 URL 설정
kakao-be는 도커 네트워크에서 쇼핑몰 백엔드 컨테이너 이름
REACT_APP_COUPON_API_URL:
쿠폰 API의 URL 설정
coupon-api는 도커 네트워크에서 쿠폰 API 컨테이너 이름
환경변수 적용 시 주의사항으로 리액트 환경 변수 규칙으로 “REACT_APP_”으로 시작해야 적용된다.

2)도커 이미지 생성 및 빌드

1.소스코드 빌드하기

2.도커 이미지 빌드하기

3)도커 컴포즈 실행 및 확인

docker-compose.yml
--- services: kakao-fe: image: kakao-fe:latest build: context: . dockerfile: ./Dockerfile container_name: kakao-fe networks: - coupon-network ports: - "80:80" environment: REACT_APP_SHOP_API_URL: http://kakao-be:8080 REACT_APP_COUPON_API_URL: http://coupon-api:8081 networks: coupon-network: name: coupon-network # 명시적으로 네트워크 이름 설정 external: true # Compose가 해당 네트워크를 외부 네트워크로 인식하도록 설정
SQL
복사
설명:
서비스 정의:
image: kakao-fe:latest: kakao-fe라는 이름의 도커 이미지를 사용하며, latest 태그를 참조한다.
build: context와 dockerfile을 지정해 Dockerfile을 기반으로 이미지를 빌드한다.
container_name: kakao-fe: 생성된 컨테이너의 이름을 kakao-fe로 명시적으로 설정한다.
networks: coupon-network 네트워크를 사용하여 다른 컨테이너와 통신한다.
ports: 80:80은 호스트의 80번 포트를 컨테이너의 80번 포트에 매핑해 외부 HTTP 요청을 받을 수 있도록 한다.
environment: 환경변수를 설정하여 React 애플리케이션이 실행 시 API URL을 올바르게 인식하도록 한다.
네트워크 정의:
name: coupon-network: 네트워크의 이름을 명시적으로 설정해 관리 용이성을 높인다.
external: true: 이 네트워크가 이미 외부에서 생성된 네트워크임을 명시한다. 이를 통해 다른 도커 컨테이너와 통신할 수 있다.
실행 및 확인
docker-compose up -d --build docker ps -a
Java
복사

6. 프로젝트 전체 APP 구조

1)구조

2)도커 컴포즈

결론

서비스 잘 동작한다.
페이지 접근 및 기능 확인
포스트 맨 요청 확인
coupon-mysql 초기 실행 시 테이블 및 데이터 생성 확인
-- 테이블 및 데이터 생성 확인 use coupon; SELECT (SELECT COUNT(*) FROM cart_tb) AS cart_tb, (SELECT COUNT(*) FROM coupon_issues) AS coupon_issues, (SELECT COUNT(*) FROM coupons) AS coupons, (SELECT COUNT(*) FROM item_tb) AS item_tb, (SELECT COUNT(*) FROM option_tb) AS option_tb, (SELECT COUNT(*) FROM order_tb) AS order_tb, (SELECT COUNT(*) FROM product_tb) AS product_tb, (SELECT COUNT(*) FROM user_tb) AS user_tb, (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'coupon') AS total_tables;
SQL
복사
도커 프로세스, 로그 확인
coupon-mysql
coupon-redis
coupon-api
coupon-consumer
kakaoshop-be
kakaoshop-fe
Search
Main PageCategoryTagskkogggokkAbout MeContact