몇 주 전 시작한 삽질이 이제까지 계속될 줄은 몰랐다.
처음에는 macOS에 올리려고 거의 몇 주 내내 삽질을 했는데 도저히 안돼서 ubuntu로 돌렸다.
그래도 macOS에서 삽질하면서 많이 배워서인지 ubuntu에서는 금방 해냈다.!
(mac에서 성공하신 분들 정말 대단... b)

감격스러움에 눈물이 앞을 가리지만.. 잊어버리기 전에 얼른 적어둬야지


개발 환경

Ubuntu 18.04 LTS
Nginx 1.14.0
Django 2.2.4

 

  • 이 포스트는 이미 어느 정도 만들어져 개발 서버로는 동작이 되는 Django 프로젝트가 존재한다는 상황을 가정한다.
  • virtualenv를 이용한 가상 환경에서의 작업을 전제로 한다.

 

여기서 사용할 Django + uWSGI + Nginx 간의 관계는 다음과 같다.

Client <-> Nginx <-> uWSGI <-> Django

: Nginx가 Client들로부터 비동기식으로 요청을 받아 이를 uWSGI한테 넘겨주면, uWSGI는 이를 Django가 이해할 수 있는 형태로 바꿔 Django에게 요청을 넘겨주고 그에 대한 응답이 다시 위 흐름대로 Client에게 돌아가는 방식

이러한 구조를 통해 내가 생각한 구현 흐름은 이렇다.
Django로 서비스를 만들고 이를 uWSGI와 연결하고 실행하면 특정 포트로 이 웹서버에 접근할 수 있을 것이다. (socket 설정 전)
그 후 Nginx와는 소켓을 이용하여 통신하도록 할 것이기 때문에 uwsgi와 nginx 사이에서는 소켓 파일을 공유하도록 하면 된다.

이를 바탕으로 작업한 내용은 다음과 같다.

 

현재 포트 포워드 상태

1. 외부 :8880 -> 내부 :8080
2. 외부 :8888 -> 내부: 8000

최종 연결은 1번 포트에 할 건데,
중간에 테스트용으로 1번과 2번을 암거나 가져다 쓸 수 있으니 양해 부탁..

 

Django

1) Directory 구조

repo
    - db.sqlite3
    - manage.py
    - app
        - migrations
        - static
        - templates
        - __init__.py
        - admin.py
        - apps.py
        - models.py
        - urls.py
        - views.py
    - conf
        - __init__.py
        - asgi.py
        - settings.py
        - urls.py
        - wsgi.py

2) settings.py

ALLOWED_HOSTS = ['*']
STATIC_URL = '/static/'

 

여기까지 한 것을 아래 명령어를 이용하여 실행 후 접속하면 다음과 같이 원하던 대로 잘 접속되는 것을 볼 수 있다.

$ python3 manage.py runserver 0:8080

 

이 템플릿 어디서 가져왔는데 기억이 안난다... Thank you so much for making good design template

 

uWSGI

1) /etc/uwsgi/django.ini

[uwsgi]
home = /path/to/venvFolder/venv
chdir = /path/to/project/repo
module = conf.wsgi:application

http = :8000

master = True
processes = 5

logto = /var/log/uwsgi/uwsgi.log

** Nginx와 연결하기 전에 uwsgi와 django가 연결이 되고 있는지를 확인해보기 위해 우선 http 방식으로 설정하였다.
Nginx와 연결할 때에는 socket으로 바꿀 예정

아래의 명령어로 uwsgi를 실행시킨 후 8000번 내부 포트에 대응하는 8888번 외부 포트로 접속하여 진행상황을 확인한다.

$ uwsgi --ini /etc/uwsgi/django.ini
[uWSGI] getting INI configuration from /etc/uwsgi/django.ini
*** Starting uWSGI 2.0.19.1 (64bit) on [Sat Sep 11 05:16:26 2021] ***
compiled with version: 7.5.0 on 11 September 2021 00:27:30
os: Linux-4.4.0-1128-aws #142-Ubuntu SMP Fri Apr 16 12:42:33 UTC 2021
nodename: goorm
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 2
current working directory: /home
detected binary path: /usr/local/bin/uwsgi
chdir() to /home/ssg
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address /path/to/socketFile/uwsgi.sock fd 3
setuid() to 33
Python version: 3.7.4 (default, Nov  4 2020, 10:17:35)  [GCC 7.4.0]
PEP 405 virtualenv detected: /path/to/venvFolder
Set PythonHome to /path/to/venvFolder
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x55eb1a8d8020
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 437520 bytes (427 KB) for 5 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x55eb1a8d8020 pid: 528 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 528)
spawned uWSGI worker 1 (pid: 531, cores: 1)
spawned uWSGI worker 2 (pid: 532, cores: 1)
spawned uWSGI worker 3 (pid: 533, cores: 1)
spawned uWSGI worker 4 (pid: 534, cores: 1)
spawned uWSGI worker 5 (pid: 535, cores: 1)

 

django 프로젝트는 잘 찾는 것 같은데, 왜인지 static 파일을 하나도 찾지 못하고 있는 것 같다. 일단 django 프로젝트만이라도 Nginx까지 연결해보자 싶어서 계속 진행했다.

Nginx와 연결할 때에는 socket을 이용하고자 아래와 같이 django.ini를 수정하였다.

[uwsgi]
base = /.../WEB
home = %(base)/venv
chdir = %(base)/repo
module = conf.wsgi:application

socket = %(base)/run/uwsgi.sock
chown-socket = www-data:www-data;
chmod-socket = 660
vacuum = True

master = True
processes = 5

logto = /var/log/uwsgi/uwsgi.log

여기서 chown과 chmod 설정을 해주지 않으면 추후에 client의 요청이 nginx를 통해 처리될 때 권한 문제로 .sock파일을 사용하지 못하는 에러가 발생한다. www-data는 nginx 설정에 적힌 user 이름이다. (뭘로 하든 nginx user와 같은 사용자로 파일 권한 설정해야 함)

(nginx와 uwsgi가 .sock파일을 이용하여 통신할 것이고 이 때 .sock파일이 매개가 되는 상황.)

 

Nginx

1) /etc/nginx/nginx.conf

user www-data;
http {
	include	/etc/nginx/sites-enabled/*;
    include	mime.types;
    default_type application/octet-stream;    
    ...
}

앞서 나왔던 대로 user를 www-data로 한다. (근데 이건 사실 default로 적혀있을 거라서 그냥 내버려 두면 된다.)
include로 sites-enabled 폴더 내용 가져오는 것도 기본적으로 적혀있을 내용이긴 하다. 별 차이 없으면 패스
(+여기서 삽질했던 거: nginx.conf 파일 안에는 server 블록이 필요 없다. server 블록은 sites-available/project.conf에 적으면 됨...)

2) /etc/nginx/sites-available/django.conf

upstream django {
	server unix:/path/to/socketFolder/uwsgi.sock;
}

server {
	listen 8080;
    server_name [local ip addr];
    
    charset utf-8;
    root /path/to/project/repo;
    
    location / {
    	include /etc/nginx/uwsgi_params;
        uwsgi_pass django;
    }
    
    location /static/ {
    	alias /path/to/project/app/static/;
    }
}

(+ static 경로 마지막에 / 를 꼭 붙여주자)

sites-available에 django.conf 파일을 작성했으면 이를 sites-enabled 폴더에 링크 걸어주는 것까지 해야 한다.

$ sudo ln -sf /etc/nginx/sites-available/django.conf  /etc/nginx/sites-enabled/

여기까지 한 뒤 uwsgi와 nginx를 실행시킨다.

$ service nginx start
$ uwsgi --ini /etc/uwsgi/django.ini

/etc/nginx/sites-available/django.conf 에서 port를 8080번으로 설정했기 때문에 이에 대응하는 8880번 포트로 접속하면 static 파일까지 다시 성공적으로 나온다!


참고

 

+ Recent posts