이전 글 : 24-12-29
개요
요즘 바빠서 잘 수정하지 못한다.
모든 도메인을 분리하여 msa로 만들기 위해, 기존의 배포 방식인 docker compose를 따로따로 분리해줄 필요가 있다.
Issue
1. docker compose 파일 분리
기존의 코드는 아래와 같다.
접기/펼치기
version: "3"
services:
mysql:
container_name: mysql
image: mysql:8.0
ports:
- ${MYSQL_BINDING_PORT}:3306
volumes:
- ${MYSQL_DATA_PATH}:/var/lib/mysql
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USERNAME: ${MYSQL_USERNAME}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
restart: unless-stopped
redis:
container_name: redis
image: redis:6.2.6-alpine
command: redis-server --requirepass ${REDIS_PASSWORD} --port 6379
ports:
- ${REDIS_BINDING_PORT}:6379
restart: unless-stopped
mongodb:
container_name: mongodb
image: mongo
ports:
- ${DANCE_MONGODB_BINDING_PORT}:27017
volumes:
- ${DANCE_MONGODB_DATA_PATH}:/data/db
environment:
MONGO_INITDB_DATABASE: dance
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: ${DANCE_MONGODB_PASSWORD}
DEV_TRIP_MONGODB_BINDING_PORT: ${DANCE_MONGODB_BINDING_PORT}
spring:
container_name: spring
image: dance_spring
ports:
- ${SPRING_BINDING_PORT}:8080
build:
context: .
dockerfile: Dockerfile
depends_on:
- mysql
- redis
volumes:
- /data/spring/vod/:/data/vod/
environment:
MYSQL_BINDING_PORT: ${MYSQL_BINDING_PORT}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USERNAME: ${MYSQL_USERNAME}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
REDIS_BINDING_PORT: ${REDIS_BINDING_PORT}
KAFKA1_BINDING_PORT: ${KAFKA1_BINDING_PORT}
KAFKA2_BINDING_PORT: ${KAFKA2_BINDING_PORT}
KAFKA3_BINDING_PORT: ${KAFKA3_BINDING_PORT}
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
KAKAO_KEY: ${KAKAO_KEY}
KAKAO_REDIRECT_URL: ${KAKAO_REDIRECT_URL}
FFMPEG_LOCATION: ${FFMPEG_LOCATION}
FFPROBE_LOCATION: ${FFPROBE_LOCATION}
REDIS_PASSWORD: ${REDIS_PASSWORD}
DANCE_MONGODB_PASSWORD: ${DANCE_MONGODB_PASSWORD}
DANCE_MONGODB_BINDING_PORT: ${DANCE_MONGODB_BINDING_PORT}
S3_ACCESS_KEY: ${S3_ACCESS_KEY}
S3_SECRET_KEY: ${S3_SECRET_KEY}
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
restart: always
kafka1:
image: confluentinc/cp-kafka:7.6.0
hostname: kafka1
container_name: kafka1
ports:
- ${KAFKA1_BINDING_PORT}:9092
environment:
KAFKA1_BINDING_PORT: ${KAFKA1_BINDING_PORT}
KAFKA_BROKER_ID: 1
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_AUTO_LEADER_REBALANCE_ENABLE: "true"
KAFKA_DELETE_TOPIC_ENABLE: "true"
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 100
CLUSTER_ID: kafka-docker-cluster-1
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true"
KAFKA_MESSAGE_MAX_BYTES: 20971520
kafka2:
image: confluentinc/cp-kafka:7.6.0
hostname: kafka2
container_name: kafka2
ports:
- ${KAFKA2_BINDING_PORT}:9093
environment:
KAFKA2_BINDING_PORT: ${KAFKA2_BINDING_PORT}
KAFKA_BROKER_ID: 2
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_AUTO_LEADER_REBALANCE_ENABLE: "true"
KAFKA_DELETE_TOPIC_ENABLE: "true"
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 100
CLUSTER_ID: kafka-docker-cluster-1
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true"
KAFKA_MESSAGE_MAX_BYTES: 20971520
kafka3:
image: confluentinc/cp-kafka:7.6.0
hostname: kafka3
container_name: kafka3
ports:
- ${KAFKA3_BINDING_PORT}:9094
environment:
KAFKA3_BINDING_PORT: ${KAFKA3_BINDING_PORT}
KAFKA_BROKER_ID: 3
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka3:9092
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_AUTO_LEADER_REBALANCE_ENABLE: "true"
KAFKA_DELETE_TOPIC_ENABLE: "true"
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 100
CLUSTER_ID: kafka-docker-cluster-1
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true"
KAFKA_MESSAGE_MAX_BYTES: 20971520
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
ports:
- ${KAFKA_UI_BINDING_PORT}:8080
depends_on:
- kafka1
- kafka2
- kafka3
environment:
KAFKA_CLUSTERS_0_NAME: kafka-docker-cluster-1
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka1:9092,kafka2:9092,kafka3:9092
이를 서비스마다 나누고, 다른 도커 네트워크 상에 배치되는 것을 막기 위해 host 네트워크를 사용해주었다.
하나의 예시만 들면 충분할 것이라 생각한다.
분리 후 redis 도커 컴포즈 파일
version: "3"
services:
redis:
container_name: redis
image: redis:6.2.6-alpine
command: redis-server --requirepass ${REDIS_PASSWORD} --port 6379
ports:
- ${REDIS_BINDING_PORT}:6379
restart: unless-stopped
networks:
host:
driver: host
external: true
2. 환경 배포 환경 만들기 (jenkins)
젠킨스의 groovy 언어를 아름답게 사용해서, 현재 디렉토리의 모든 yml 파일을 배포하는 코드를 꿈꿨다.
하지만 groovy 내에서 자바 코드를 이용하여 현재 디렉토리의 파일들을 파악할 수 있었는데,
자바 코드를 사용하는 블럭인 script
를 사용하면, 디렉토리 위치가 바뀌어 현재 디렉토리의 파일을 실행하는 과정이 훨씬 어려워졌다.
예전같았으면 머리를 싸매고 고민했을 수도 있을 부분이지만… 빠르게 넘어가기로 했다.
무엇보다, 파일만 추가한다고 배포가 되는 환경이면 이 또한 위험성이 있기 때문이다.
pipeline {
agent any
stages {
stage('Make & Execute Docker Containers') {
steps {
script {
// 대상 파일 이름 리스트
def files = [
"kafka",
"mongodb",
"mysql",
"redis"
]
// compose-files 디렉토리로 이동
dir('../compose-files') {
files.each { file ->
echo "Executing: docker-compose -f ${file}.yml up -d"
sh "docker-compose -f ${file}.yml up -d"
}
}
}
}
}
}
}
이를 배포하였고, 우여곡절이 많았지만, 환경을 따로 배포하는 데 성공했다.
3. 도메인 배정하기
NPM을 이용할 때의 장점은 쉽게 SSL을 설정할 수 있다는 점도 있다.
이 SSL 인증서를 받기 위해서는 제대로 된 도메인이 필요하다.
나는 가비아에서 사서, 내 프로젝트로 연결해 주었다.
아직 서버를 나누어 올리지 않았기에, SSL 등록은 후순위로 미루겠다.
후기
본격적으로 발전시킬 틀이 이제야 왼성이 되고있다는 생각이 든다.
신년을 맞아 약속도 많아지고, 다른 할일도 많다보니 시간이 계속 미뤄지고 있다.
2025년은 모두 이겨낼 수 있는 한 해가 될 수 있기를 바라고, 프로젝트도 원활하게 진행되었으면 좋겠다.