Nginx컨테이너와 API서버 컨테이너를 통신하기 위해 도커의 네트워크 개념을 알아야 한다.

 

도커 네트워크를 확인해보자

docker network ls

도커가 자동으로 생성한 bridge, host, none 네트워크를 확인 할 수 있다.

 

 

도커 컨테이너를 생성 할 때 network옵션을 주지 않으면 기본 bridge에 연결된다.

bridge들은 16 bit prefix를 가진 서브넷 ip를 쓰게 되며, 

같은 bridge 내 컨테이너들은 서로 컨테이너 명으로 통신 할 수 있다.

 

도커 기본 bridge는 모든 컨테이너가 생성될 때 기본적으로 연결되는 network이므로 새로 bridge를 만들어 쓰도록 하자.

docker network create {your_network}

docker network create 명령어로 새로운 bridge를 생성한다.

 

구동중인 컨테이너를 방금 만든 bridge에 연결하자

docker network connect {your_bridge} {your_container_id}

도커를 처음 만들 때 커스텀 브릿지에 연결할 수도 있다.

docker run --netowrk {your_bridge} {docker_image}

또는 docker-compose에 컨테이너별 networks 항목에 명시해주면 된다.

 

 

이제 nginx 컨테이너의 설정파일을 수정해줘야한다.

nginx.conf의 기본 경로는 /etc/nginx/nginx.conf 이다. (다를 수도 있다.)

cat으로 내용을 띄워보면 하단 http 블럭에 'include /etc/nginx/conf.d/*.conf' 라고 씌여있는 걸 볼 수 있다.

nginx.conf 파일을 직접 수정해주어도 되고, 해당 경로의 파일을 수정해도 되고, {your_file}.conf를 해당 경로에 생성해도 된다.

아무튼 http 블럭에 아래 내용을 추가한다.

upstream {your_resolver_name} {
	server {your_API_container_id}:{PORT};
}

server {
    location /api {
    	proxy_pass http://{your_resolver_name}$request_uri
    }
}

nginx가 reverse proxy의 역할을 수행하여 '~/api'로 요청된 요청을 upstream에 명시된 서버로 전달한다.

API서버와는 같은 docker network bridge에 있기 때문에 컨테이너 ID를 ip대신 명시 할 수 있다.

 

그림으로는 위와 같이 구성 할 수 있다.

외부에서 서버로 온 요청은 Docker의 network를 통해 nginx컨테이너로 전달된다.

nginx 컨테이너를 생성할 때 외부에 노출할 port를 80번으로 했기 때문에 80포트로 들어온 요청이 Nginx로 들어오게 된다.

그리고 nginx는 그 중에서도 ~/api uri로 들어온 요청을 API서버로 전달하게 된다.

즉, API 컨테이너는 외부로 노출되는 포트가 없음에도 Nginx의 Reverse Proxy를 통해 client에게 응답해줄 수 있게 된다.

 

 

728x90
반응형

git repository에 있는 react project를 Jenkins를 사용해

 

자동으로 개발서버에 빌드 및 도커 컨테이너로 배포하려 한다.

 

젠킨스 > Jenkins 관리 > 플러그인 관리

docker를 사용하여 컨테이너를 띄울 예정이니 docker 관련 플러그인을 설치해주자.

 

Jenkins에서 파이프라인을 만들어보자

Jenkins > 새로운 Item

새로운 Item을 생성한다.

 

Jenkins > 새로운 Item

'Pipeline', 배관 아이템을 선택한다. 아이템 이름은 필수값이다.

 

Jenkins > 새로운 Item > Pipeline

SCM을 Git으로 선택 후, GitHub의 Repository를 선택해준다.

Credentials에서는 여기서 생성한 Credential을 넣으면 된다.

 

Branches to build에는 master브랜치를 입력해준다.

개발 branch를 따로 지정해주고 싶다면 그렇게 해도 된다.

 

Script Path에는 레파지토리에 사전 작성할 파이프라인 스크립트의 파일명을 입력해주면 된다.

그리고 레파지토리에 Script Path에 해당하는 경로에 Script파일을 작성하면 된다.

나는 다음과 같이 작성했다.

pipeline {
    agent none
    //기본적으로 체크아웃을 하지 않는 옵션
    options { skipDefaultCheckout(true) }
    stages {
        stage('Checkout repository') {
            agent any
            steps {
                checkout scm
            }
        }
        stage('Build') {
            agent {
                docker {
                    image 'node:14.15.2-alpine'
                }
            }
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
        stage('Docker build') {
            agent any
            steps {
                sh 'docker build -t {image_name}:latest .'
            }
        }
        stage('Docker run') {
            agent any
            steps {
                sh 'docker ps -f name=raor_dev -q | xargs --no-run-if-empty docker container stop'
                sh 'docker container ls -a -fname=raor_dev -q | xargs -r docker container rm'
                sh 'docker images --no-trunc --all --quiet --filter="dangling=true" | xargs --no-run-if-empty docker rmi'
                sh 'docker run -d --name {container_name} -p 80:80 {image_name}:latest'
            }
        }
    }
}

Checkout repository에서 레파지토리 내용을 checkout받고 

Build에서 node를 docker agent로 실행해 소스를 build한다.

Docker build에서 도커 이미지를 빌드하고

Docker run에서 기존 컨테이너와 이미지를 지우고 새로운 컨테이너를 실행한다.

 

도커 build stage에서 사용할 Dockerfile은 다음과 같이 작성했다.

FROM nginx:latest
VOLUME /raor_dev_volume
RUN rm -rf /etc/nginx/conf.d/default.conf
ADD ./nginx/default.conf /etc/nginx/conf.d/default.conf
ADD ./build /usr/share/nginx/html

혹시 nginx 컨테이너와 파일 교환이 필요할 때 사용할 volume을 마운트해주고

build stage에서 빌드해놓은 ./build 디렉토리를 컨테이너의 nginx/html로 복사해주면 된다.

 

nginx의 기본 설정 파일의 경로는 /etc/nginx/conf.d/default.conf 이며

레파지토리에 nginx의 설정 파일을 작성해놓고 사용하려 한다. 기존 이미지에 있는 conf 파일은 삭제해준다.

사용자에게 api서버를 노출하지 않고 nginx가 제공하는 reverse proxy를 사용하려면 필수이다.

 

물론 nginx 컨테이너를 사용하지 않고 node 컨테이너를 사용하여 npm serve를 사용해 빌드된 리액트 애플리케이션을 실행 할 수 있다.

위와 같은 방법은 최신버전에서 보안도 많이 개선되었다고 한다. 하지만 nginx는 잘 알려진 훌륭한 웹서버이며 node컨테이너를 웹서버화하여 이미지로 만들어야 하는 번거로움도 없다.

 

이제 젠킨스에서 PIPELINE 실행을 통해 GitHub 레파지토리의 파일을 체크아웃받아 node로 빌드를 하고 nginx 이미지를 통해 빌드된 React application을 웹서버 컨테이너로 실행 할 수 있다.

 

 

 

작성 참조 링크

www.jenkins.io/doc/tutorials/build-a-node-js-and-react-app-with-npm/

twofootdog.github.io/Docker-Docker%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A1%9C-jenkins-%EC%8B%A4%ED%96%89-%ED%9B%84-%EC%86%8C%EC%8A%A4-push-%EC%8B%9C-%EC%9E%90%EB%8F%99-%EB%B9%8C%EB%93%9C%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0(Springboot)/

728x90
반응형

+ Recent posts