웹사이트 검색

Rocky Linux 9에서 Postgres, Nginx 및 Gunicorn과 함께 Django를 설치하는 방법


이 페이지에서

  1. 전제 조건
  2. 1단계 - 방화벽 구성\n
  3. 2단계 - PostgreSQL 및 유틸리티 설치
  4. 3단계 - PostgreSQL 구성
  5. 4단계 - Django 설치
    1. pip를 사용하여 설치\n
    2. 개발 버전 설치

    1. nohup을 사용하여 영구 Django 서버 실행\n
    2. Gunicorn 설치

    Django는 동적 웹 사이트 및 애플리케이션을 개발하는 데 사용되는 Python 프레임워크입니다. MVC(Model-View-Controller) 아키텍처를 따릅니다. Django를 사용하면 대부분의 기본 작업이 Django에서 처리되므로 애플리케이션 개발 프로세스의 속도가 빨라집니다.

    이 튜토리얼에서는 Rocky Linux 9 서버에 Django 프레임워크를 설치하는 방법을 배웁니다. 또한 데모 프로젝트를 만들고 테스트합니다.

    전제 조건

    • A server running Rocky Linux 9.

    • A non-root user with sudo privileges.

    • A fully qualified domain name (FQDN) pointing to your server. For our purposes, we will use django.example.com as the domain name.

    • Make sure everything is updated.

      $ sudo dnf update
      
    • Install basic utility packages. Some of them may already be installed.

      $ sudo dnf install wget curl nano unzip yum-utils -y
      

    • SELinux가 비활성화되었습니다.\n

    1단계 - 방화벽 구성

    첫 번째 단계는 방화벽을 구성하는 것입니다. Rocky Linux는 Firewalld Firewall을 사용합니다. 방화벽 상태를 확인하십시오.

    $ sudo firewall-cmd --state
    running
    

    방화벽은 다른 영역에서 작동하며 공개 영역은 우리가 사용할 기본 영역입니다. 방화벽에서 활성화된 모든 서비스와 포트를 나열합니다.

    $ sudo firewall-cmd --permanent --list-services
    

    다음 출력이 표시되어야 합니다.

    cockpit dhcpv6-client ssh
    

    Django가 작동하려면 HTTP 및 HTTPS 포트가 필요합니다. 열어보세요.

    $ sudo firewall-cmd --add-service=http --permanent
    $ sudo firewall-cmd --add-service=https --permanent
    

    변경 사항을 적용하려면 방화벽을 다시 로드하십시오.

    $ sudo firewall-cmd --reload
    

    2단계 - PostgreSQL 및 유틸리티 설치

    Rocky Linux 9는 이전 버전의 PostgreSQL과 함께 제공됩니다. 튜토리얼을 위해 Postgres 14를 설치합니다.

    PostgreSQL용 리포지토리 RPM을 설치합니다.

    $ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
    

    PostgreSQL 14 서버를 설치합니다.

    $ sudo dnf install -y postgresql14-server postgresql14-contrib postgresql14-devel python3-psycopg2
    

    데이터베이스를 초기화합니다.

    $ sudo /usr/pgsql-14/bin/postgresql-14-setup initdb
    

    PostgreSQL 서비스를 활성화하고 시작합니다.

    $ sudo systemctl enable postgresql-14 --now
    

    서비스 상태를 확인합니다.

    $ sudo systemctl status postgresql-14
    ? postgresql-14.service - PostgreSQL 14 database server
         Loaded: loaded (/usr/lib/systemd/system/postgresql-14.service; enabled; vendor preset: disabled)
         Active: active (running) since Mon 2022-09-12 01:17:24 UTC; 2s ago
           Docs: https://www.postgresql.org/docs/14/static/
        Process: 87995 ExecStartPre=/usr/pgsql-14/bin/postgresql-14-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
       Main PID: 88000 (postmaster)
          Tasks: 8 (limit: 5915)
         Memory: 16.5M
            CPU: 60ms
         CGroup: /system.slice/postgresql-14.service
                 ??88000 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
                 ??88001 "postgres: logger "
                 ??88003 "postgres: checkpointer "
                 ??88004 "postgres: background writer "
                 ??88005 "postgres: walwriter "
                 ??88006 "postgres: autovacuum launcher "
                 ??88007 "postgres: stats collector "
                 ??88008 "postgres: logical replication launcher "
    
    Sep 12 01:17:24 board.example.com systemd[1]: Starting PostgreSQL 14 database server...
    

    Django가 작동하는 데 필요한 몇 가지 추가 유틸리티를 설치하겠습니다.

    $ sudo dnf install -y python3 python3-devel python3-pip gcc
    

    pg_config를 찾을 수 없다는 향후 오류를 해결하려면 PostgreSQL bin 폴더에 경로를 추가해야 합니다. 편집을 위해 .bashrc 파일을 엽니다.

    $ nano ~/.bashrc
    

    파일 끝에 다음 줄을 추가합니다.

    export PATH=$PATH:/usr/pgsql-14/bin	
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    3단계 - PostgreSQL 구성

    PostgreSQL 셸에 로그인합니다.

    $ sudo -i -u postgres psql
    

    Django용 새 데이터베이스를 만듭니다.

    postgres=# CREATE DATABASE djangoapp;
    

    강력한 암호로 새 데이터베이스 사용자를 생성합니다.

    postgres=# CREATE USER djangouser WITH ENCRYPTED PASSWORD 'dbpassword';
    

    사용자에게 데이터베이스를 사용할 수 있는 권한을 부여합니다.

    postgres=# GRANT ALL PRIVILEGES ON DATABASE djangoapp TO djangouser;
    

    Postgres 셸을 종료합니다.

    postgres=# \q
    

    4단계 - Django 설치

    Django를 설치하는 방법에는 여러 가지가 있습니다. 어떤 것이 가장 적합한지 결정하는 것은 개발 환경을 구성하려는 방법과 필요에 따라 다릅니다. 각 방법에는 고유한 장단점이 있습니다. 이 모든 방법을 살펴 보겠습니다.

    pip를 사용하여 설치

    Django를 설치하는 가장 일반적인 방법입니다. 권장되는 방법은 가상 Python 환경을 만드는 것입니다. 이렇게 하면 시스템에 영향을 주지 않고 Python 패키지를 설치할 수 있습니다.

    데모 프로젝트 디렉토리를 생성해 보겠습니다.

    $ mkdir ~/sampleproject
    $ cd ~/sampleproject
    

    다음 명령을 사용하여 가상 환경을 만듭니다. sample_env를 가상 환경을 호출할 이름으로 바꿉니다.

    $ python3 -m venv sample_env
    

    이렇게 하면 프로젝트 디렉터리 내에 이식 가능한 Python 버전인 pip가 설치됩니다. 프로젝트에 패키지를 설치하려면 다음 명령을 사용하여 환경을 활성화해야 합니다.

    $ source sample_env/bin/activate
    

    쉘 프롬프트는 가상 환경을 반영하도록 변경됩니다.

    (sample_env) :~/sampleproject$
    

    이제 가상 환경이 활성화되었으므로 pip를 사용하여 Django를 설치합니다. 다음 명령을 실행하여 Django를 설치합니다.

    (sample_env) $ pip install django
    

    설치를 확인하십시오.

    (sample_env) $ django-admin --version
    4.1.2
    

    프로젝트 요구 사항에 따라 다음과 같은 방법으로 다른 버전의 Django를 설치할 수 있습니다.

    (sample_env) $ pip install django==3.2.1
    

    설치를 확인하십시오.

    (sample_env) $ django-admin --version
    3.2.1
    

    보시다시피 이 방법은 Rocky Linux 저장소에서 얻은 버전보다 최신 버전의 Django를 설치합니다.

    가상 환경을 종료하려면 다음 명령을 실행하십시오.

    (sample_env) $ deactivate
    

    개발 버전 설치

    pip를 사용하여 Django의 개발 버전을 설치할 수도 있습니다. 이를 위해 Djangos Github 리포지토리에서 개발 버전을 가져옵니다.

    다음 명령을 사용하여 리포지토리를 ~/django-dev 디렉터리에 복제합니다.

    $ git clone https://github.com/django/django ~/django-dev
    

    새로 만든 디렉터리로 전환합니다.

    $ cd ~/django-dev
    

    가상 환경을 만듭니다.

    $ python3 -m venv dev_django_env
    

    환경을 활성화합니다.

    $ source dev_django_env/bin/activate
    

    pip를 사용하여 Django를 설치합니다. -e 플래그는 버전 제어에서 설치하는 경우 필요한 편집 가능 모드로 설치합니다.

    (dev_django_dev) $ pip install -e ~/django-dev
    

    설치를 확인하십시오.

    (dev_django_dev) $ django-admin --version
    4.2.dev20221012095013
    

    보시다시피 여기 버전이 최신 개발 버전입니다. Django의 개발 버전은 프로덕션 환경에 유용하지 않습니다.

    5단계 - 샘플 프로젝트 생성

    샘플 Django 프로젝트를 빌드해 보겠습니다. 샘플 프로젝트의 디렉터리를 만듭니다.

    $ mkdir ~/dj-sample
    $ cd ~/dj-sample
    

    Python 가상 환경을 만듭니다.

    $ python3 -m venv sample_proj
    

    환경을 활성화합니다.

    $ source sample_proj/bin/activate
    

    휠 패키지를 설치합니다.

    (sample_proj) $ pip install wheel
    

    Django 및 필요한 패키지를 설치합니다.

    (sample_proj) $ pip install django psycopg2 psycopg2-binary
    

    프로젝트를 빌드하려면 startproject 명령을 사용해야 합니다. 이 명령은 다음을 포함하는 다른 디렉토리를 생성합니다.

    • Django 관련 작업을 관리하는 데 사용되는 관리 스크립트 manage.py.\n
    • 프로젝트 코드가 포함된 프로젝트와 이름이 같은 디렉토리.\n

    현재 작업 디렉토리에 프로젝트 디렉토리를 생성합니다. 그렇게 하려면 다음 명령 끝에 점(.) 문자를 사용하십시오.

    (sample_proj) $ django-admin startproject demoproject .
    

    Django는 SECRET_KEY 변수를 사용하여 암호화 서명을 제공합니다. 설치 중에 기본값을 생성합니다. 안전한 값으로 바꿔야 합니다. 다음 명령을 실행하여 키를 생성하고 나중에 복사합니다.

    (sample_proj) $ python3 -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
    

    키를 사용하여 다음 출력을 얻을 수 있습니다.

    wm#dzb^ymuo3s3tza=f5cx^kan!$4sch1!b-q=v%)=d0pb(jqf
    

    첫 번째 단계는 프로젝트 설정을 조정하는 것입니다. 편집을 위해 설정 파일을 엽니다.

    (sample_proj) $ nano demoproject/settings.py
    

    SECRET_KEY 변수의 현재 값을 생성한 키로 바꿉니다.

    SECRET_KEY = 's)3m=4s&!a=p#$8(z6e+u8(^tkpw28qyj0t#8ku2'
    

    다음과 같이 DATABASES 섹션의 설정을 변경합니다.

    DATABASES = {
        'default': {
    		'ENGINE': 'django.db.backends.postgresql_psycopg2',
    		'NAME': 'DATABASE_DB',
    		'USER': 'DATABASE_USER',
    		'PASSWORD': 'DATABASE_PASSWORD',
    		'HOST': 'DATABASE_HOST',
    		'PORT': 'DATABASE_PORT',
    	},
    }
    

    다음으로 파일 하단으로 이동하여 정적 파일 위치에 대한 설정을 추가합니다. 이것은 Nginx가 작동하고 이러한 파일에 대한 요청을 처리하는 데 중요합니다. STATIC_URL 변수 위에 다음 줄을 추가합니다.

    STATIC_ROOT = os.path.join(BASE_DIR, "static/")
    

    STATIC_ROOT 변수는 os 모듈을 사용하기 때문에 기본적으로 가져오지 않기 때문에 가져와야 합니다. from pathlib import Path 줄 위에 다음 줄을 추가합니다.

    import os
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    데이터베이스 설정을 확인하십시오.

    (sample_proj) $ python manage.py check --database default
    

    다음 출력을 얻어야 합니다.

    System check identified no issues (0 silenced).
    

    다음으로 migrate 명령을 사용하여 데이터베이스를 마이그레이션해야 합니다. Django의 마이그레이션은 모델에 대한 변경 사항을 데이터베이스 스키마로 전파합니다.

    (sample_proj) $ python manage.py makemigrations
    (sample_proj) $ python manage.py migrate
    

    다음과 같은 결과가 표시됩니다.

    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying auth.0012_alter_user_first_name_max_length... OK
      Applying sessions.0001_initial... OK
    

    다음으로 Djangos 관리 인터페이스에 액세스할 관리 사용자를 만듭니다.

    (sample_proj) $ python manage.py createsuperuser
    

    사용자 이름, 이메일 및 비밀번호를 입력하라는 메시지가 표시됩니다.

    Username (leave blank to use 'navjot'):
    Email address: 
    Password:
    Password (again):
    Superuser created successfully.
    

    정적 파일을 정적 디렉토리에 복사하십시오. 메시지가 표시되면 yes를 입력합니다.

    (sample_proj) $ python manage.py collectstatic
    130 static files copied to '/home/navjot/dj-sample/static'.
    

    6단계 - 개발 서버 테스트

    응용 프로그램을 테스트할 시간입니다. 이를 위해서는 Django 설정에서 ALLOWED_HOSTS 지시문을 수정해야 합니다. 이 지시문은 Django 애플리케이션에 대한 액세스 권한이 부여된 IP 주소 및 도메인 이름 목록을 정의합니다.

    다음 명령을 사용하여 설정 파일을 엽니다.

    (sample_proj) $ nano demoproject/settings.py
    

    다음 항목을 찾으십시오.

    ALLOWED_HOSTS = []
    

    대괄호 안에 서버 IP 주소를 입력합니다. 각 항목은 따옴표로 묶어야 하며 여러 항목은 쉼표로 구분해야 합니다. www.example.com을 입력하면 정확히 일치합니다. 그러나 .example.comexample.comwww.example.com과 일치하며 모든 example.com의 다른 하위 도메인. 따라서 마침표를 사용하여 도메인 이름과 해당 하위 도메인을 일치시키는 접두사를 사용하는 것이 좋습니다.

    ALLOWED_HOSTS = ['<yourserver_ip_address>']
    

    우리는 서버와 일치시키기 위해 IP 주소를 사용했습니다. Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    개발 서버를 테스트하기 전에 Django가 작동하도록 방화벽을 구성해야 합니다. Django는 기본적으로 포트 8000을 사용합니다. Uncomplicated Firewall(UFW)을 사용하여 포트를 엽니다.

    (sample_proj) $ sudo firewall-cmd --add-port=8000/tcp --permanent
    (sample_proj) $ sudo firewall-cmd --reload
    

    개발 서버를 시작합니다.

    (sample_proj) $ python manage.py runserver 0.0.0.0:8000
    

    브라우저에서 URL http://:8000을 실행하면 다음 화면이 나타납니다.

    URL http://:8000/admin/을 따라 관리 인터페이스에 액세스할 수 있으며 다음 로그인 화면이 표시됩니다.

    아래 표시된 관리자 패널에 로그인하려면 이전에 만든 자격 증명을 입력하십시오.

    데모 프로젝트가 완료되면 터미널에서 Ctrl + C를 눌러 서버를 닫을 수 있습니다.

    7단계 - Gunicorn 설치 및 테스트

    nohup을 사용하여 영구 Django 서버 실행

    지금까지 Djangos 서비스는 영구적이지 않습니다. 서비스를 지속적으로 유지하려면 두 가지 방법이 있습니다. 첫 번째 방법은 nohup 유틸리티를 사용하는 것입니다. nohup은 끊지 않음을 의미하는 POSIX 명령입니다. 사용자가 로그아웃해도 멈추지 않는 방식으로 명령을 실행하기 위해 사용합니다.

    Ctrl + C를 눌러 터미널에서 서버를 종료했는지 확인하십시오.

    다음 명령을 실행하여 Djangos 개발 서버를 실행합니다.

    (sample_proj) $ nohup python manage.py runserver 0.0.0.0:8000 &
    

    이제 Django 서버는 수동으로 죽일 때까지 계속 실행됩니다. 이 명령은 프로세스 ID를 제공하고 다른 명령을 출력합니다.

    [1] 42595
    (sample_proj) $ nohup: ignoring input and appending output to 'nohup.out'
    ^C
    

    종료하려면 Ctrl + C를 누르십시오. 원래 Django 서버는 계속 실행됩니다. 브라우저에서 URL을 열어 확인할 수 있습니다.

    완료되면 프로세스를 종료해야 합니다. nohup 명령은 하나의 프로세스 ID를 제공합니다. 그러나 실제로는 두 개의 프로세스가 실행되고 있습니다. 두 프로세스의 ID를 찾으려면 다음 명령을 실행하십시오.

    (sample_proj) $ ps aux | grep manage.py
    navjot    153474  1.6  3.9  46264 39016 pts/0    S    04:15   0:00 python manage.py runserver 0.0.0.0:8000
    navjot    153475  3.0  4.4 196060 43500 pts/0    Sl   04:15   0:00 /home/navjot/dj-sample/sample_proj/bin/python manage.py runserver 0.0.0.0:8000
    navjot    153483  0.0  0.2   6420  2248 pts/0    S+   04:15   0:00 grep --color=auto manage.py
    

    보시다시피 ID가 153474인 프로세스와 ID가 153475인 프로세스 두 개가 실행되고 있습니다.

    위에서 얻은 프로세스 ID를 사용하여 다음 명령을 실행하여 서버를 종료합니다.

    (sample_proj) $ sudo kill -9 153474 153475
    

    Gunicorn 설치

    영구 Django 서버를 실행하는 두 번째 방법은 Gunicorn 및 Nginx 웹 서버를 설치해야 합니다. Gunicorn은 Python WSGI HTTP 서버입니다. Django 응용 프로그램과 인터페이스하고 Nginx가 Gunicorn에 대한 리버스 프록시 역할을 합니다. 이 방법은 Nginx 사용 시 제공되는 보안 및 성능을 제공하는 추가적인 이점이 있습니다.

    Gunicorn을 설치합니다.

    (sample_proj) $ pip install gunicorn
    

    진행하기 전에 Gunicorns가 프로젝트를 수행할 수 있는 능력을 테스트해야 합니다. 다음 명령을 실행하여 Gunicorn을 실행합니다.

    (sample_proj) $ gunicorn --bind 0.0.0.0:8000 demoproject.wsgi:application
    

    이렇게 하면 Django가 실행 중인 동일한 인터페이스에서 Gunicorn이 시작됩니다. 확인하려면 브라우저에서 URL http://:8000을 열면 동일한 Django 홈페이지가 표시됩니다. 이는 Gunicorn이 완벽하게 실행되고 있음을 의미합니다.

    테스트가 끝나면 터미널에서 Ctrl + C를 눌러 Gunicorn을 종료합니다.

    일반 셸로 돌아가려면 가상 환경을 비활성화하십시오.

    (sample_proj) $ deactivate
    

    8단계 - Gunicorn용 소켓 및 서비스 파일 생성

    첫 번째 단계는 Gunicorn 소켓 파일을 만드는 것입니다. Gunicorn 소켓은 부팅 시 생성되고 연결을 수신 대기합니다. 연결이 발생하면 systemd가 Gunicorn 프로세스를 자동으로 시작하여 처리합니다.

    편집을 위해 Gunicorn 소켓 파일을 만들고 엽니다.

    $ sudo nano /etc/systemd/system/gunicorn.socket
    

    다음 코드를 붙여넣습니다.

    [Unit]
    Description=gunicorn socket
    
    [Socket]
    ListenStream=/run/gunicorn.sock
    
    [Install]
    WantedBy=sockets.target
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    다음으로 편집을 위해 Gunicorn 서비스 파일을 생성하고 엽니다.

    $ sudo nano /etc/systemd/system/gunicorn.service
    

    다음 코드를 붙여넣습니다.

    [Unit]
    Description=django gunicorn daemon
    Requires=gunicorn.socket
    After=network.target
    
    [Service]
    User=navjot
    Group=nginx
    WorkingDirectory=/home/navjot/dj-sample
    ExecStart=/home/navjot/dj-sample/sample_proj/bin/gunicorn \
              -t 3000 \
              --access-logfile - \
              --workers 3 \
              --bind unix:/run/gunicorn.sock \
              demoproject.wsgi:application -w 2
    
    [Install]
    WantedBy=multi-user.target
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다. navjot를 시스템 사용자 이름으로 바꿉니다. nginx 그룹은 Nginx 서버가 Django와 통신할 수 있도록 합니다.

    시스템 데몬을 다시 로드하여 systemd 파일을 새로 고칩니다.

    $ sudo systemctl daemon-reload
    

    Gunicorn 소켓 파일을 활성화하고 시작합니다.

    $ sudo systemctl start gunicorn.socket
    $ sudo systemctl enable gunicorn.socket
    

    Gunicorn 소켓의 상태를 확인하십시오.

    $ sudo systemctl status gunicorn.socket
    

    비슷한 출력을 받게 됩니다.

    ? gunicorn.socket - gunicorn socket
         Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: disabled)
         Active: active (listening) since Thu 2022-10-13 04:19:28 UTC; 14s ago
          Until: Thu 2022-10-13 04:19:28 UTC; 14s ago
       Triggers: ? gunicorn.service
         Listen: /run/gunicorn.sock (Stream)
         CGroup: /system.slice/gunicorn.socket
    
    Oct 13 04:19:28 django.nspeaks.xyz systemd[1]: Listening on gunicorn socket.
    

    확인할 수 있듯이 Gunicorn 서비스가 아직 실행되지 않고 있습니다.

    $ sudo systemctl status gunicorn.service
    ? gunicorn.service - django gunicorn daemon
         Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
         Active: inactive (dead)
    TriggeredBy: ? gunicorn.socket
    

    소켓 활성화 메커니즘을 테스트하려면 다음 명령을 실행하십시오.

    $ curl --unix-socket /run/gunicorn.sock localhost
    

    터미널에서 Django 홈페이지의 HTML 출력을 받게 됩니다. 이렇게 하면 애플리케이션을 제공하기 위해 Gunicorn도 시작됩니다. 서비스 상태를 다시 확인하면 현재 실행 중임을 알 수 있습니다.

    $ sudo systemctl status gunicorn.service
    ? gunicorn.service - django gunicorn daemon
         Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: disabled)
         Active: active (running) since Thu 2022-10-13 06:13:55 UTC; 1min 34s ago
    TriggeredBy: ? gunicorn.socket
       Main PID: 157742 (gunicorn)
          Tasks: 4 (limit: 5915)
         Memory: 96.2M
            CPU: 1.198s
         CGroup: /system.slice/gunicorn.service
                 ??157742 /home/navjot/dj-sample/sample_proj/bin/python3 /home/navjot/dj-sample/sample_proj/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock demoproject.wsgi:application -w 2
                 ??157746 /home/navjot/dj-sample/sample_proj/bin/python3 /home/navjot/dj-sample/sample_proj/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock demoproject.wsgi:application -w 2
                 ??157747 /home/navjot/dj-sample/sample_proj/bin/python3 /home/navjot/dj-sample/sample_proj/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock demoproject.wsgi:application -w 2
                 ??157748 /home/navjot/dj-sample/sample_proj/bin/python3 /home/navjot/dj-sample/sample_proj/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock demoproject.wsgi:application -w 2
    .......
    

    9단계 - Nginx 설치

    마지막 단계는 Nginx를 설치하고 구성하는 것입니다. Rocky Linux는 이전 버전의 Nginx와 함께 제공됩니다. 최신 버전을 설치하려면 공식 Nginx 저장소를 다운로드해야 합니다.

    공식 Nginx 리포지토리를 만들기 위한 /etc/yum.repos.d/nginx.repo 파일을 만들고 엽니다.

    $ sudo nano /etc/yum.repos.d/nginx.repo
    

    다음 코드를 붙여넣습니다.

    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    Nginx 서버를 설치합니다.

    $ sudo dnf install nginx -y
    

    설치를 확인하십시오.

    $ nginx -v
    nginx version: nginx/1.22.1
    

    Nginx 서버를 활성화하고 시작합니다.

    $ sudo systemctl enable nginx --now
    

    서버의 상태를 확인하십시오.

    $ sudo systemctl status nginx
    ? nginx.service - nginx - high performance web server
         Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
         Active: active (running) since Thu 2022-10-13 06:17:24 UTC; 1s ago
           Docs: http://nginx.org/en/docs/
        Process: 157900 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
       Main PID: 157901 (nginx)
          Tasks: 2 (limit: 5915)
         Memory: 1.9M
            CPU: 18ms
         CGroup: /system.slice/nginx.service
                 ??157901 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
                 ??157902 "nginx: worker process"
    
    Oct 13 06:17:24 django.example.com systemd[1]: Starting nginx - high performance web server...
    

    10단계 - SSL 설치

    지금까지 Django 애플리케이션은 일반 텍스트 HTTP 연결을 통해 제공되었습니다. SSL 인증서를 통해 보호하는 것이 좋습니다. 이를 위해 Snapd 도구를 사용하는 Certbot 도구를 사용합니다. 작동하려면 EPEL 저장소가 필요합니다.

    $ sudo dnf install epel-release
    

    Snapd를 사용하여 Certbot을 설치합니다. 스냅드를 설치합니다.

    $ sudo dnf install snapd
    

    Snap 서비스를 활성화하고 시작합니다.

    $ sudo systemctl enable snapd.socket --now
    

    Snapd가 작동하는 데 필요한 링크를 만듭니다.

    $ sudo ln -s /var/lib/snapd/snap /snap
    $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
    

    핵심 Snapd 리포지토리를 설치합니다.

    $ sudo snap install core
    $ sudo snap refresh core
    

    Certbot을 설치합니다.

    $ sudo snap install --classic certbot
    $ sudo ln -s /snap/bin/certbot /usr/bin/certbot
    

    인증서를 생성합니다. 다음 명령은 Nginx도 자동으로 구성합니다.

    $ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m  -d django.example.com
    

    위의 명령은 서버의 /etc/letsencrypt/live/django.example.com 디렉토리에 인증서를 다운로드합니다.

    Diffie-Hellman 그룹 인증서를 생성합니다.

    $ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
    

    SSL 갱신이 제대로 작동하는지 확인하려면 프로세스를 시험 실행하십시오.

    $ sudo certbot renew --dry-run
    

    오류가 표시되지 않으면 모두 설정된 것입니다. 인증서가 자동으로 갱신됩니다.

    11단계 - Nginx 구성

    편집을 위해 /etc/nginx/conf.d/django-gunicorn.conf 파일을 만들고 엽니다.

    $ sudo nano /etc/nginx/conf.d/django-gunicorn.conf
    

    다음 코드를 붙여넣습니다.

    # enforce HTTPS
    server {
      listen 80 default_server;
      server_name django.example.com;
      return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name django.example.com;
    
        access_log  /var/log/nginx/django.access.log;
        error_log   /var/log/nginx/django.error.log;
    
        http2_push_preload on; # Enable HTTP/2 Server Push
    
        ssl_certificate /etc/letsencrypt/live/django.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/django.example.com/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/django.example.com/chain.pem;
        ssl_session_timeout 1d;
    
        # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
        ssl_protocols TLSv1.2 TLSv1.3;
    
        # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
        # prevent replay attacks.
        #
        # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
        ssl_early_data on;
    
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:50m;
    
        # OCSP Stapling ---
        # fetch OCSP records from URL in ssl_certificate and cache them
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
        add_header X-Early-Data $tls1_3_early_data;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/navjot/dj-sample;
        }
    
        location / {
            proxy_set_header Host $http_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;
            proxy_pass http://unix:/run/gunicorn.sock;
        }
    }
    
    # This block is useful for debugging TLS v1.3. Please feel free to remove this
    # and use the `$ssl_early_data` variable exposed by NGINX directly should you
    # wish to do so.
    map $ssl_early_data $tls1_3_early_data {
      "~." $ssl_early_data;
      default "";
    }
    

    위 파일의 루트 위치를 서버의 디렉토리로 바꿉니다.

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    편집을 위해 /etc/nginx/nginx.conf 파일을 엽니다.

    $ sudo nano /etc/nginx/nginx.conf
    

    include /etc/nginx/conf.d/*.conf; 줄 앞에 다음 줄을 추가합니다.

    server_names_hash_bucket_size  64;
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    Nginx 구성을 확인합니다.

    $ sudo nginx -t
    

    오류가 표시되지 않으면 잘 진행된 것입니다.

    또한 ALLOWED_HOSTS 지시문에 도메인 이름을 추가해야 합니다. settings.py 파일을 엽니다.

    $ nano ~/dj-sample/demoproject/settings.py
    

    ALLOWED_HOSTS 변수의 값을 변경합니다.

    ALLOWED_HOSTS = ['<yourserver_ip_address>','django.example.com']
    

    Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

    Gunicorn 소켓 및 서비스를 다시 시작합니다.

    $ sudo systemctl restart gunicorn.socket
    $ sudo systemctl restart gunicorn.service
    

    Nginx 서버를 다시 로드합니다.

    $ sudo systemctl reload nginx
    

    HTTP 포트를 엽니다. 더 이상 사용하지 않을 경우 8000 포트를 삭제할 수도 있습니다.

    $ sudo firewall-cmd --remove-port=8000/tcp --permanent
    $ sudo firewall-cmd --reload
    

    URL http://django.example.com을 열어 확인하면 Django 홈페이지가 로드됩니다.

    결론

    이것으로 Rocky Linux 9 서버에 Gunicorn 및 Nginx와 함께 Django를 설치하는 방법을 배운 튜토리얼을 마칩니다. Django 프로젝트의 보안을 강화하기 위해 SSL 인증서도 설치했습니다. 질문이 있으시면 아래 의견에 게시하십시오.