프로그래밍 기초/portfolio project

NGINX 와 서브도메인 연결

NOG 2024. 10. 2. 21:28

 

호스팅

 
웹사이트를 공용 IP 주소나 도메인을 통해 인터넷에 배포하고 사용자가 접근할 수 있도록 하기 위해 서버 공간과 필요한 기술을 제공하는 서비스
도메인과 웹 호스팅 서버의 IP 주소와 연결하여 웹 사이트에 접근할 수 있도록 도와준다.
 
자신의 웹사이트를 운영하려면 데이터를 저장할 서버 공간과 인터넷 연결이 필요
=> 웹 호스팅은 이러한 자원과 기술을 제공하여 사용자가 복잡한 서버 관리 없이도 비용 효율적이고 안정적으로 공개가능
 
 

EC2 생성

 

프라이빗 키 파일을 만든다.

 

 

프라이빗키는 로컬에 저장된다. SSH 접속 시 사용된다.

 

인바운드 HTTP,HTTPS 허용시킨다

 
 

 

개인키가 있는 디렉토리에서 ssh 명령어 실행

 

sudo service nginx status를 통해 active 확인

 
 

 

서브도메인 생성

 
 

 

name에 api만 적어도 api 가 서브도메인으로  입력되고 value에 ec2에 연결된 public ip를 입력하면 생성이 완료된다.


https://sourcebox.dev/blog/20231117/
 

/*

TTL : 얼마의 시간동안 DNS 캐시 서버들이 해당 레코드를 캐싱할 지 결정

TTL이 낮으면 레코드의 변경사항이 빠르게 적용하는 대신 요청빈도나 네트워크 트래픽,조회시간 늘어난다.

*/

 

LET'S ENCRYPT SSL 설치

 

sudo apt update

sudo apt upgrade

sudo apt install nginx

sudo add-apt-repository ppa:certbot/certbot

sudo apt install -y certbot python3-certbot-nginx

sudo nano /etc/nginx/sites-available/default

# certbot이 제대로 설정할 수 있도록 sever name 뒤에 도메인 입력

 

 

ngnix 설정의 sever_name 뒤 도메인 입력

 

 

sudo nginx -t => 테스트

sudo systemctl reload nginx

sudo ufw status => inactive 확인 # ec2 기본적으로 비활성화

sudo certbot --nginx -d 도메인 -d www.도메인

 

 

sudo certbot --nginx -d 도메인이름

 

HTTPS 실패 화면

 

 

Timeout during connect (likely firewall problem) Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.

 

실패화면이 뜨고 오류문구를 잘 읽어보면 방화벽 문제이거나 등록된 도메인 포인트를 잘 확인하라고 되어있다.

 

=>

1. EC2의 SG를 확인한다. (인바운드 규칙에서 https ,http 허용)

2. sudo ufw status => inactive 확인한다. 

3. /etc/nginx/sites-available/default 에  해당 도메인 잘 입력했는지 확인

4. 서브도메인EC2의 public ip가 잘 입력되어있는지 확인

5. nginx 실행중인지 확인한다. => sudo systemctl status nginx

 

경험상 설정된 방화벽 관련 포트가 허용이 되지 않았거나 public ip 혹은 도메인 타이핑에 문제가 있었을 가능성이 높다.

잘 확인한다.

 

HTTPS 성공화면

 

 

 

HTTPS 성공화면(2)

 

 

redirect 설정 따로 안해주었는데 80번 포트로 보내도 443으로 간다.

 /etc/nginx/sites-available/default 확인해보니 마지막 부분이 managed by Certbot 부분으로

자동적으로 추가된 것을 볼 수 있다.

 

 

 

 

host 가 즉 클라이언트가 요청하는 도메인이 api.nogresume.com이면 301 리다이렉션을 통해서 https://로 전환시킨다는 코드가 적혀있다.

따라서 별도의 코드를 적지 않아도 redirection이 구성되었다.

https://king-ja.tistory.com/104
 
 

python코드를 aws ec2에 git clone으로 받아서 실행

 

 


 
원격 Git 저장소를 로컬에 복제하는 작업을 Git에서는 클론(clone)이라고 부른다. 
원격 서버에 있는 저장소의 모든 파일, 폴더, 커밋 내역 등을 로컬로 가져와서 Git 프로젝트 작업을 시작할 수 있게 한다.
 Git 저장소를 복사하는 명령어로, 원격에 있는 Git 저장소를 로컬 환경으로 다운로드한다

 

 

HTTPS 와 SSH 프로토콜  를 쓸 수 있다.

 

Public은 상관없지만 Private 프로젝트라면

1. HTTPS 프로토콜로 저장소를 복제하려면 GitHub 아이디와 패스워드를 입력해야한다.

 

2. SSH 프로토콜을 사용하면 SSH 키가 사용자 인증 역할을 기본적으로 포함하고 있기 때문에

GitHub에 대한 추가 인증 없이도 저장소를 클론할 수 있다.

프라이빗 저장소 작업이 많다면 SSH 키 방식이 더 편리하다.

 

사용자는 개인키로 SSH에 접속

접속하려는 SSH 서버에 요청받은 개인키와 매칭되는 등록된 공개키가 있는지 확인한다.

 

/*

개인키는 다른 사람에게 노출되어서는 안 된다.

내가 공개키를 등록해놓은 SSH 서버나 Git 서버에 접속할 수 있기 때문이다.

*/

 

git clone git@github.com:~/portfolio-back.git

 

 

SSH키가 제대로 설정되지 않아서 뜨는 오류 메세지이다.

cd ~/.ssh

ls

 

 id_rsa id_rsa.pub 파일쌍이 있는지 확인

 

 

ssh -keygenn -t rsa -b 4096 -C "이메일주소"

 

본인은 RSA 유형으로 SSH 키를 만들었다.

 

개인키는 id_rsa

공개키는 id_rsa.pub 에 저장이 된다.

이제 cat 명령어를 이용해서 id_rsa(공개키)를  github 계정에 등록한다.

 

Settings - SSH ad GPG keys - new ssh key - add ssh key - paste 하면 완료

 

 

 

 

git clone git@github.com:~~.git 성공

 

https://www.lainyzine.com/ko/article/creating-ssh-key-for-github/

 

 

Port forwarding ( 80 - > 443 - > 5050)

 

 

/etc/nginx/sites-available/default 에서 

 

server_name과 location의 proxy_pass를 지정해주어 해당 sever와 포트를 연결해줄 수 있다.

sever name은 이미 api.nogresume.com 으로 지정되어 있으니 5050포트로 연결 시켜 주면 된다.

5050 포트로  포트포워딩을시켜주었다.

 

 

listen 80은 포트 80에 대한 설정이고 location / 는 URL이 ‘/’가 포함된 경로에 대한 설정을 의미

 

/etc/nginx/sites-available/경로의 파일들은 실제로 활성화되지 않았지만 사용 가능한 설정 파일들이다.
/etc/nginx/sites-available/경로에 있는 default파일을 수정하고 저장하였다면

자동으로 /etc/nginx/sites-enabled/경로에 있는 default파일에 수정사항이 저장된다.

 

만일 실수로 해당 파일을 삭제하거나 수정사항이 저장이 되지 않았다면

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

 

위의 명령어로 심볼릭 링크(바로가기)를 만들 수 있다.

 

readlink /etc/nginx/sites-enabled/default

 

readlink는 해당 심볼릭 링크가 가리키는 실제 파일의 경로를 보여준다.

 

https://velog.io/@hsg5533/Ubuntu-NginX%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%84%9C%EB%B2%84%EB%A5%BC-%EC%97%B4%EC%96%B4%EB%B3%B4%EC%9E%90

https://velog.io/@fermion/Nginx%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9%EC%9D%84-%ED%95%B4%EB%B3%B4%EC%9E%90

https://losskatsu.github.io/it-infra/nginx-port-forwarding/#2-1-%EC%88%98%EC%A0%95%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%ED%8C%8C%EC%9D%BC

https://zionh.tistory.com/20

https://velog.io/@brgndy/Nginx%EB%A1%9C-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9-%EB%A6%AC%EB%B2%84%EC%8A%A4-%ED%94%84%EB%A1%9D%EC%8B%9C

 

웹서버와 WAS 그리고 리버스 프록시

 

웹 서버란

웹 브라우저와 같은 클라이언트로 부터 HTTP 요청을 받고, HTML 문서와 같은 웹 페이지를 반환하는 컴퓨터 프로그램

정적인 데이터를 처리한다.

여기서 쓰이는 NGINX는 Apache와 달리 비동기 기반 구조라 더 적은 리소스를 사용해서 요청을 처리할 수 있다.

 

WAS는 동적 데이터를 처리하는 서버이다. 즉 DB와 연결되어 데이터를 주고 받는다.

대표적으로 Tomcaf이 있다.

웹사이트 주소를 보다보면 html이 아닌 http://~/abc.jsp 라는 주소를 볼 때가 있는데 이러한 JSP(Java Server Page) 같은 sever side script를 처리하는 프로그램이다. 

Java로 만들어진 프로그램을 웹서버에서 돌려서 결과값을 클라이언트로 돌려준다.

 

 

 

/*

WAS는 언어를 실행시켜 동적 데이터를 처리하고 응답값을 받아오기 위해서 쓰는 프로그램이다.

백엔드라는 것은 언어를 말하는 것이 아니라 사용자의 눈에 보이는 UI 즉 front단을 넘어서면 back이다. 

언어는 응답값을 잘 받아오게 하기 위해 도와주는 도구이다. 위 그림에서는 front를 넘어선 nginx부터가 back이다. 

*/

 

 

리버스 프록시는 웹서버 앞에 놓여 있다. 적절한 백엔드 서버에게 전달하는 역할을 수행한다. 사용 목적은 다음과 같다.

 

1. 로드밸런싱 : 여러 개의 서버 앞에 리버스 프록시를 두어 과부하를 막는다.

2. 보안 : 본래 서버의 IP 주소를 노출시킬 필요가 없다. 대신 CDN과 같은 리버스 프록시 서버는 공격 대상이 될 수 있다.

3. 캐시 데이터 : 리버스 프록시 서버에 캐싱되어 있는 데이터를 사용할 경우에는 더 빠른 성능을 보여줄수 있다.

4. SSL 암호화 : 들어오는 요청을 모두 복호화하고 나가는 응답을 암호화해준다

 

/*

포워드 프록시 서버는  클라이언트 앞에 놓여 있다.

기관에 속한 유저가 특정 컨텐츠에 접근하는 것을 방지하는데 사용

*/

 

https://losskatsu.github.io/it-infra/reverse-proxy/#2-%ED%8F%AC%EC%9B%8C%EB%93%9C-%ED%94%84%EB%A1%9D%EC%8B%9Cforward-%EC%84%9C%EB%B2%84%EB%9E%80

 

 

Open AI api 응답받기 및 트러블슈팅

 

pip install openai 시 오류 코드

 

 

error: externally-managed-environment

 리눅스에 내장된 파이썬(시스템 파이썬)에 패키지 설치를 하면 위험할 수 있다.

OS 구동에 사용되는 패키지들에 영향을 줄 수 있고 OS 에러를 초래할 수 있다.

이런 상황을 방지하기 위해 패키지를 막아주는 기능(externally managed) 


× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.12/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.

 

 

이게 안되어서 apt 를 이용하였다.

 

sudo apt install python3-openai

sudo apt install python3-dotenv

sudo apt install python3-flask

sudo apt install python3-flask-cors

 

그런데..

 

 

Open AI API 는 잘 받아오지만 계속 업로드된 파일이 없다는 반응이 온다.

로컬에서 테스트할 때는 api를 잘 받아온다.

왜 웹에서는 첨부파일을 인식하지 못할까 계속 생각했다.

 

분명 답이 오는 것을 보면 env 파일 내에 있는 API_KEY 자체는 잘 받아오고 있는 것 같은데

ASSISTANT_ID 는 받아오지 못하는 것처럼 보였다.

 

로그를 보면

 

127.0.0.1 - - [13/Oct/2024 07:07:03] "OPTIONS /chat HTTP/1.0" 200 -
ThreadMessage(id='msg_~~~', assistant_id='asst_(my_assistant_id_code)', content=[MessageContentText(text=Text(annotations=[], value='죄송합니다. 이전에 업로드된 파일이 없어서 자세한 정보를 제공해드릴 수가 없네요. 자격증에 대해 특별히 궁금하신 부분이 있거나 다른 정보가 필요하신 경우 알려주세요. 부연 설명이나 추가 질문을 통해 도움을 드릴 수 있도록 최선을 다하겠습니다.'), type='text')], created_at=1728803226, file_ids=[], metadata={}, object='thread.message', role='assistant', run_id='run_~~~', thread_id='thread_~~~')
ThreadMessage(id='msg_~~~', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='자격증'), type='text')], created_at=1728803223, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_~~~')

분명 assistant_id 도 잘 받아오는데 어떤 것이 문제인지 모르겠다.

env에서 받아오지 말고 소스코드 안에 직접 넣어보았지만

결과는 똑같았다.

 

일단 응답값을 제대로 받고 싶었다.

ASSISTANT_ID만 못받아오는 것이라면  그냥 소스코드 내에서 ASSISTANT_ID를 생성시켜버리자는 생각을 했다.

 

그래서 assistant create 하고 file_id 보는 법 찾아서

소스코드 안에 넣어주었다.

 

file_ids=[
    "file-your_file",
]


    assistant = client.beta.assistants.create(
    instructions="You are a chatbot that provides information about my resume.",
    name="Job seeker",
    tools=[{"type": "retrieval"}],
    file_ids=file_ids,
    model="gpt-3.5-turbo",
)

 

 

  File "/usr/lib/python3/dist-packages/openai/_base_client.py", line 980, in _request
    raise self._make_status_error_from_response(err.response) from None
openai.BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: 'file_search'. Supported values are: 'code_interpreter', 'function', and 'retrieval'.", 'type': 'invalid_request_error', 'param': 'tools[0].type', 'code': 'invalid_value'}}

그러다가 file_search가 아닌 retrieval 만 지원한다는 문구를 보았다.

이 때 버전문제 있을 수도 있다는 것을 알게되었다.

 

 

 

일단 retrieval 로 바꿔서 실행해보니 된다...

 

 

 

 

확인해보았더니 버전이 1.12.0 이다.

apt는 update 되지 않은 상태로 보인다.

 

그래서 패키지 설치 권한 푸는 문장을 알아내어

$ python3 -m pip config set global.break-system-packages true

 

pip install --upgrade pip
pip install --upgrade openai

 

pip  로 설치하였더니 

 

pip show openai

 

최신 버전(1.51.2)으로 업데이트가 된 것을 볼 수 있었다.

 

 

 

 

수정한 코드가 아닌 .env로 불러오는 원래의 코드로 돌려봤더니

정상적으로 답이 온다.

 

https://blog.naver.com/kim1417/223493704161

https://blog.naver.com/b14nc4/223418048502

 

 

nohup

 

ssh를 꺼도 python이 백그라운드에서 계속 구동되게 하는 방법이 있다.

 

 

nohup을 통해 터미널을 닫아도 프로세스가 계속 실행되도록 방지다. &를 통해 프로세스를 백그라운드에서 실행한다.

 

nohup python3 back.py > flask_output.log 2>&1 &

 

로그 파일을 사용해 애플리케이션 출력을 저장한다.

로그 파일로 출력을 리다이렉트시키는 방법이다.

 

> flask_output.log  : 표준 출력을 flask_output.log 파일로 저장

2>&1 &  : 표준 에러를 표준 출력에 리다이렉트하여 모든 출력이 하나의 파일에 저장되도록 한다.

 

 

프로세스 실행 여부 확인

ps aux | grep back.py

 

돌아가고 있는 프로세스에 대하여 kill 명령어로 PID(process ID) number 입력하면 프로세스가 종료된다.

 

 

========================================================================
 참고
 
port forwarding
https://velog.io/@hsg5533/Ubuntu-NginX%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%84%9C%EB%B2%84%EB%A5%BC-%EC%97%B4%EC%96%B4%EB%B3%B4%EC%9E%90
https://wildeveloperetrain.tistory.com/237
https://zionh.tistory.com/20
https://velog.io/@brgndy/Nginx%EB%A1%9C-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9-%EB%A6%AC%EB%B2%84%EC%8A%A4-%ED%94%84%EB%A1%9D%EC%8B%9C
https://ekdms5566.tistory.com/29
https://velog.io/@fermion/Nginx%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9%EC%9D%84-%ED%95%B4%EB%B3%B4%EC%9E%90
https://losskatsu.github.io/it-infra/nginx-port-forwarding/#2-1-%EC%88%98%EC%A0%95%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%ED%8C%8C%EC%9D%BC
 
 
 
git clone
https://owening2.tistory.com/7
https://choiiis.github.io/git/how-to-clone-project/
https://www.lainyzine.com/ko/article/git-clone-command/
 
 
 
https://developer-jinnie.tistory.com/80
https://mark340.tistory.com/53
=
https://king-ja.tistory.com/100
https://8ugust-dev.tistory.com/17
https://soda-dev.tistory.com/72
 
https://velog.io/@yaejin9503/%EA%B0%80%EB%B9%84%EC%95%84%EC%97%90%EC%84%9C-domain%EC%9D%84-Vercel%EC%9D%98-%EB%82%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EC%99%80-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0

https://teddylee777.github.io/openai/openai-assistant-tutorial/#%EB%8F%84%EA%B5%AC2-retrieval%EA%B2%80%EC%83%89