2025. 2. 18. 13:06ㆍ프로젝트
이 전 글들이 궁금하다면 ?
0. 사이트를 만드려는 이유
https://hsjoo126.tistory.com/80
1-1. 프로젝트 가능성 보기
https://hsjoo126.tistory.com/81
pandas 와 jupyter 이용해서 테스트해보기
https://hsjoo126.tistory.com/82
1-2. 기획 단계 - 디자인, 와이어 프레임, ERD 등
https://hsjoo126.tistory.com/83
2. 개발 단계 - 계획짜기, 구현해보기
https://hsjoo126.tistory.com/84
2-1. 개발 단계 - 배당지불일, 시장별 티커리스트 구하기
https://hsjoo126.tistory.com/85
2-2. 개발 단계 - 코드 정리
https://hsjoo126.tistory.com/86
2-3. 개발 단계 - 사이트에 적용하기(장고)
https://hsjoo126.tistory.com/87
2-4. 개발 단계 - 사이트 로딩 속도 줄이기
https://hsjoo126.tistory.com/88
2-5. 개발 단계 - 주식별 동적인 페이지 만들기
https://hsjoo126.tistory.com/89
2-6. 개발 단계 - 티커리스트 db에 저장해서 불러오기, 해결하지 못한 트러블슈팅
https://hsjoo126.tistory.com/91
2-7. 429에러를 해결하기위한 노력, 로직 대폭 수정하기 엉엉... 그리고 해냄...
https://hsjoo126.tistory.com/92
2-8. cron.py , view.py 작성하기, 디테일 잡기
https://hsjoo126.tistory.com/93
2-9. 개발 단계 - 주가그래프그리기(matplotlib), Non-GUI 백엔드? Agg가 뭐야!, 상세페이지 수정, 페이지네이션 등
https://hsjoo126.tistory.com/94
2-10. 개발 단계 - 배포를 위한 준비단계!(pip list 정리, 도커 관련, postgresql 접속하기, 트러블 슈팅 등)
https://hsjoo126.tistory.com/96
3. 디자인 - 잠깐 쉬어가자! 그런김에 디자인~!
https://hsjoo126.tistory.com/90
4-1. 배포 단계 - nginx작성 ec2 배포, http 설정
https://hsjoo126.tistory.com/97
4-2. 배포 단계 - 로컬에 있는 DB(postgresql) 백업 후 EC2에 복원하기 (docker 사용함)
https://hsjoo126.tistory.com/98
배포를 오랜만에 하다보니.. 생각나는 대로 배포를 진행했다
그래서 순서가 뒤죽박죽일 수 있다!
대부분 '아 맞다 ... 나 이거 안 하지 않았나 ?' -> 급하게 함
그래서 원래는 블로그 글과 동시에 쓰면서 프로젝트를 진행하는데
이번에는 모든 과정을 다 끝내고! 블로그 글을 쓴다
TMI 라면 TMI 지만 어쨌든 ~
오늘은 배포 마무리를 진행해보도록 하겠다! 정리 시작~
오늘의 목차
➡️ 1차 nginx
➡️ 도메인 연결
➡️ https : ssl 인증
➡️ 2차 nginx
➡️ collectstatic (어라... css 왜 안되지 ? 앗차차)
➡️ wsgi : gunicorn (어라 ... 나 뭐 까먹었는데 ? 앗차차)
➡️ 1차 nginx
nginx 관련된 건 다음과 같이 작성했다.
설명은 주석을 참고하자
#docker-compose.yml
nginx:
image: nginx:latest #제일 최신 버전 사용
volumes:
- /etc/letsencrypt:/etc/letsencrypt #ssl인증서 관련
- ./nginx.conf:/etc/nginx/conf.d/default.conf #nginx.conf 파일을 컨테이너 내부의 Nginx 기본 설정 파일로 덮어씀
ports:
- "80:80" #http요청 받을 수 있게
depends_on:
- web #web컨테이너 먼저 실행하고 nginx 실행할 수 있게
#nginx.conf
server {
listen 80; #80번 포트로 들어온 요청만 허용
server_name 서버ip주소;
location / { # / 주소로 들어올 경우
proxy_pass http://web:8000; #web컨테이너로 전달 & 8000포트로 요청
proxy_set_header Host $host; #클라이언트가 요청한 원래 호스트 정보를 유지하도록 설정.
proxy_set_header X-Real-IP $remote_addr; #클라이언트의 실제 IP 주소를 Django에 전달. 기본적으로 프록시를 거치면 클라이언트의 IP가 프록시 IP로 바뀌는데, 이를 방지함.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #클라이언트가 여러 개의 프록시를 거칠 경우, 전체 IP 경로를 전달.
proxy_set_header X-Forwarded-Proto $scheme; #클라이언트가 요청한 프로토콜(HTTP 또는 HTTPS)을 Django에 전달.
}
}
➡️ 도메인 연결
도메인은 가비아를 통해 연결했다
사실 저번 프로젝트 때 썼던 도메인을 그대로 갖다 쓰는 거라
자세한 설명은 건너뛰겠다 ... (기대했다면 ㅈㅅㅈㅅ)
➡️ https : ssl 인증 & ➡️ 2차 nginx
sudo apt update
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
이런식으로 해서 인증서 발급 받고
nginx 를 수정해주었음!
server {
listen 80;
server_name hsjoo.site;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name hsjoo.site;
ssl_certificate /etc/letsencrypt/live/hsjoo.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hsjoo.site/privkey.pem;
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
그리고 도커에서도 https인 443 포트를 추가해줌
nginx:
image: nginx:latest
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- static_volume:/var/www/static
ports:
- "80:80"
- "443:443" #https
depends_on:
- web
사실 우여곡절이 많았지만 ..... 해결하느라 블로그에 담을 시간이 없었음 ㅜ
아무튼.. nginx 까지 잘 설정하고 사이트는 매우매우 잘 돌아갔음!
➡️ collectstatic (어라... css 왜 안되지 ? 앗차차)
그리고 사이트를 보는데 css 가 다 날라가버린 것임!
ㅋㅋㅋㅋㅋㅋㅋㅋ 알고보니 ..... 내가 collectstatic을 안 해줘서 그런 거였음 ...
collectstatic 이란?(도와줘요 gpt!)
collectstatic은 Django에서 정적 파일(static files)을 모아주는 명령어입니다.
Django 프로젝트에서는 CSS, JavaScript, 이미지 파일과 같은 정적 파일을 관리해야 하는데,
개발 중에는 각 앱의 static/ 디렉토리에서 이 파일들을 사용합니다.
하지만 운영 환경(Production)에서는 성능 최적화와 보안 문제로
이러한 정적 파일들을 별도의 디렉토리(일반적으로 STATIC_ROOT)에 모아
웹 서버(Nginx, Apache 등)를 통해 서빙하는 것이 일반적입니다.
collectstatic의 역할
프로젝트의 모든 앱에 있는 static/ 디렉토리와 STATICFILES_DIRS에 정의된 경로에서 정적 파일을 검색합니다.
검색한 모든 정적 파일을 STATIC_ROOT 디렉토리로 복사하거나 링크를 생성합니다.
이렇게 모아진 파일들은 운영 환경에서 정적 파일을 효율적으로 제공하기 위해 사용됩니다.
그렇다고 한다~
그래서 settings.py에 static_root를 추가하고
nginx 한테도 위치를 알려주었다.
server {
listen 443 ssl;
server_name hsjoo.site;
ssl_certificate /etc/letsencrypt/live/hsjoo.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hsjoo.site/privkey.pem;
location /static/ {
alias /var/www/static/; #위치 알려줌
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
도커에도 볼륨을 추가해서 도커가 껐다 켜져도 static 데이터가 안 날라가게끔 했다
#docker-compose.yml
web:
build: .
command: >
sh -c "python manage.py migrate &&
python manage.py crontab add &&
service cron start &&
python manage.py runserver 0.0.0.0:8000"
volumes:
- .:/app
- static_volume:/var/www/static #삭제 안 되게 볼륨 추가
ports:
- "8000:8000"
depends_on:
- redis
- db
nginx:
image: nginx:latest
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- static_volume:/var/www/static #삭제 안되게 볼륨 추가
ports:
- "80:80"
- "443:443"
depends_on:
- web
volumes:
postgres-data:
static_volume: #web과 nginx가 공유하는 외부 볼륨 추가
이렇게 다 적었으면 도커 한 번 재시작하고
web 컨테이너로 가서 명령어를 입력해주면 됨!
#web 컨테이너 접속
sudo docker-compose exec web bash
#명령어 입력
python manage.py collectstatic
이렇게 하고 홈페이지 들어가면 ? css 매우 잘뜸 휴 -
➡️ wsgi : gunicorn (어라 ... 나 뭐 까먹었는데 ? 앗차차)
위에까지 마친 후에 음.... 나 또 뭐 까먹은 거 없나?
하면서 둘러보는데 생각해보니 ㅋㅋㅋㅋㅋㅋ wsgi 설정을 안 해놨음...
..
원랜 nginx전에 했어야했는데 ....
그냥 .... 까먹어버림 앗차차 -
ㅋㅋㅋㅋㅋㅋㅋ ㅠㅠ
이제라도 생각났으니 다행이란 마음으로 ... wsgi 설정을 해줌
wsgi가 뭐에요 ? ⬇️⬇️⬇️⬇️⬇️
https://hsjoo126.tistory.com/67
ASGI가 뭐에요? 에서 시작된... WSGI, CGI... 동기와 비동기
장고에서 채팅을 구현하다가, ASGI 라는 말이 나오길래 엥? 저게 뭐지..? 에서 시작된 글이다 ! 그냥 공식 문서 보고 이해가 되었다면 좋았을텐데... 안타깝게도 그렇지 않았음.ASGI 정리글 이라고
hsjoo126.tistory.com
wsgi인 gunicorn을 사용했고 먼저 docker file을 변경해줌
# Django Dockerfile
FROM python:3.10.11
# 프로젝트 작업 디렉터리
WORKDIR /app
# 프로젝트 요구사항 파일 복사 및 설치
COPY requirements.txt /app/
RUN apt-get update && apt-get install -y python3-pip cron fonts-nanum && \
pip install --no-cache-dir -r requirements.txt && \
pip install gunicorn #gunicorn 설치
# 프로젝트 파일 복사
COPY . /app/
# 포트
EXPOSE 8000
# 장고 서버 실행
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "dividend_stock.wsgi:application"] #실행명령어도 gunicorn 관련으로 변경
web 컨테이너에서도 wsgi 가 실행할 수 있도록 바꿔줌
web:
build: .
command: >
sh -c "python manage.py migrate &&
python manage.py crontab add &&
service cron start &&
gunicorn dividend_stock.wsgi:application --bind 0.0.0.0:8000" #wsgi 실행할 수 있도록 변경
volumes:
- .:/app
- static_volume:/var/www/static
ports:
- "8000:8000"
depends_on:
- redis
- db
이미 장고에 wsgi.py 가 존재하고 있기 때문에 이렇게 바꾸는 것만으로도
사이트는 문제없이 잘 돌아갔음
(밑에는 gpt 슨생님 설명임! 참고!)
Django 프로젝트에는 기본적으로 wsgi.py 파일이 포함되어 있는데,
이 파일이 WSGI 서버(Gunicorn 등)와 Django 애플리케이션 간의 연결을 제공합니다.
wsgi.py의 역할:
project_name.wsgi:application은 Gunicorn이 Django 애플리케이션에 접근할 수 있는 진입점입니다.
WSGI 서버는 이 application 객체를 호출하여 Django와 통신합니다.
휴... 정리끝!!
기억을 되살려서 정리를 하다보니.. 빈틈이 많을 거라 예상 ,,, 되지만 어쩔 수 없지!
일단 배포까지 다 했다!
사실 실감 안 남 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
거의 마무리 한 거나 다름 없어서 깃허브나 사이트 공개하고 싶지만?
일단 주변 사람들한테 피드백 먼저 받고 블로그에도 공개하도록 하겠다!
다음 글은 ,,, 피드백 보충 or 새 기능 추가가 되지 않을까 ? ㅋㅋㅋㅋㅋㅋ
다음 글에서 봐요 여러분 안뇽!