글 읽기에 앞서 해당 글을 docker 개념을 어느 정도 안다는 가정하에 작성하였습니다. 혹시 docker 개념에 대해 잘 모르시거나 생소하시면 여기 블로그의 글들(총 3탄)을 꼭 읽어보시기를 강추드립니다!!
Contexts
요점만 말하자면 docker container 간 네트워크 통신을 할 수 있도록 하는게 목표였습니다. 우선 제가 원하는 그림은 다음과 같습니다.
Newman은 API 개발도구 중 하나인 Postman의 command-line API runner입니다. 그리고 Server Container는 dev 환경의 db와 직접 connection 되어 있습니다.
- 웹서버 컨테이너(Server Container) 1대, 이를 테스트 할 Newman 컨테이너(Newman Container) 1대가 동시에 떠있습니다
- 그리고 각각의 컨테이너들은 비록 다른 machine, 환경에 있지만 테스트가 진행할 수 있도록 서로 통신하는데 막힘이 없어야 합니다
- Newman 컨테이너가 API 요청을 보내면 Server 컨테이너는 해당 요청을 받고 응답을 보냅니다
물론 이렇게 구성할 수도 있을 것입니다.
한 Machine 안에 server와 newman을 동시에 넣을 수 있지만, 이는 각각의 컨테이너가 해당 역할에 최적화된 환경에서 깔끔, 간결하게 일을 처리하는 Docker의 장점을 살리지 못하는 것이라고 생각하였습니다.
Solutions
docker-compose 작성
사실 이 방법으로 해결하진 않았습니다. 하지만 많은 글에서 해당 방법을 추천하고 있었습니다. 왜냐하면 기본적으로 docker-compose 내의 각각의 서비스들은 같은 네트워크를 사용하고 있기 때문입니다. 위에서 강추드린 docker 기초 설명 블로그 2탄에서도 wordpress 구성할 때 wordpress의 db 호스트로 db:3306
로 사용된 모습을 볼 수 있는데요. 잠깐 그 코드를 가져와볼게요.
version: '2'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wp_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
wp_data:
(출처: https://subicura.com/2017/01/19/docker-guide-for-beginners-2.html)
db:3306
에서 db는 서비스 이름을 말합니다. wordpress 라는 서비스 위에 db라는 서비스를 이용한 것이며 이게 곧 host로 쓰인 것입니다. 물론 이 기저에 깔린 것은 db와 wordpress라는 서비스는 같은 네트워크에 있다는 가정이겟죠!!
직접 네트워크 생성
이 방법이 제가 택한 방법인데요. 저는 굳이 docker-compose 파일을 만들고 싶지 않았습니다. 그 이유는 사실 네트워크만 엮어주면 또 다른 구성이 별도로 필요하지 않았기 때문입니다. 이 방법은 다음 순서로 만들어질 수 있습니다.
-
우선 도커 네트워크를 만듭니다(참고)
-
각각의 컨테이너 실행시
--network
옵션을 통해 조금 전에 만들어둔 네트워크로 함께 엮습니다 -
API 서버 컨테이너를 먼저 실행시키고 이때
--name
옵션을 통해 해당 컨테이너 이름을 부여합니다 -
Newman 컨테이너는 host를 이전 API 서버 컨테이너에 부여한 이름을 이용합니다
- 예를들어 API 서버 컨테이너 이름이
test-server
이고 포트를 8080 사용하고 있었다면test-server:8080
이라는 곳으로 요청을 보내는 것입니다
- 예를들어 API 서버 컨테이너 이름이
아무래도 코드를 보는게 더 빠르겠죠?
# docker network 생성
docker network create --name internal-container-network
# API 서버 이미지 생성 및 실행(with --name 옵션)
docker build -t test-server .
docker run --rm --network internal-container-network --name test-server -itd -p 8080:8080 test-server
docker pull postman/newman:ubuntu
NEWMAN_COLLECTION_URL="https://www.getpostman.com/collections/token"
# newman 이미지 실행
docker run --rm --network internal-container-network -v "$PWD:/tmp/collection" --entrypoint /bin/bash postman/newman:ubuntu \
-c "npm i -g newman-reporter-html;
newman run ${NEWMAN_COLLECTION_URL} \
-r cli,html --reporter-html-export /tmp/collection/reports/newman-report-internal.html"
# API 서버 중단
docker stop test-server
위 순서 설명과 달리 코드에선 안보이는 부분이 있는데요. API 서버로 요청보낼 때 host 설정하는 부분입니다. 다시 말씀드리면 위 코드에서 API 서버 이름을 --name
옵션으로 test-server, port는 8080로 선언하였습니다. 따라서 test-server:8080
으로 요청을 보내야 같은 네트워크 내에서 원하는 곳으로 요청이 제대로 들어갈 수 있습니다. 혹시 같은 네트워크라 127.0.0.1:8080
으로 보내는 실수는 하지 않으시길 바랍니다.