[사이드 프로젝트] react & flutter 채팅 앱 만들기 0 - 프로젝트 설계 및 인프라 구축

gimseonjin616·2022년 2월 26일
1

들어가며


플러터 공부를 하며 문득 '카카오톡은 웹에서 메시지를 보내면 앱에서 어떻게 인지하고 알람을 보내는 것일까?' 라는 생각이 들었다.

그래서 관련 자료를 리서치 해보니 FCM(Firebase cloud messaging)을 통해 푸시 알림을 준다는 것을 알았다.

'바퀴는 개발하지 마라'라는 말처럼 이미 기존에 존재하는 기술을 쓰면 되지만 나는 FCM 없이 자체적으로 알람을 주고 싶다! 따라서 나는 Websocket을 사용해서 웹에서 메시지를 보내면 서버에서 앱에게 푸시 알림과 메시지를 보내는 방식을 구현해보고자 한다.

Tech Stack


Front endAppBack end
프론트 엔드에서는 요즘 공부하고 있는 React를 사용해서 채팅창을 구현해보고자 한다.앱에서도 최근 공부하고 있는 fluttter를 사용해서 채팅창을 구현해보가자 한다.서버 부분은 이전까지(?) 열심히 공부한 Spring boot를 사용해보고자 한다. nest js랑 flask 공부한다고 너무 소홀했다.

Architecture


  • flutter에서 로컬 환경의 서버를 감지하기 위해서는 10.0.2.2 내부 ip를 사용해야한다. 다만 내 mac 설정 문제인지? 제대로 연결이 되지 않는다. 따라서 AWS EC2 내에 서버를 배포해서 flutter와 react와 연결하고자 한다.

  • 이때 매번 ec2 가서 배포하기 귀찮을 듯 해서 Jenkins 환경을 구축해서 git push 하면 자동으로 배포할 수 있는 인프라를 구축한다.(이게 더 귀찮으려나?)

ch.0 Jenkins Setting


우선 젠킨스를 설치해서 서버 인스턴스를 관리할 젠킨스 서버를 구축하도록하자.

  1. EC2 생성

  2. 접속 후, 환경 구축

# 기본적으로 linux는 설치가 안되는 패키지가 많다!
# 젠킨스를 설치하기 위해 필요한 daemonize도 설치가 안된다!
# 따라서 epel 설정을 줘서 이 부분을 설치할 수 있게 해준다
# Jenkins는 자바 기반이라 java를 같이 설치해주자
$ sudo amazon-linux-extras install epel -y
$ sudo yum update -y
$ sudo yum install jenkins java-1.8.0-openjdk-devel

# Jenkins는 yum 패키지에 포함되어 있지 않아서  설치 경로를 yum 패키지에 추가해줘야 한다!
$ sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
$ sudo yum install jenkins

# Jenkins를 실행해주고 제대로 실행됐는 지 확인한다.
$ sudo systemctl start jenkins
$ sudo systemctl status jenkins

  1. 8080포트 열어서 접속하기

...? 안된다??? 왜지??

우선 리서치 해보니 거의 대부분 linux에서 jenkins 환경을 세팅할 때, nginx를 프록시 서버로 앞단에 두더라(이유는 설명 안해준다... 일단 해보자!)

$ sudo yum install nginx
$ sudo vim /etc/nginx/nginx.conf
server {

	# 추가할 내용 
	location / {
                proxy_pass http://localhost:8080;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
        }
	...
}
$ sudo systemctl restart nginx

흠!! 안된다!!! 그러면 Ubunto로 바꿔서 한번 시도해보겠다.

$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk

$ wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
$ sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \
    /etc/apt/sources.list.d/jenkins.list'
$ sudo apt-get update
$ sudo apt-get install jenkins

$ sudo systemctl start jenkins

위 방식으로 설치하고 8080 포트를 열어서 접속해보자!

잘 뜬다! 아무래도 linux에서 jenkins 설치할 때 뭔가 실수가 있었던 듯 하다.

아래 명령어로 비밀번호를 받아와서 젠킨스 설정을 마무리하자.

$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword

플러그인 설치 버튼으로 설치를 계속해주자

관리자 계정 설정 후, 완료 버튼을 클릭하면 다음과 같이 완료 페이지가 뜬다!

대시보드에서 좌측 jenkins 관리로 들어갑니다.

플러그인 관리로 들어가서 필요한 플러그인 ssh를 설치해줍니다.

이제 .pem 키 내용을 jenkins에 넣어줘야 한다.
그래야 다른 인스턴스에 접근해서 배포를 할 수 있으니까!

이제 실제 서버를 배포할 EC2 서버를 만들어서 잘 연결되는 지 확인해보자!

ch.1 Spring boot server 만들기


이제 젠킨스 서버와 인스턴스가 연결됐다.
제대로 배포할 수 있는 지 확인하고 우리가 사용할 서버를 만들어보자!

스프링 이니셜라이저 : https://start.spring.io/

우선 Spring Web과 Spring WebSocket, Lombok을 세팅해서 프로젝트를 만들었습니다.

그리고 intellij로 열어주겠습니다.

그 후, TestController.java 파일을 만들어줍니다.

package com.example.practice_websocket;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/")
    public String test(){
        return "hello world!";
    }
}

이제 젠킨스에서 이 파일을 가져올 수 있도록 github에 올리도록 합시다.

다시 젠킨스 대시보드로 이동해서 ssh 배포 설정을 해줍니다.

여기서 exec command 부분에 배포 스크립트를 입력해줍니다.

그리고 저장 후 좌측에 build now를 클릭해줍니다.

보면 3번의 실패 후, 4번째에 성공한 것을 볼 수 있다!
3번의 실수는 커맨드 권한 문제, 그리고 백그라운드 실행 문제였다.
따라서 배포 스크립트를 아래와 같이 수정했다.

sudo git clone https://github.com/gimseonjin/practice_websocket.git

cd practice_websocket

sudo ./gradlew build
sudo ./gradlew bootJar
sudo nohup java -jar build/libs/practice_websocket-0.0.1-SNAPSHOT.jar &

그리고 EC2 8080 포트로 들어가보면 다음과 같이 뜬다.

Ch.2 github webhook과 연결하기


이제 github webhook과 젠킨스를 연결해서 git push 하면 자동으로 ec2에 배포되는 것을 설정해보자.

젠킨스 아이템으로 들어와서 구성에 들어갑니다.

빌드 유발 쪽에서 github hook trigger for ~~ 부분을 체크한다.

다음으로 command를 다음과 같이 작성한다. 이따 >/dev/null 2>&1 코드는 nohup으로 백그라운드로 재생시킨 서버의 log output을 지정해줘서 build 시퀀스가 성공적으로 마칠 수 있게 하기 때문에 꼭 해줘야 합니다.

그리고 github로 들아간다. 그리고 세팅으로 들어가 webhook으로 간다.

그리고 add webhook,

거기서 payload url 부분에 젠킨스 base url + /github-webhook/ 을 입력해줍니다.

그 후 webhook 페이지로 이동해서 새로고침 한 후, 초록색 체크표시가 생겼는 지 확인합니다.

그리고 소스 코드를 다음과 같이 수정해서 git push를 해서 제대로 배포가 되는 지 확인해봅니다.

package com.example.practice_websocket;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class TestController {

    @GetMapping("/")
    public String test(HttpServletRequest req){
        String ip = req.getHeader("X-Forwarded-For");
        if (ip == null) ip = req.getRemoteAddr();
        return ip;
    }
}

접속 화면 -> 성공!!!

profile
to be data engineer

1개의 댓글

comment-user-thumbnail
2022년 9월 12일

따라해보겠습니다.

답글 달기