본문 바로가기

만들고 싶은거 만들기

광고 수익을 창출할 웹사이트 만들어보기 3-6(EC2 서버에 SSL인증 + 도메인 넣기)

지난편에서 python 삽집을 땅 끝까지 했다.

다행히 설치랑 필요 패키지까진 완료를 했으니 이제 실제 배포를 진행할 차례다.

 

찾아봤는데 Python은 JAVA와 다르게 WAS에 올라가는 개념이 아니더라. (오잉 걍 톰캣에 못 띄움?!)

대신 유사한 역할을 하는 다양한 웹 서버 및 애플리케이션 서버 프레임워크가 존재한다.

WSGI라는 was 비슷한 역할을 하는 서버가 있는듯 하다. 

(참고로 나는 톰캣 등 여러 was를 2만번은 써봤기 때문에 와스의 개념이 좀 더 쉽게 다가온다.)

개발하는 환경이라면 그냥 app.py를 가져다 실행만 시키면 되지만, 

운영환경의 경우 WSGI를 사용하는 것이 실제 운영 환경에서 성능과 안정성을 보장하기 위해서 더 좋다고 한다.

 

Flask에는 기본적으로 내장 개발 서버(Werkzeug)가 포함되어 있다.

python app.py로 내 프로그램을 실행하면 Flask의 개발 서버가 작동하여 웹 애플리케이션이 실행된다.

하지만 역시 개발서버라서 단일 스레드와 단일 프로세스만 사용되고 LB도 안되고

Nginx 같은 리버스 프록시 서버와 결합하여 HTTPS 지원하지 못하는 등 여러가지 단점이 존재한다고 한다.

 

아무튼 오늘 해볼껀 일단 ec2사이트에

1차적으로 개발개념의 배포 후 

2차적으로 gunicorn을 이용해 WSGI서버에 배포를 해보겠다.

(저거 구니콘이라고 읽는거 맞음? 쥬니콘?)

 

바로 시작한다.


일단 첫번째 할일은 d:/경로에 보관되고 있는 내 백앤드프로젝트를 ec2의 /emoji-gen 경로에 넣을것이다.

 

필요한 파일은 app.py파일과 .env파일 밖에 없다.

저것을 내경로에 바로 옮겨주겠다. 여기서 moba의 특장점이 나오는데, 파일을 그냥 드래그형식으로 옮길수 있다.

원래는 일반적인 putty를 사용하려면 귀찮게 명령어를 쳐줘야 하지만,

윈도우의 파일을 리눅스에도 그냥 파일 옮기듯 드래그해서 넣는게 가능하다.

 

 

이 후 파일이 다 옮겨 졌따면 아래 명령어를 통해 가상환경에 진입한다. (venv명령어가 window랑 살짝 다름)

source venv/bin/activate

 

진입완료

이제 여기서 app.py를 실행시켜주면 되는 것이다.

 

내장 개발서버라 그런지

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. 라는 문구가 보인다.

" 경고: 이것은 개발 서버입니다.프로덕션 배포에서 이서버를 사용하지 마세요. 대신 프로덕션 WSGI 서버를 사용하세요."

 

개발서버 쓰지말고 WSGI 쓰라고한다. 어 알았어 쓸거야 기다려

 

이제 잘 띄워졌으나, 한가지 부족하다 바로바로 http라는 점 SSL인증서를 적용해서 https 프로토콜을 사용해야 

기본적으로 https를 지원하는 버셸과 서로 통신할 수 있다.

브라우저는 HTTPS → HTTP 요청을 허용하지 않으므로, API 요청도 HTTPS를 사용해야 한다.

 

API 요청이 HTTPS를 통해 이루어지도록 설정하려면 일단 SSL 인증서를 발급 받아야 하는데 나는 무료 SSL d인증서인 Let's Encrypt를 사용 해볼 예정이다.

 

일단 사용하는 이유는 무료이고 간단해서다.

Nginx가 데이터를 암호화(HTTPS)해 주니까 서버 코드(Flask)는 따로 신경 쓸 필요가 없다.

무료 인증서(예: Let's Encrypt)를 자동으로 설정하고 갱신하는 걸 Nginx가 지원한다.

 

시작해보자.

아래 명령어를 쳐보면 서버에 nignx가 설치되어있는지 확인할수있다.

nginx -v

 

설치안되어있음

 

 

설치되어 있지 않다면 다음 명령어로 설치한다.

sudo apt update
sudo apt install nginx -y

apt도 없다.

yum으로 설치가 안된다.

sudo yum install -y nginx

 

찾아보니 Amazon Linux 2를 사용 중이므로, Amazon Linux Extras를 통해 Nginx를 설치해야 한다고 한다.

 

설치방법은 아래와 같다.

 

1. Amazon Linux Extras를 사용하여 Nginx 설치

  1. Nginx 설치 가능 확인
    • 출력에서 nginx1이 설치 가능 상태인지 확인합니다.
       
amazon-linux-extras list | grep nginx
  1. Nginx 설치
     
sudo amazon-linux-extras enable nginx1 
sudo yum install -y nginx
  1. Nginx 서비스 시작
    • 상태가 **active (running)**으로 표시되면 Nginx가 정상적으로 실행되고 있습니다.
       
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx

 

위 순서로 설치 후 서비스가 시작되면 아래 처럼 초록색으로 active라고 나온다.

Nginx가 정상적으로 실행되고 있음을 나타낸다.

 

ec2서버의 퍼블릭IP로 서버를 띄워서 확인해보면 환영해주는 메세지가 나온다.

이렇게 나오면 설치된거임

 

HTTP가 정상적으로 작동하면, 다음 단계로 HTTPS를 설정한다.

 

Certbot 설치 (Let's Encrypt):

sudo amazon-linux-extras enable epel
sudo yum install -y epel-release
sudo yum install -y certbot

캄플릿트~!

 

이제 SSL 인증서를 생성해주면 되는데 생성전에 일단 알아두어야 할게 있따.

 

인증서를 발급하려면 도메인이 무조건 있어야 한다.

IP만으로는 설정할 수 없다.

AWS에서 제공하는 임시 퍼블릭 도메인(ec2-xxx-xxx-xxx-xxx.compute.amazonaws.com)은

보안상의 이유로 Let's Encrypt 인증서를 지원하지 않는다.

 

(자체인증서를 만드는 부분은 굳이 따라하지 마세요.)


그래서 도메인이 없더라도 EC2의 퍼블릭 IP로 HTTPS 통신을 설정해보려고 한다.

 

일단 Nginx로 HTTPS 설정을 해줄꺼다.

아래 명령어로 자체 서명된 SSL 인증서를 생성한다.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/self-signed.key -out /etc/nginx/self-signed.crt

 

생성할때 이것저것 값을 물어보는데 아래를 참고해서 넣어주자.

1. Country Name (2 letter code)

  • 예시: KR
    (대한민국의 경우 KR, 미국은 US 등 국가 코드를 입력)

2. State or Province Name (full name)

  • 예시: Seoul
    (거주지 또는 서버 위치의 주/도 이름)

3. Locality Name (eg, city)

  • 예시: Seoul
    (시 이름)

4. Organization Name (eg, company)

  • 예시: My Company
    (회사 이름 또는 개인 프로젝트 이름)

5. Organizational Unit Name (eg, section)

  • 예시: IT
    (부서 이름 또는 빈 칸으로 비워둬도 됨)

6. Common Name (e.g. server FQDN or YOUR name)

  • 중요: 여기에 서버의 도메인 이름 또는 퍼블릭 IP 주소를 입력해야 합니다.
    • 도메인 사용 시: example.com
    • IP 주소 사용 시: 123.45.67.89

7. Email Address

  • 예시: admin@example.com
    (관리자 이메일, 빈 칸으로 비워둬도 무방)

8. 기타 추가 정보 (Optional)

"Challenge password"나 "Optional company name" 등 추가 입력란은 그냥 비워둬도 됩니다.

 

입력이 완료되면 인증서와 키가 /etc/nginx/self-signed.key 및 /etc/nginx/self-signed.crt로 저장된다.

이후 Nginx 설정에 반영하면 된다.

 

Nginx 설정 파일 수정: /etc/nginx/conf.d/default.conf를 열어 아래 내용을 추가한다.

server {
    listen 443 ssl;
    server_name <EC2_PUBLIC_IP>;

    ssl_certificate /etc/nginx/self-signed.crt;
    ssl_certificate_key /etc/nginx/self-signed.key;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

 

이 후 Nginx를 재시작해준다.

sudo systemctl restart nginx

 

 

SSL 인증서를 신뢰하라는 경고가 표시될 수 있지만,

이는 자체 서명 인증서이기 때문에  "고급" 옵션을 클릭하고 진행하면된다......... 만

 

Velcel에서 자체 서명 인증서를 신뢰하지 않아 프론트앤드와 백앤드간의 통신이 안된다.

하는 수 없이 도메인을 하나 사야된다는 말이다. 


(이제부터 따라해도됨.)

가비아에서 도메인 구입해서 ec2서버에 고유 도메인을 설정한 후,

EC2에 Let's Encrypt 인증서를 설치하는 방향으로 바꿔보겠다.

 

일단 가비아 웹사이트에 들어가 도메인 구경을 해본다.

나는 API 통신만 주고 받을것이기 때문에 아무거나 사도 된다.

 

1900원 나이스

일단 1년만 설정하고 결제해보자.

간단하게 구매했으면 이제 EC2 서버의 고정 IP 설정이 필요하다.

EC2 인스턴스의 퍼블릭 IP는 재부팅 시 다른 IP로 변경된다.

그래서 **탄력적 IP(Elastic IP)**를 사용해 고정 IP를 설정해야 한다.

 

설정 방법은 아래와 같다.

  • 왼쪽 메뉴에서 네트워크 및 보안 > 탄력적 IP를 클릭합니다.
  • 탄력적 IP 주소 할당을 클릭한 뒤, 탄력적 IP를 생성합니다.
  • 생성된 탄력적 IP를 EC2 인스턴스에 연결합니다:
    • 작업 > 탄력적 IP 주소 연결을 클릭.
    • 인스턴스를 선택한 후 연결을 클릭.

 

이렇게 하면 IP주소가 서버가 재부팅되어도 똑같이 유지된다.

 

이제 가비아에서 구입한 도메인을 ec2서버와 연결할 차례다.

가비아에서 구입한 도메인을 EC2의 탄력적 IP에 연결하려면 DNS 설정을 변경해야 한다.

절차는 아래와 같다.

  1. 가비아 마이서비스 > 도메인 관리로 이동합니다.
  2. 구입한 도메인의 DNS 설정을 클릭합니다.
  3. A 레코드 추가:
    • 타입: A를 선택합니다.
      • A 레코드는 도메인을 특정 IP 주소로 연결할 때 사용됩니다.
    • 호스트: @를 입력합니다.
      • @는 루트 도메인을 의미합니다. 만약 하위 도메인(예: www.xxx.xxx)을 설정하고 싶다면 www를 입력합니다.
    • 값/위치: (아까 할당 받은 탄력적 IP 주소)
      • EC2 인스턴스의 탄력적 IP 주소를 입력합니다.
    • TTL: 기본값(600)으로 설정합니다.
      • TTL은 캐싱 시간을 설정하며, 기본값으로 유지해도 문제가 없습니다.
    • 우선 순위: 필요 없습니다. 그대로 두세요.
    • 저장 버튼을 클릭하여 레코드를 추가합니다.
  4. 저장 버튼을 클릭합니다.

DNS 레코드를 추가한 뒤 변경 사항이 전파되기까지 최대 몇 분에서 몇 시간까지 소요될 수 있다고 한다.

변경 사항이 전파되었는지 확인하려면 터미널에서 아래 명령어를 사용하여 도메인의 IP 주소를 확인할수있다.

nslookup <내 도메인>

결과에 EC2의 퍼블릭 IP 주소가 표시되면 설정이 완료된 것이다.

이렇게 설정이 완료되면 가비아에서 구매한 도메인으로 접속을하면

DNS 서버가 해당 도메인을 EC2서버의 탄력적 IP 주소로 변환하고 EC2로 요청을 보내준다.

 

이제 Let's Encrypt의 Certbot을 사용하여 무료 SSL 인증서를 발급할 수 있다.

발급절차는 아래와 같다.

sudo certbot --nginx -d imoji-gen.site

아래 명령어를 쓰면 이메일과 약관동의/HTTP동의 여부가 나오는데 순서대로 입력해준다.

 

만약 실패한다면 HTTP 포트가 안열려있는걸수도 있으니 EC2 대쉬보드로 이동해서 보안그룹-인바운드규칙에 

HTTP허용도 추가해주자.

드디어 생성되었다.

하지만 Nginx 설정에 자동으로 설치되지 않았다는 메시지가 있다.

설정해주면 HTTPS가 정상적으로 동작하게 된다.

 

Nginx 설정 파일을 수정해보겠다.

기본적으로 /etc/nginx/conf.d/ 디렉토리에 설정 파일이 있다. (default.conf 아까만듬)

얘는 그냥 냅두고 새로운 설정 파일을 생성해서 진행하겠다.

sudo vi /etc/nginx/conf.d/imoji-gen.site.conf

 

vim 편집기로 파일을 생성하고 아래 내용을 추가한다.

server {
    listen 443 ssl;
    server_name imoji-gen.site;

    ssl_certificate /etc/letsencrypt/live/imoji-gen.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/imoji-gen.site/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5000;  # Flask 서버와 연결
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

# HTTP를 HTTPS로 리다이렉트
server {
    listen 80;
    server_name imoji-gen.site;

    return 301 https://$host$request_uri;
}

 

저장하고 나온 뒤 아래 명령어로 설정이 잘 되는지 오타는 없는지 확인 후 Nginx를 재시작해준다.

sudo nginx -t

sudo systemctl restart nginx

 

이제 가상환경에서 app.py를 실행한 뒤 아까 구입한 도메인으로 접속해보면 된다.

Not Found로 보이지만 잘 실행이 된 상태다. 백앤드서버이기 때문에 웹페이지가 없는것일 뿐이다.

이로써 도메인 할당 및 https 세팅까지 완료되었다.

 

이번편은 여기까지하고 다음편에서 실제 Vercel로 배포된 리액트서버와 EC2에 배포된 flask서버와 통신을 해보겠다.


 

.다음편에 께속...