일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 스타트업
- 엣지컴퓨팅
- uuid-ossp
- SFINAE
- psql extension
- 스플릿키보드
- 도커
- Cloud Spanner
- 쿠버네티스
- 이노베이션아카데미
- 42서울
- 42seoul
- c++
- GraphQL
- 프라이빗클라우드
- 어셈블리어
- adminbro
- 창업
- 정렬
- mistel키보드
- enable_if
- 자료구조
- schema first
- 동료학습
- 파이썬
- raycasting
- 레이캐스팅
- 부동소수점
- 텍스트북
- 어셈블리
- Today
- Total
written by yechoi
[gunicorn] 서비스 등록 - 111: Connection Refused, 13: Permission Failed 해결 본문
[gunicorn] 서비스 등록 - 111: Connection Refused, 13: Permission Failed 해결
yechoi 2021. 3. 14. 22:40gunicorn을 사용하는 데는 두가지 방식이 있다.
하나는 포트를 이용해 서버를 띄우는 것이다. gunicorn --bind 0:8000 config.wsgi:application
와 같은 커맨드가 그러한 역할을 한다.
두번째는 소켓을 사용하는 것이다. unix 계열 시스템에선 포트로 서비스 하는 것보다 유니스 소켓을 사용하는 게 빠르고 효율적이라고 한다. gunicorn --bind unix:/tmp/gunicorn.sock config.wsgi:application
와 같은 커맨드로 소켓을 사용할 수 있다.
나는 소켓을 사용하는 방식을 택했다. 자동적으로 gunicorn을 실행하기 위해선 앞선 명령어를 매번 쓰는 것보단, gunicorn을 서비스로 등록하는 게 좋다.
gunicorn 서비스로 등록하기
서비스 파일 만들기
서비스에 등록하기 위해선 아래와 같은 경로에 .service
파일을 만든다. (확장자 앞의 파일 이름은 사이트 이름이라든지 프로젝트 이름으로 해도 되지만, 나는 단순하게 gunicorn.service로 이름 지어줬다.)
cat /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=humansof42
Group=www-data
WorkingDirectory=/home/humansof42/h42
ExecStart=/home/humansof42/.local/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
config.wsgi:application
Environment=H42_SECRET_KEY=abcdedf
위의 파일은 gunicorn.socket 파일을 참조해 소켓을 만든다. .socket
파일은 다음과 같이 만든다. ListenStream은 듣고 있는 소켓의 위치를 지정한다. (gunicorn.socket도 마찬가지로 이름을 mysite.socket 등등으로 지어도 괜찮다. 앞선 .socket 파일에서 잘만 참조하고 있다면.)
cat /etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
서비스 실행하고 등록하기
sudo systemctl start gunicorn.service
서비스 재실행하기
sudo systemctl restart gunicorn
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
111: Connection Refused
나는 이과정에서 여러 에러를 겪었는데, 111:Connection Refused
에러의 경우 gunicorn.service 파일에서 필요한 변수들을 제대로 세팅해주지 않았기 때문이다. 남들의 gunicorn.service 파일을 복붙해줬던 것이 원인. 구체적으로 아래의 두가지 경우가 문제였다.
- User 이름을 root, ubuntu 등 내 User가 아닌 명칭을 사용했던 것
- django에서 필요로 하는 SECRET_KEY 환경변수를 세팅해주지 않은 것
참고로 환경변수를 세팅할 때는 Environment=H42_SECRET_KEY=abcdedf
이런식으로 하드 코딩할 수도 있지만, 원하는 위치에 환경변수용 파일을 따로 만들어서 인클루드 해줄 수도 있다. 다음과 같은 식으로 설정하면, 비공개해야 할 환경변수를 공개해버리는 일을 막을 수 있다.
cat /home/humansof42/h42/config/h42.env
H42_SECRET_KEY=abcdef
cat /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=humansof42
Group=www-data
WorkingDirectory=/home/humansof42/h42
ExecStart=/home/humansof42/.local/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
config.wsgi:application
EnvironmentFile=/home/humansof42/h42/config/h42.env
13: Permission Denied
앞선 문제를 해결하고 마주한 에러는 13: Permission Denied
. 이건 nginx에 소켓의 위치를 제대로 지정해주지 않았기 때문이다.
server {
listen 80;
server_name 34.64.112.133;
charset utf-8;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /root/humansof42/h42;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
proxy_pass에 우리가 만들어놓은 소켓을 넣어둬야 한다. 이전엔 proxy_pass http://unix:/etc/systemd/system/gunicorn.socket;
으로 엉뚱하게 소켓 대신 소켓 설정파일을 넣어뒀었다.
참고: https://wikidocs.net/76904