채팅 서버 배포 - ECR, MongoBD, Docker, Swagger 이용
1. 개요
채팅 서버 1차적 구현을 완료하고, 배포를 시작하였다.
무중단 배포를 목표로 구현을 하였으며 MongoDB를 이용하기로 생각하였다.
MongoDB를 RDS에서 선택해서 구현할 수 있을 것이라 생각하였지만, 예상과 달리 RDS에는 MongoDB가 없었다.
사실 relation이 아니라서 그것이 맞는 것이기도 하다.
따라서 Docker를 이용해서 container로 MongoDB를 띄우기로 생각하고 구현을 시작하였다.
2. Swagger 적용
프론트엔드분들에게 API에 대한 정보를 보내드리기 위해 Swagger를 이용하였다.
이 분의 블로그를 참고하면서 swagger를 적용하였다.
3. 배포 구현
과거에 작성하였던 아래 글을 확인하면서 다시 구현하였다.
https://potatoscatteringsmile.tistory.com/241
https://potatoscatteringsmile.tistory.com/243
크게 달라진 점이라면, docker-compose.yml을 작성함에 있어서 달라졌다.
4. Mongo Config 작성
MongoConfig에서 local 과 dev에 따라 Uri가 달라져야 했다.
이를 적용하기 위해 아래 annotation을 이용해서 프로퍼티 값을 주입 받았다.
@Value("${mongodb.uri}")
전체적인 코드는 아래와 같다.
@Configuration
public class MongoConfig {
@Value("${mongodb.uri}")
private String mongoUri;
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(MongoClients.create(mongoUri), "aper");
}
}
application-dev.yml은 아래와 같이,
mongodb:
uri: ${dev.mongodb.uri}
application-local.yml은 아래와 같이
mongodb:
uri: ${local.mongodb.uri}
구성을 하고, application-secret.yml에 아래와 같이 명시해 주었다.
dev:
swagger:
path: /swagger
api-docs: /api-docs
match: /**
mongodb:
uri: mongodb://mongo_container:27017/aper
local:
mongodb:
uri: mongodb://localhost:27017
이를 통해 환경에 따라서 다르게 코드가 실행될 수 있도록 하였다.
5. docker-compose.yml 작성
cat docker-compose.yml
version: '3.8'
services:
app:
image: 000000000.dkr.ecr.ap-northeast-2.amazonaws.com/chat-repository:latest
container_name: app_container
ports:
- "8080:8080"
environment:
SPRING_DATA_MONGODB_URI: mongodb://mongo_container:27017/aper
depends_on:
- mongodb
networks:
- aper-network
mongodb:
image: mongo:5.0.9
container_name: mongo_container
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
networks:
- aper-network
volumes:
mongo_data: {}
networks:
aper-network: {}
위와 같이 작성해 주었다.
docker로 application과 mongodb를 띄워줄 것이기 때문에, 이 둘에 대한 명시를 해주었다.
app에서는 ECR - URI를 통해서 이미지를 가지고 오고, app_container라는 이름으로 띄워줬다.
포트는 8080을 이용해 주었다.
environment로 환경변수를 설정해주고, aper-network로 mongodb와 network를 묶어주었다.
mongodb의 경우 이미지 번호를 가져와주고, container이름 작성, 포트 결정을 해주었다.
여기서 volumes는 컨테이너가 삭제되고, 다시 띄워지더라도, 내부 data들을 보존해주는 역할을 한다.
mongo_data라는 이름으로 디렉토리를 생성하고, /data/db의 위치에 값들을 저장해 둔다.
6. 프론트 코드 수정
localhost:8080으로 되어 있던 부분들을 배포한 서버의 주소로 변경해 주었다.
fetch(`http://ec2-44-26-000-9999.ap-northeast-2.compute.amazonaws.com:8080/history?chatRoomId=${roomId}`)
stompClient = new StompJs.Client({
brokerURL: 'ws://ec2-44-26-000-9999.ap-northeast-2.compute.amazonaws.com:8080/ws/aper-chat',
reconnectDelay: 5000,
});
이를 통해서 local에서 접근해 보았다.
CORS 설정을 백엔드에도 해주는 것을 잊지 말아야 한다.
7. 확인
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4870000000 000000000.dkr.ecr.ap-northeast-2.amazonaws.com/chat-repository:latest "java -jar app.jar" 13 hours ago Up 13 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp app_container
78100000000 mongo:5.0.9 "docker-entrypoint.s…" 13 hours ago Up 13 hours 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp mongo_container
sudo docker ps를 통해서 container들이 잘 띄워져 있는 것을 확인할 수 있다.
/var/lib/docker/volumes/docker-compose_mongo_data/_data
위 경로에서, volume 내용을 확인할 수 있다.
mongoClient를 설치하고, 아래 명령어들을 확인해서 mongoDB에 저장되어 있는 채팅들을 확인할 수 있었다.
sudo docker exec -it mongo_container mongo
use database이름
show collections
db.collection이름.find()