지난 포스팅에 이어 백엔드용 Spring Boot 를 빌드 및 배포해보자.

  1. DockerFile 작성 (프로젝트 루트경로에 작성한다
FROM openjdk:11
# FROM amazoncorretto:11 ==> amazon corretto 11 사용할 경우
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENV SPRING_PROFILES_ACTIVE=prod
ENTRYPOINT ["java","-jar","/app.jar"]
# ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"]
# => 설정파일을 분리해서 사용할 때
# java -jar -Dspring.profiles.active=prod app.jar

2. Build

필자는 Gradle 을 쓰기 때문에 Gradle 로 한다.

./gradlew build -x test

3. 도커 이미지 생성

# gradle linux/amd64 옵션은 맥북 M1을 위한 옵션
$ docker build --build-arg DEPENDENCY=build/dependency -t 도커허브 ID/Repository --platform linux/amd64 .

# maven
$ docker build -t 도커허브 ID/Repository --platform linux/amd64 .

# 확인
$ docker images

4. 도커 업로드

# 로그인
$ docker login

# 업로드
$ docker push 도커허브이름/Repository:버전정보

그 외 리눅스 서버 배포는 Next.js 배포와 동일하니 거길 보고 따라하시면 됩니다.

 

평상시 나는 서버에 도커 실행을 하려면 어지간해서는 서버가 꺼지지 않기에

재시작 설정을 거의 하지 않았다.

그러나 이번에 고객사 서버의 전원이 불량상태로, 잦은 재시작을 하여 교체전까지는 그대로 사용해야 하는 상황이라 재시작 설정 및 도커 데몬 자동 설정을 해야만 했다.

  1. 도커 데몬 자동 실행

* 리눅스

sudo systemctl enable docker // 시스템 재시작시 자동 사용 설정
 

* 윈도우

General -> Start Docker Desktop when you log in 항목 체크, Apply & restart 버튼 클릭

2. 도커 컨테이너 자동 재시작 명령어

# 새로운 컨테이너 생성 시 재시작 정책 적용 
docker run -p [포트번호:포트번호] --restart unless-stopped -d [도커이미지]
 

폴더에 읽기 및 편집 권한을 준다. (하위 폴더까지)

chown {소유권자}:{그룹식별자} {소유권을 변경하고 싶은 디렉토리명}
chown -R root:root test

 

리눅스 명령어를 정리해보자.

분류
명령어
설명
관리자 권한으로 실행
$ sudo
super user
  1. 관리자만 읽을 수 있는 파일 읽기
  2. 새로운 프로그램 설치(ubuntu)
기본 명령어
$ ls
list
파일 보기
$ al
all
파일의 세부내용 확인
$ cd
change directory
디렉토리 이동
$ pwd
print working directory
현재 디렉토리 경로 확인
$ cd ~
홈 디렉토리 이동
$ cd /
루트 디렉토리 이동
$ cd .
현재 디렉토리
$ cd ..
부모 디렉토리 이동
$ clear
터미널 정보 지워줌
$ touch [file_name]
빈 파일을 만듬
$ mkdir [dir_name]
make directory
빈 폴더를 만듬
$ cat [file_name]
concatenate
텍스트 형태 파일 확인
$ mv [file or dic name]
[target_dir_name]
move
파일 또는 디렉토리 위치 옮기기
$ mv [file or dic name]
[new file name]
파일 및 디렉토리 이름 변경
$ cp [file][target_dir_name]
copy
복사
$ cp -r [folder_name]
all copy
하위폴더 및 파일
까지 복사
삭제 관련
$ rm [file_name]
remove
파일 삭제
$ rm -r [dir_name]
remove
폴더 삭제
$ rm -rf [dir_name]
no question remove
삭제할 때 경고창 생략 삭제
파일 소유권 변경
$ chown -R root:root [file_name OR dir_name]
change owner
파일 소유권 변경,
-R을 추가할 경우
하위 폴더 및 파일까지 소유권이 변경됌
GUI 프로그램 실행
$ explorer .
현재 폴더를 window 관리자에서 보기
$ open .
현재 폴더를 macOS finder에서 보기
$ code .
현재 폴더를 VS Code 에디터로 열기

추가적으로 더 발생하면 적어주자

 

 

프로그램 개발 중 코드를 작성하면서 협업을 하는 상황이 매우 자주 발생하는 데,

이 소스 관리를 제대로 하려면 형상 관리 툴을 사용해야 한다.

요즈음 개발자들이 주로 쓰는 GitHub 로 소스를 공유하려면 SSH-Key 를 만들어 허용을 받아야 하므로

만들어보자.

SSH 는 Secure Shell 의 줄임말로, 원격으로 접근할 때 쓰는 보안 프로토콜이다.

비유하자면, 일종의 출입증을 등록하는 절차라고 하겠다.

https://storycompiler.tistory.com/112

상세한 원리와 방식은 위의 자료를 참고하길 바란다.

간단하게 키를 만들어 서버에 접속을 시도해보겠다.

목차

  1. Local 환경 SSH Key 만들기
  2. Git Hub 에 SSH Key 등록하기

1. Local 환경 SSH Key 만들기

일단 현재 ssh key가 있는지 확인해보자.

통상적으로 ssh key는 따로 이름을 설정하지 않을 경우

id_rsa 파일과

id_rsa.pub 파일로 나뉘어진다.

둘의 차이점은 pub 가 붙은 파일은 Public key 즉 공용키이고,

붙지 않은 파일은 private key , 보안이 적용된 키이다.

필자의 경우 있지만 없다고 가정하고 만들어보며,

다른 이름을 부여하여 만들어보자.

ssh key 생성

위를 보면 명령어

ssh-keygen -t rsa -b 4096 -C ohks486@naver.com

으로 작성되어 있다.

-t 옵션으로 암호화 타입을 정할 수 있으며, rsa 는 암호화 방식입니다.

-b 는 생성할 키의 비트수를 정하며, 필자의 경우 4096 비트로 지정했다.

알아보니 rsa타입은 최소 768 비트가 필요하다고 한다.

-C 의 경우 주석을 입력할 수 있으며, 깃헙의 경우 사용자의 로그인ID를 적으라고 가이드한다고 한다.

자 이제 rsa 가 만들어졌으므로,

제대로 만들어졌는지 확인해보자.

인증키 파일 확인

잘 만들어졌다.

이제 이 ssh key가 돌아가고 있는지 확인해보자.

인증키 상태 확인

잘 돌아가고 있다.

이제 이 인증키를 정식으로 등록해보자.

인증키 등록

등록이 잘 됐다.

이제 인증키를 텍스트형식으로 복사하여 사용해보자.

인증키를 텍스트 형식으로 확인한다.

이제 깃헙이나 다른 클라우드에서 ssh key를 등록할 때

저 텍스트 부분을 복사해서 붙여넣으면 되는데,

주의할 점은 제일 첫부분인 ssh-rsa 부터 제일 끝부분까지 전부 복사하여 넣어야 한다는 것이다.

2. Git Hub 에 SSH Key 등록하기

Git Hub 에 로그인에서 자기 프로필을 클릭하면, 다음과 같은 메뉴가 켜지는데

Settings를 클릭한다.

Git Hub SSH and GPG keys

다음과 같이 좌측의 SSH and GPG keys 버튼을 클릭한다.

클릭하고 New SSH key 버튼을 클릭한다.

인증키를 텍스트 형식으로 확인한다.

아까 진행했던 텍스트형식으로 확인한 인증키를

아래 화면에 붙여넣는다.

이런 식으로 키를 첫 부분부터 이메일부분까지 전부 넣어야 한다.(밑에는 짤렸어요 ㅜㅜ)

위 사진은 깃헙에 ssh-key를 넣은 것으로, 정상적으로 등록됬다면

이제 깃의 명령어를 사용해서 깃헙에 있는 소스코드를 내려받거나, 편집 등 수정을 할 수 있다.

막상해보면 별거 아닌데 처음하면 어렵게 느껴진다

혹시 안된다면 절차대로 했는 지 꼭 확인해보자!

파일 복사

cp test.txt test_2.txt

폴더 복사 (하위 폴더까지)

cp -r test test2
 

 

개발하다보면 의도치 않게 프로젝트를 종료했음에도 포트가 살아 있는 경우가 있다.

그럴 때는 포트를 찾아서 종료해야 프로젝트가 정상적으로 실행된다.

1. 종료하길 원하는 포트번호를 찾자

lsof -i :포트번호

포트를 종료하려면 포트번호가 아닌 PID가 필요한데, PID를 종료시켜야 한다.

2. 포트 종료하기

kill -9 [종료대상 PID]

포트 종료를 하고 포트 찾기 명령어를 확인하니 나오지 않는다.

종료가 잘 됐다.

서버를 원격으로 연결하여 프로그램을 실행한 이후,

터미널로 봤을 때는 프로그램이 정상적으로 실행되고 있지만

터미널 세션을 종료하면 프로그램이 같이 종료되는 경우가 있다.

터미널을 종료해도 프로그램을 실행할 수 있도록 하는 방법이 몇 가지 있지만

제일 쉬웠던 방법만 써본다.

  1. 평상시 프로젝트 실행 명령
npm run start

   2. 개선 방법

nohup npm run start & exit

nohup 명령어로 실행하고

exit 의 경우에는 따로 입력하여 종료한다.

나같은 경우 터미널을 그냥 x버튼을 클릭하여 종료했는데

그러면 nohup 명령어가 정상적으로

실행되지 않기에

exit 로 안전하게 터미널을 빠져나간다.

하루단위로 서버가 자꾸 내려가길래..뭔가 했더니

인위적으로 매우 빠른속도로 도메인에 접근 시도를 하더라..

이제 차단해보자.

내가 사용하는 리눅스는 CentOs 를 쓰는데 기본적으로 firewall 이 있더라.

구글링을 해보니 iptables 로 차단하는 게 적절해보여 이것으로 시도해보자.

우선 iptables 로그파일을 생성하도록 rsyslog.conf 에 RULE을 추가한다.

1. vi /etc/rsyslog.conf

RULE 추가

kern.* /var/log/iptables.log

2. iptable 서비스 추가, 재부팅시 설정값이 사라지지않도록 systemctl 에 서비스를 등록한다.

yum install iptables-services
systemctl enable iptables.service #(자동실행)

3. 특정 포트로 접근하는 것들 차단

(80 포트로 1초에 5번이상 접근하는 것들 차단)

iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 5 --name HTTP -j DROP

간단하게 긴급조치할것만 작성하였고 다음에 또 알아보도록 하자

서버 설정 가끔씩 하는 데, 가끔 까먹을 때가 있어 기재해놓는다. 나의 개발환경은

리눅스(CentOS),Nginx, 도커, 스벨트,스프링부트, MariaDB 환경이다.

(도메인 갱신은 Let's encrypt)

  1. ELCAP 방화벽 설정

2. 서버에 firewalld 설치

sudo yum install firewalld // 설치
sudo systemctl start firewalld // 시작
sudo systemctl enable firewalld // 재부팅해도 자동실행하도록 등록

 

3. 특정포트 허용(위의 ELCAP 방화벽 관리의 포트를 허용해준다고 보면 됌)

sudo firewall-cmd --zone=public --add-port=80/tcp --permanent // 80 포트 허용 .. 이하 생략

4. 특정 서비스 허용(http,https 등)

sudo firewall-cmd --zone=public --add-service=https --permanent // https 허용 .. 이하 생략

했을 때 success 라고 나오면 된 것임

5. firewalld 업데이트

sudo firewall-cmd --reload

이제 방화벽을 업데이트하자

6. firewalld 업데이트 후 등록된 리스트 확인

sudo firewall-cmd --list-all

방화벽 설정은 이제 끝났다.

이쯤에서, 소프트웨어 패키지 도구인 epel 을 설치해보자

7. epel-release 설치

sudo yum install epel-release // epel 설치

중간에 질문을 할텐데, y눌러주면 됌

8. MariaDB 버전 설정

cd /etc/yum.repos.d   // 해당경로 이동
touch MariaDB.repo   // MariaDB 설정용 파일 생성
vim MariaDB.repo  // 해당 파일 접근

 

vim으로 접근한 MariaDB.repo에 아래 내용 작성

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.6/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

 

나의 경우 10.6버전대를 사용, 위와 같이 설정한다.

9. mariadb 설치

sudo yum install mariadb-server

epel 로 설치되는 것을 볼 수 있다.

10. 시스템 등록 및 시작

sudo systemctl start mariadb // MariaDB 서비스 시작
sudo systemctl enable mariadb // 재부팅시에도 동작하게 등록

11. 비밀번호 설정

MariaDB의 경우 초기비밀번호는 공백이기 때문에 개나소나 들어올 수 있다.

바로 비밀번호 설정을 해준다.

sudo mysql_secure_installation // 보안설정

 

위와 같이 root 비밀번호 세팅할거냐 물어보면. y 눌러주고 현재 비밀번호가 공백이기 때문에

그냥 엔터누르면 바꿀 비밀번호 입력하고 확인 비밀번호까지 입력하면 성공처리된다.

그 외 보안옵션이 있지만 취향껏 설정한다.

12. 최종체크

데이터베이스 세팅 및 테이블 세팅은 별개로 한다.(자기 개발환경에 맞춰서)

13. Nginx 설치

설치전 내 블로그를 참조해보고 진행하면 좋다.

https://blog.naver.com/ohks486/222832867066

sudo yum install nginx

14. Nginx 경로 이동

cd /etc/nginx/conf.d

15. default.conf 파일 생성

디렉토리로 접근했는데, default.conf 파일이 없을 경우 만들어준다. 있으면 안 만들어도 됌

touch default.conf

 

16. default.conf 파일 수정(중요)

sudo vi default.conf // vim으로 해도됌

17. 각 도메인별 서버 설정한다.

 

server {


     if ($http_user_agent ~* (AhrefsBot|BLEXBot|DotBot|SemrushBot|Eyeotabot|PetalBot|MJ12bot|brands-bot|bbot|AhrefsBo|MegaIndex|UCBrowser|Mb2345Browser|MicroMessenger|LieBaoFast|Headless|netEstate|newspaper|Adsbot/3.1|WordPress/|ltx71) ) {
    return 403;
  }

                        listen 80 default_server;
                        server_name *.도메인.kr;
                        return 301 https://$host$request_uri;

        }


server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;
                server_name test.도메인.kr;
                ssl_certificate /etc/letsencrypt/live/test.도메인.kr/fullchain.pem;
                ssl_certificate_key /etc/letsencrypt/live/test.도메인.kr/privkey.pem;
                ssl_session_timeout 1440m;
                ssl_session_cache shared:SSL:50m;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                location / {
                 proxy_pass http://localhost:8081/;
                         proxy_read_timeout 600s;
                         proxy_send_timeout 600s;
                         proxy_redirect off;
                         proxy_pass_header Server;
                         proxy_set_header Host $http_host;
                         proxy_set_header X-Real-IP $remote_addr;
                         proxy_set_header X-Scheme $scheme;
                         proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
                         proxy_set_header X-Forwarded_Server $host;
                         proxy_set_header X-Forwarded-Host $host;
                         proxy_set_header Upgrade $http_upgrade;
                         proxy_buffer_size 128k;
                         proxy_buffers 4 256k;
                         proxy_busy_buffers_size 256k;
                         proxy_http_version 1.1;
               }

}

server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;
                server_name test.도메인.kr;
                ssl_certificate /etc/letsencrypt/live/test.도메인.kr/fullchain.pem;
                ssl_certificate_key /etc/letsencrypt/live/test.도메인.kr/privkey.pem;
                ssl_session_timeout 1440m;
                ssl_session_cache shared:SSL:50m;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                location / {


                 proxy_pass http://localhost:3000/;
                         proxy_read_timeout 600s;
                         proxy_send_timeout 600s;

                         proxy_redirect off;
                         proxy_pass_header Server;
                         proxy_set_header Host $http_host;
                         proxy_set_header X-Real-IP $remote_addr;
                         proxy_set_header X-Scheme $scheme;
                         proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
                         proxy_set_header X-Forwarded_Server $host;
                         proxy_set_header X-Forwarded-Host $host;
                         proxy_set_header Upgrade $http_upgrade;
                         proxy_buffer_size 128k;
                         proxy_buffers 4 256k;
                         proxy_busy_buffers_size 256k;
                         proxy_http_version 1.1;
                 }
        }

18. Let's encrypt 설치

설정은 다했는데.. nginx -t 로 테스트를 해보면 실패할 것이다.

왜냐하면 아직 Let's encrypt로 설정을 안했기 때문이다.

자세한내용은 여기 참고

https://blog.naver.com/ohks486/222833865442

sudo yum install certbot

19. 도메인 등록

sudo certbot certonly --standalone -d 도메인주소

만약 80포트 관련 에러가 나올 경우, nginx stop 후 다시 진행한다.

sudo systemctl stop nginx sudo certbot certonly --standalone -d 도메인주소

위와 같이하면 인증서가 나오는데, nginx 에서 서버설정 시 인증서 경로를 추가해주자

20. Docker 설치

 

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io​

21. Docker 서비스 시작 및 등록

sudo systemctl start docker
sudo systemctl enable docker

22. Docker login

docker login

docker 로 실행하기 때문에 Node.js, 자바 등은 별도로 설치하지 않는다.

이상 끝~

** 혹시 서비스 접근했는데 502 에러 나올 시 조치방법이다. **

vi /var/log/nginx/error.log 내용

13: Permission denied) while connecting to upstream

나의 경우 https만 안되었다.

setenforce 0 // SEL Linux를 disable 처리한다.
sestatus // SEL Linux 상태확인

sestatus를 하면 위에 sentenforce를 0으로 했기 때문에 아래와 같이 간단하게만 나올 것이다.

 

그럼 이제 이부분을 편집해보자.

RHEL/CentOS 8 일경우

vi /etc/selinux/config

RHEL/CentOS 7 일경우

vi /etc/sysconfig/selinux

아래 SELINUX = enforcing 으로 수정한다.

그다음, 서버를 재시작한다.

reboot

+ Recent posts