엔틸롭 캐년에 방문했을때 건조한 사막기후라 비가 잘 오지 않는다 하였지만 럭키비키...? 하게 엔틸롭 캐년을 비를 맞으며 경험할 수 있었다!

엔틸롭 캐년에 가기 위해 베가스에서부터 끝도 없이 달리고 달렸던 사막 도로...!!! 상상도 못할 정도의 거리를 직진만 해야했다

 

 

 

 

 

- TIL -

 

구현 목표)

1. MySQL 컨테이너 정의하기

2. 가비아에서 도메인 구매하여 아이피랑 연결하기

3. Nginx 를 설치하여 저렴한 도메인을 구매한 뒤 도메인과 연결하여 경로를 처리하기

 

 

 

구현 과정)

1. 필요한 포트 정보를 오픈

더보기

1) 8080 포트와 80 포트 3000 포트를 오픈

8080, 80, 3000 포트를 any 로 오픈

 

 

 

2. randomchat 디렉토리(프로젝트 디렉토리 최상위)에 docker-compose.yml 작성

더보기

1) docker-compose.yml 작성

version: "3.8"
services:
  mysql:
    image: mysql:8.0
    container_name: randomchat-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "{자신의 mysql root 비밀번호 설정}"
      MYSQL_DATABASE: "{사용할 데이터베이스 이름 설정}"
      MYSQL_USER: "{사용할 유저 아이디 설정}"
      MYSQL_PASSWORD: "{사용할 유저의 비밀번호 설정}"
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

  spring:
    build:
      context: ./spring
    container_name: randomchat-spring
    restart: always
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://randomchat-mysql:3306/{위의 mysql 에서 정의한 데이터베이스 이름 설정}
      SPRING_DATASOURCE_USERNAME: {위의 mysql 에서 정의한 유저 아이디 입력}
      SPRING_DATASOURCE_PASSWORD: {위의 mysql 에서 정의한 유저 비밀번호 입력}
    ports:
      - "8080:8080"
    depends_on:
      - mysql

  react:
    build:
      context: ./react
    container_name: randomchat-react
    restart: always
    volumes:
      - ./react/build:/usr/share/nginx/html
      # 중요!!!! react 의 빌드파일을 nginx 의 서빙 디렉토리와
      # 맵핑하므로써 80포트로 접속시 리액트 프로젝트가 출력되게 한다!
    ports:
      - "3000:80"

  nginx:
    build:
      context: ./nginx
    container_name: randomchat-nginx
    restart: always
    ports:
      - "80:80"
    depends_on:
      - spring
      - react

volumes:
  mysql_data:

해당 설정을 통해 MySQL 컨테이너를 생성하면서 동시에 Spring 컨테이너와 의존 관계를 생성해주고

Nginx 의 리액트, 스프링 프로젝트의 의존 관계도 설정해준다.

 

 

 

2) randomchat 디렉토리 내부 상태

randomchat 디렉토리 내부 상태

 

 

 

3. 가비아에서 도메인 구매 후 아이피 연결

더보기

1) 가비아에서 도메인 구매

random-chat.site 도메인을 구매

 

2) DNS 설정하기

( 아이피와 도메인을 연결하는 과정 )

배포 서버의 공인 IP 값을 도메인과 연결, www.random-chat.site 로 접근시 api.random-chat.site 로 접근시 동일한 서버 아이피로 전송하게끔 세팅

( 도메인 경로를 나눠놓는 이유는 www 로 오게되면 Nginx 를 통해 React 서버를 호출, api 로 오게되면 Ngingx 를 통해 Spring 서버를 호출하기 위함 )

 

 

 

4. Nginx 설정

더보기

1) Nginx 리버스 프록시 파일 설정

( nginx 디렉토리에 nginx.conf 파일 생성 및 작성 )

worker_processes 1;

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;

        server_name www.random-chat.site;
        location / {
            proxy_pass http://randomchat-react:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

    server {
        listen 80;

        server_name api.random-chat.site;
        location / {
            proxy_pass http://randomchat-spring:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

( 80 포트로 접속 시 접속 도메인 별로 www 로 접속하면 React 프로젝트를 호출, api 로 접속하면 Spring 프로젝트를 호출하게 설정 )

 

 

 

 

2) Dockerfile 파일 생성 및 작성

From nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf

도커의 버전과 설정을 잡아준다.

 

 

 

3) nginx 디렉토리 내부 상태

nginx 디렉토리 내부 상태

 

 

 

5. 빌드 및 테스트

더보기

1) randomchat 디렉토리에서 아래 명령어로 빌드 실행

docker-compose up --build

 

 

 

2) 테스트

www.random-chat.site 로 접속하면 위와 같이 리액트 프로젝트가 잘 출력되는 모습

 

api.random-chat.site 의 하위 경로로 api 요청을 보내도 제대로 응답이 오는 모습이다.

 

 

 

구현 후기)

Spring 프로젝트까지는 제대로 Nginx 를 통해 매핑되어 호출이 이루어졌는데 React 프로젝트가 매핑되지 않아 URL 접속 시 Nginx 의 메인 화면이 계속

출력되는 상황이 발생하였다.

 

이는 docker-compose.yml 의 React 프로젝트의 볼륨을 Nginx 의 디렉토리로 잡아줌으로써 서빙되는 파일을 제대로 리액트 프로젝트의

index.html 파일로 맵핑해줌으로써 해결하였다.

 

위 오류로 인해 3일이라는 시간이 소비되었지만 결국은 배포에 성공하였고 이제 남은 것은 Jenkins 를 활용한 CI / CD 파이프라인 구축이다!

 

 

 

 

 

최종적으로 배포된 사이트의 주소는 아래로 접속하면 되며 아직은 프론트 세부 로직이 구현되지 않은 상태이므로 천천히 구현해나갈 것이다.

 

React App

 

www.random-chat.site

( 미니 PC 는 항상 켜놓지 않고 오전, 오후 시간대에만 실행시켜 서비스할 생각이다. )

 

728x90

 

 

 

 

 

베가스의 밤은 불이 꺼지지 않았다... 정말 번쩍번쩍한 호텔들이 많았고 길거리 어딜 가든지 카지노가 즐비했으며 대마초 냄새가 진동을 했다...

 

호텔앞에서는 정해진 시간마다 분수쇼가 5분 넘게 진행되었다

 

 

 

 

 

- TIL -

 

구현 목표)

프로젝트를 배포할 미니pc 한대를 구매하게 되었다.

미니 피씨에 Docker Compose 를 활용하여 Spring, React, MySQL, Nginx 컨테이너를 각각 생성할 것이며

Nginx 의 리버스 프록시 기능을 사용하여 접속 도메인 별로 React 프로젝트와 Spring 프로젝트로 분류하여 응답할 것이다.

 

 

 

프로젝트 디렉토리 구조)

randomchat/
├── nginx/
│   ├── nginx.conf
│   └── Dockerfile
├── spring/
│   └── Dockerfile
├── react/
│   └── Dockerfile
├── docker-compose.yml

 

 

 

구현 과정)

1. 도커 컨테이너를 구현하기 위해 Docker 설치와 생성된 컨테이너들을 하나로 묶어서 관리할 수 있게 해주는 Docker Compose 를 설치해준다.

더보기

1) 아래 명령어를 사용하여 Docker 와 Docker Compose 를 설치

sudo apt update
sudo apt install docker.io docker-compose -y

 

 

 

2) 각 컨테이너를 관리할 디렉토리를 생성

( 홈 디렉토리 위치는 root 계정의 홈이 아닌 사용자 계정의 홈 디렉토리로 생성한다 )

mkdir -p ~/randomchat/{spring,mysql,react,nginx}
cd ~/randomchat

 

 

 

2. Spring Dockerfile 작성

더보기

1) Spring 컨테이너로 이동하여 빌드된 스프링 파일을 위치시킨다.

( scp 를 사용하여 빌드 파일을 미니 피씨로 전송하였다 )

-P 뒤에는 사용하는 SSH 포트 번호를 기재, youngho3358 은 사용자 계정이며 @ 뒤에는 아이피 주소가 들어간다.

 

정상적으로 빌드 파일이 spring 디렉토리 하위에 생성되었다.

 

위 작업 이후에  jar 파일 이름을 app.jar 로 mv 명령어를 사용해 변경해주었다.

 

 

 

 2) Dockerfile 작성

( /randomchat/spring 경로에 작성 )

FROM openjdk:21-jdk-slim
WORKDIR /app # 컨테이너 내부의 작업 경로
COPY app.jar app.jar
# 로컬의 빌드파일인 app.jar 파일을 도커 컨테이너 내부 경로에 동일한 이름인 app.jar 로 복사하여 사용
# 여기서 앞의 app.jar 이 로컬의 위치인데 docker-compose.yml 에 context 항목을
# 현재 위치인 . 으로 표기했기 때문에 현재 위치인 spring 디렉토리부터의 경로를 기재해주면 된다.
ENTRYPOINT ["java", "-jar", "app.jar"]

 

 

 

3) 디렉토리 내부 상태

app.jar 와 Dockerfile 존재

 

 

 

3. React Dockerfile 작성

더보기

1) React 컨테이너로 이동하여 빌드된 리액트 파일을 위치시킨다.

( scp 를 사용하여 빌드 파일을 미니 피씨로 전송하였다 )

리액트 빌드 파일을 scp 를 사용해서 가져온 뒤 압축을 풀어 react 디렉토리에 위치시켜준다.

 ( 주의할 점 : build.zip 을 압축해제 하면 build/build/{빌드파일} 형태로 디렉토리로 하나 더 감싸져 있는 경우가 있기 때문에 주의해야 한다. )

 

 

 

 2) Dockerfile 작성

( /randomchat/react 경로에 작성 )

FROM nginx:latest
WORKDIR /user/share/nginx/html
COPY build/ .
CMD ["nginx", "-g", "daemon off;"]

 ( COPY 를 통해 react 디렉토리 내부에 build 파일 하위의 파일을 복사하여 도커 컨테이너 내부에 복사하여 사용한다 )

 

 

 

 3) 디렉토리 내부 상태

디렉토리 내부 상태

 

 

 

To-Do List)

1. MySQL 컨테이너 정의하기

2. 가비아에서 도메인 구매하여 아이피랑 연결하기

3. Nginx 를 설치하여 저렴한 도메인을 구매한 뒤 도메인과 연결하여 경로를 처리하기

4. Jenkins 를 사용하여 깃허브에 코드가 커밋될때마다 자동으로 배포하게 설정하기

728x90

+ Recent posts