[AWS]AWS 맛보기 #5(EC2)

peppermint100
14 min readOct 14, 2020

--

서론

저번까지 어플리케이션과 RDS, S3를 연결하여 파일을 올리고 리액트를 통해 저장된 이미지들을 보여주었습니다. 이번엔 이 어플리케이션도 어디서든 접속 가능하도록 EC2를 통해 배포해보도록 하겠습니다. 먼저 제 블로그에는

이러한 글들이 있습니다. 전부다 배포에 관련된 글이고 제가 지금까지 이용했던 배포용 서버는 전부 PaaS였습니다. PaaS는 Platform as a Service의 약자로 코드만 있다면 서버를 아예 건드릴 필요없이 heroku나 cafe24에서 전부 컨트롤을 해줍니다. 모두 git을 기반으로 관리가 되며 코드만 있으면 되기에 관리가 아주 간단합니다. 코드만 있다면 5분내로 배포가 가능하죠.

하지만 EC2는 조금 다르게 작동합니다. EC2는 아마존 회사 어디엔가 있을 컴퓨터안의 빈 깡통 서버 하나를 받게 됩니다. 그 서버의 운영체제도 저희가 정할 수 있고 어떤 보안 그룹에서 접속할 것인지부터 세세한 세팅을 직접 설정할 수 있습니다. 그러면 지금 부터 EC2 인스턴스를 생성하고 지금까지 만든 코드를 올려보겠습니다.

작동 방식

이건 AWS #1에서 제가 그린 간단한 프로토타입입니다. 표시가 허접하지만 X 친 부분이 저희가 지금까지 완성한 부분입니다. 저희는 이제 EC2 인스턴스를 생성하고 안에 NodeJS를 설치해줍니다. 그리고 저희가 작성한 NodeJS Express 백엔드 코드를 실행하여 어디서든 이 백엔드 서버에 접속하여 HTTP 요청을 할 수 있게 만들고 NginX를 이용하여 리액트 어플리케이션의 웹 서버도 띄울 것입니다. 그러면 먼저 EC2 인스턴스부터 생성해 보겠습니다.

EC2 인스턴스

먼저 EC2 대시보드에 접속합니다. S3와 RDS 생성을 다 해보았다면 EC2 대시보드는 쉽게 찾을 수 있습니다. 그리고 주황색의 인스턴스 시작버튼을 누릅니다.

먼저 어떤 운영체제를 사용할지 선택합니다. 제 컴퓨터는 WSL을 사용한 윈도우 컴퓨터로 운영체제로 우분투를 사용하고 있기 때문에 우분투를 선택하겠습니다. 편한 리눅스 운영체제를 사용하셔도 좋지만 우리는 프리티어 사용가능 표시가 있는 운영체제를 사용하는 것이 좋습니다.

인스턴스 유형도 프리티어 사용가능한 인스턴스를 선택하고 다른것은 전부 기본으로 두고 보안그룹에서

아래와 같이 규칙을 추가해줍니다. 80은 NginX 서버에 사용할 것이고 5000번은 저희가 만든 백엔드를 사용할 포트입니다. 그리고 우측하단 검토 및 시작버튼을 누르고 다시 시작하기 버튼을 누르면 키를 생성하라고 합니다.

새 키페어 생성을 선택하고 키페어 이름은 자유롭게 하고 키 페어 다운로드를 해줍니다. 이 키는 ssh 접속을 위한 키로 파일을 잘 관리하셔야 합니다. 이 키가 없으면 이 인스턴스에 접속할 수 없고 해커가 이 파일을 가져간다면 우리가 만든 EC2 인스턴스에 접속할 수 있게 되니 잘 관리합니다.

그리고 인스턴스를 시작해줍니다.

성공적으로 EC2 인스턴스가 실행중이라고 나오면 클릭해서 들어가주도록 합니다.

SSH 접속과 FileZila

SSH는 네트워크의 프로토콜 중 하나로 접속하는 방식을 뜻합니다. SSH를 이용하면 파일 전송과 원격 제어를 할 수 있게 되는데 다른 통신 방식들과 다른 점은 보안이 중요시 된다는 것입니다.

SSH를 통한 접속 방식은 비밀번호를 통한 방식과 키를 통한 방식이 있는데 저희는 방금 저희가 생성한 키 파일을 통해 SSH 접속을 하도록 하겠습니다. 먼저 키파일이 있는 폴더로 이동합니다.

그리고

chmod 600 <YOUR_KEY_NAME>.pem

방금 정한 키의 권한을 변경해줍니다. 600은 차례로 사용자, 그룹, 다른 이용자들의 접근 권한을 의미하며 4는 읽기, 2는 쓰기, 1은 실행 권한을 뜻합니다. 저희는 사용자만 읽고 쓰기를 가능하게 권한을 설정해 준 것입니다. SSH와 chmod는 중요하니 따로 리눅스와 네트워크 전반적인 내용을 공부하는 것이 좋습니다.

그리고

ssh -i <YOUR_KEY_NAME>.pem ubuntu@<YOUR_PUBLIC_DNS>

를 통해 원격으로 방금 생성한 EC2 인스턴스의 우분투 서버에 접속할 수 있습니다.

<YOUR_PUBLIC_DNS>

이 부분은 방금 생성한 EC2 인스턴스의 대시보드에 보면 위쪽에 퍼블릭 IPv4 DNS 라는 부분이 있으니 복사해서 넣으시면 되고 @ 앞에 ubuntu는 서버의 사용자 이름을 뜻하는데 우분투 서버를 생성하면 디폴트로 ubuntu가 사용자의 이름입니다. 다른 운영체제는 root, admin 등 다른 이름을 사용하고 있을 수 있습니다. 그런 경우엔 우측 상단 연결 버튼을 누르면 확인이 가능합니다.

이렇게 접속하면 이제 커맨드라인을 통해 이 EC2 서버를 이용할 수 있게 됩니다. (원격 제어) 하지만 SSH는 파일 전송 역시 지원하는데 이를 쉽게 하기 위해 저희는 FileZila를 이용하도록 하겠습니다.

이곳을 통해 설치하시고 실행한 다음 우측 상단에 open site 버튼을 누르신다음

Host에는 퍼블릭 DNS를 또 복사해서 붙여놓고 Logon Type을 Keyfile로 설정하고 Browse 버튼을 눌러서 생성한 키파일을 지정해주고 Connect를 누릅니다. 그러면

이렇게 원격에서 쉽게 EC2 서버의 파일들에 접근할 수 있습니다. 이제 우리는 우리가 사용한 운영체제에서 파일을 끌어다가 저 안에 드랍하는 것으로 쉽게 파일을 옮길 수 있습니다.

NodeJS와 NginX 설치

다시 ssh로 접속한 터미널로 돌아와서 아래와 같은 커맨드를 입력합니다.

sudo apt-get update

그리고 EC2 서버에 NodeJS와 NginX를 설치해줍니다.

sudo apt install nodejs
sudo apt install nginx

나오는 옵션에는 전부 yes를 해주시고

node -v
nginx -v

를 통해 제대로 설치되었는지 확인합니다.

NginX

NginX는 아파치와 같은 웹서버 프로그램입니다. 하지만 NginX는 현재까지 급격하게 진화해온 웹에 더 알맞고 가볍고 빠릅니다.

cd /etc/nginx
ls -la

를 통해 nginx 파일들을 살펴봅니다.

이 중에서 nginx.conf 파일의 설정을 저희가 만든 프로그램에 맞게 변화할 것입니다.

sudo vim nginx.conf

를 통해 파일을 열어줍니다. 그리고 내용을 전부 지우고 아래 내용으로 교체해줍니다.

user ubuntu;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;sendfile on;
#tcp_nopush on;
client_body_buffer_size 100k;
client_header_buffer_size 1k;
client_max_body_size 100k;
large_client_header_buffers 2 1k;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
server_tokens off;
#gzip on; on;
server {
#listen 80;
#listen 80 default_server;
#listen [::]:80 default_server;
#server_name yourdomain.com;
access_log /home/ubuntu/client/server_logs/host.access.log main;location / {
root /home/ubuntu/client/dist;
index index.html index.htm;
try_files $uri /index.html;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
server_tokens off;location ~ /\.ht {
deny all;
}
}// nginx.conf

nginx.conf 파일은 nginx의 설정을 모아놓은 파일입니다. 가장 위 부분부터

user ubuntu;
worker_processes 1;

user는 이 운영체제 사용자이름이고 worker processes는 사용할 프로세스 코어수를 의미합니다.

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

이 부분은 http 통신을 통한 파일의 타입과 로그 파일 경로를 설정하게 합니다.

server {
#listen 80;
#listen 80 default_server;
#listen [::]:80 default_server;
#server_name yourdomain.com;
access_log /home/ubuntu/client/server_logs/host.access.log main;

이 부분은 nginx의 포트를 정하는데 ec2 인스턴스를 만들때 정했던 80번 포트를 설정해주어야합니다. 전부 #으로 주석 처리를 해주었는데 저렇게 포트를 정해주지 않으면 기본적으로 80번 포트가 설정이 됩니다. 그리고 도메인이 있다면 server_name에 도메인을 정해줄 수 있습니다.

그리고 그 아래는 서버 로그를 저장할 수 있는 설정입니다.

location / {
root /home/ubuntu/client/dist;
index index.html index.htm;
try_files $uri /index.html;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
}

이제 root와 index 부분을 잘 보시면 저희가 제작한 웹 어플리케이션의 구조와 비슷하다는 것을 볼 수 있습니다. client폴더에서

yarn run build

를 통해 빌드파일을 만들면 dist 파일에 index.html 이라는 이름으로 들어가게 webpack 설정을 해놓았기 때문에 저렇게 설정을 해주었습니다. 그 아래는 보안 관련 설정입니다.

이외에도 에러 페이지 설정등 nginx의 설정에서는 지금 여기서 다룰수 없는 부분들이 굉장히 많기 때문에 따로 공부를 하는 것이 좋고 저 역시 nginx에 대해 조금 더 깊게 파볼 생각입니다. 일단은 간단히 설정이 있고 이러한 의미들을 가지고 있다는 것 정도만 알고 넘어가도록 합니다.

어플리케이션 불러오기

이제 ec2 서버에서

cd /home/ubuntu

를 통해 사용자 홈 디렉토리로 이동한 다음 이 안에 저희가 만든 어플리케이션을 전부 집어 넣을 것입니다.

방법은 git으로 가져오는 방법, 그리고 저희가 설치했던 filezila로 가져오는 방법이 있습니다. filezlia를 사용한다면 그냥 저희가 제작한 어플을 마우스로 끌어다가 연결된 서버에 넣으면 되고

아니면

git clone https://github.com/peppermint100/trying-aws

이렇게 제 어플리케이션을 그냥 가져다가 쓰셔도 됩니다. 하지만 직접 ec2에 들어갈 어플리케이션을 만들어보면서 발생하는 에러를 하나하나 보고 해결해보는게 큰 도움이 됩니다. 참고로 git clone으로 가져가면 .env 파일을 자신의 설정에 맞게 다시 작성해주셔야 합니다.

그리고 filezila로 옮길 때 node_modules 파일은 옮기지말고 다른 파일들만 옮겨서 ec2 서버 내에서

npm install

을 통해 node_modules를 새로 다운로드 받는게 빠릅니다.

마찬가지로 client 파일도 그대로 옮길 필요 없이 client 폴더에서

npm run build

로 생성된 빌드 파일만 옮기는 방법도 있습니다.

그리고 nginx.conf 설정에 서버로그를 client/server_logs에 넣어주기로 설정으니 client 폴더에 server_logs라는 디렉토리를 만들어주는 것도 잊지 마세요.

저는 최종적으로 이러한 구조를 갖게 되었습니다. 그리고 client와 server를 각 .env 파일에 엔드포인트를 우리가 생성한 ec2의 퍼블릭 ip로 지정해주어야 cors오류를 해결하고 통신할 수 있습니다.

퍼블릭 ip는 ec2 대시보드 상단에 퍼블릭 IPv4에서 확인할 수 있습니다.

여기 까지 잘 따라오셨다면 퍼블릭 ip를 브라우저 주소창에 입력하는 것으로 웹 페이지에 접속할 수 있습니다. 그리고 ec2 서버에서

yarn run server

를 통해 서버를 실행시켜주면 RDS와 S3를 통해 이미지를 불러오고 업로드도 가능하게 됩니다. 이렇게 하면 최종적으로 어디서든지 접속을 하여 이미지를 올릴 수 있게 되었습니다. 다음 글은 AWS 마지막 포스트로 보안 관련된 설정들을 해보겠습니다.

이번 ec2 설정 및 배포는

위 유튜브 영상을 참고하였습니다.

--

--

peppermint100
peppermint100

Written by peppermint100

기억하기 위해 또는 잊어버리기 위해 작성하는 블로그입니다.

No responses yet