AWS EC2 서버 설정하기

  • EC2에 웹 서버 설정하기

    1. EC2에 SSH로 접속한다.

      1
      $ ssh -i ~/.ssh/[키페어 파일 이름] ubuntu@[EC2의 퍼블릭 DNS]
    2. 접속이 성공했다면 패키지를 최신으로 업데이트한다.

      1
      $ sudo apt-get update
    3. Nginx를 설치한다.

      1
      2
      # apt-get 사용
      $ sudo apt-get install nginx
    4. nginx가 잘 동작하는지 다음 명령어를 통해 확인한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      $ systemctl status nginx

      # nginx를 설치했다면...
      # status 명령어를 통해 상태를 확인한다.(active)
      # 웹 브라우저에서 퍼블릭 DNS 주소를 입력하여 확인한다.(Welcome to nginx 화면)

      # 아래 명령어를 알아두자.
      $ sudo systemctl stop nginx
      $ sudo systemctl start nginx
      $ sudo systemctl restart nginx
      $ systemctl status nginx
    5. Nginx는 한 서버 컴ㅍ퓨터에서 여러 사이트를 운영할 수 있다.

      • 사이트 별로 설정 파일을 만들어야 한다.
      • 여기서는 staticweb이라는 이름을 예시로 사용해본다.
        1
        2
        3
        # default 파일을 복사하여 staticweb 파일 생성
        # 파일 이름은 자유롭게 생성하자.
        $ sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/staticweb
    6. 생성한 설정 파일을 수정한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      $ sudo vim /etc/nginx/sites-available/staticweb

      # staticweb
      # default 파일을 복사했기 때문에 아래와 같이 내용을 수정한다.
      # server_name에는 퍼블릭 DNS 주소를 기입한다.
      server {
      listen 80;
      listen [::]:80;

      root /var/www/staticweb;

      index index.html index.htm index.nginx-debian.html;

      server_name [퍼블릭 DNS]

      location / {
      try_files $uri $uri/ =404;
      }
      }
    7. 설정 파일을 Nginx에 활성화시킨다.

      1
      2
      3
      # 심볼릭 링크를 사용하여 sites-enabled에 링크 파일을 생성한다.
      # site-enabled에 파일이 위치해야 사이트가 동작한다.
      $ sudo ln -s /etc/nginx/sites-available/staticweb /etc/nginx/sites-enabled
    8. 테스트를 위해 staticweb이라는 폴더를 만든다.

      1
      2
      $ cd /var/www/
      $ sudo mkdir staticweb
    9. staticweb 폴더 안에 index.html을 생성한다.

      1
      2
      $ cd /var/www/staticweb
      $ vim index.html
      1
      2
      3
      4
      5
      <html>
      <body>
      hello
      </body>
      </html>
    10. 웹 브라우저에서 퍼블릭 DHS 주소를 입력하여 hello가 출력되는지 확인한다.

  • EC2 인스턴스에 고정 IP 설정하기

    • 퍼블릭 DNS의 IP는 동적으로 변하는 상태이기 때문에 연결이 끊기는 상황이 발생할 수 있다.
    • Elastic IP 서비스를 사용하여 고정 IP를 할당받을 수 있다.
    1. EC2 화면 좌측 메뉴에서 네트워크 및 보안 / 탄력적 IP를 선택한다.
    2. 새 주소 할당을 누른다.
      • IP의 사용은 무료이지만, IP를 할당받고 사용하지 않으면 비용이 청구된다.
      • 따라서 사용하지 않는다면 삭제하자.
    3. 할당을 누르고 새 주소 요청 성공이 보이면 닫기를 누른다.
    4. IP 목록에서 할당받은 IP를 마우스 오른쪽 버튼으로 클릭한다.
    5. 주소 연결을 누르고 인스턴스 항목에 사용할 인스턴스를 선택하고 연결을 누른다.
    6. 주소 연결 요청 성공이 보이면 닫기를 누른다.
    7. 인스턴스 목록으로 가서 사용할 인스턴스에 설정이 되었는지 확인한다.
      • 퍼블릭 DNS 주소 대신에 탄력적 IP가 나타나는지 확인한다.
    8. [서비스] 메뉴에서 네트워킹 및 콘텐츠 전송/Route53으로 이동한다.
    9. 호스팅 영역으로 이동하여 사용중인 도메인을 누른다.
    10. 레코드 세트 생성을 누른다.
      • 원하는 이름을 설정한다.
      • 유형은 A-IPv4 주소를 선택한다.
      • 값에 할당받은 탄력적 IP를 기입하고 생성한다.
    11. 이제 ssh로 접속할 때 설정한 도메인 이름으로 접속할 수 있다.
    12. staticweb 설정 파일에서 server_name을 설정한 도메인 주소로 바꾸자.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      $ sudo vim /etc/nginx/sites-available/staticweb

      # staticweb
      # server_name에 연결한 도메인 주소를 기입한다.
      server {
      listen 80;
      listen [::]:80;

      root /var/www/staticweb;

      index index.html index.htm index.nginx-debian.html;

      server_name [Route53을 통해 연결한 도메인 주소]

      location / {
      try_files $uri $uri/ =404;
      }
      }
  • 커스텀 유저 모델 만들기

    • 생성한 장고 프로젝트에서 account 앱을 생성한다.

      1
      $ python manage.py starapp account
    • settings.py의 INSTALLED_APPS에 앱을 추가한다.

      1
      2
      3
      4
       INSTALLED_APPS = [
      #...
      'account',
      ]
    • models.py를 작성한다.

      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
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      from django.db import models

      # 기존에 있던 User 모델을 확장해서
      # 내가 원하는 추가 필드를 만드는 것
      # 커뮤니티 사이트 - 프로필 사진, 자기소개

      """
      기존에 모델을 확장(필드를 추가)하려면 모델 소스코드를 변경하는데,
      애시당초 모델을 만들 때는 models.Model을 상속받는다.
      * 모델은 어떤 모델을 상속받아서 확장할 수도 있다.

      기존 User 모델은 AbstractUser라는 모델을 상속받아서 구현된다.
      AbstractUser모델은 AbstractBaseUser라는 모델을 상속받아서 구현된다.
      * Abstract : 추상이라고 해석되는 단어인데, 모델의 설정값에 Abstract라는 값을 설정할 수 있다.
      abstract가 설정되어 있으면 실제 모델로 사용 불가

      1) 기존 User 모델은 AbstractUser라는 모델을 상속받아서 필수 필드들이 이미 구현이 되어있는 상태다.
      - 우리가 익히 보던 기본 필드들과 권한 관련 기능 등 장고에서 유저에게 기본적으로 필요한 기능이 구현이 되어있다.
      - 추가 필드가 필요한 경우에는 AbstractUser 모델을 상속받아서 구현하는 것이 제일 편하다.

      2) AbstractBaseUser로 구현해야 되는 경우
      - 모든 필드 구조를 변경할 필요가 있을 때
      - 퍼미션 기능 등 장고에서 사용하는 유저 기본 기능 전체를 뜯어 고치고 싶을 때
      - Backend를 새로 구현해줘야 한다.

      3) 기존 User 모델을 상속받거나, 확장해서 사용하는 경우
      - User + AdditionalInfo(생일, 주소, 주민번호)
      -> 회원 수정 페이지 AdditionalInfoForm을 추가로 입력

      1번을 제일 권장하는 확장 방식 - 프로젝트 시작 시점에 고려, (* 기존 데이터 유지 불가)
      3번은 사이트를 운영 중에 확장을 고려해야 할 때 선택 가능, 기존 User 데이터 그대로 존재, + 추가 테이블
      * OneToOne 필드

      swappable은 AUTH_USER_MODEL 값에 설정된 모델과 교체가 가능하다라고 미리 설정해둔 것

      class User(AbstractUser):
      class Meta(AbstractUser.Meta):
      swappable = 'AUTH_USER_MODEL'
      """
      from django.contrib.auth.models import AbstractUser

      class User(AbstractUser):
      message = models.TextField(blank=True)
      profile = models.ImageField(upload_to='user_images/profile/%Y/%m/%d', blank=True)
    • settings.py에 아래 항목을 추가한다.

      1
      AUTH_USER_MODEL = 'account.User'
    • 새로 만든 유저 모델의 데이터베이스 생성을 위해 아래 명령어를 실행한다.

      1
      2
      3
      4
      5
      6
      # 모델에 이미지 필드가 있으므로 pillow 모듈 설치
      $ pip install pillow

      $ python manage.py makemigrations account

      $ python manage.py migrate
    • 관리자 계정을 생성한다.

      1
      $ python manage.py createsuperuser
    • admin.py에 유저 모델을 등록해준다. 등록하지 않으면 관리자 페이지에서 볼 수 없다.

      1
      2
      3
      4
      from django.contrib import admin
      from .models import User

      admin.site.register(User)
    • 관리자 페이지에 접속하여 유저 모델을 수정해보면 기존 유저 모델 화면과 다른 것을 확인할 수 있다.

      • UserAdmin 클래스 옵션을 등록하여 기존 유저 모델과 같이 보이게 할 수 있다.
        1
        2
        3
        4
        5
        from django.contrib import admin
        from .models import User
        from django.contrib.auth.admin import UserAdmin

        admin.site.register(User, CustomUserAdmin)
    • 모델에서 만든 추가 필드 값에 대한 클래스를 새로 만들어서 등록해줘야 한다.

      • message와 profile의 필드 값이 나타나지 않는 것을 확인할 수 있다.
      • admin.py를 다음과 같이 수정한다.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        from django.contrib import admin
        from .models import User
        from django.contrib.auth.admin import UserAdmin

        class CustomUserAdmin(UserAdmin):

        # fieldsets - 상세 화면에서 출력될 수정 폼 설정
        # add_fieldsets - 추가 화면에 출력될 입력 폼의 설정
        UserAdmin.fieldsets[1][1]['fields']+=('profile','message')

        UserAdmin.add_fieldsets += (
        (('Additional Info'), {'fields':('profile','message')}),
        )

        # CustomUserAdmin으로 옵션 클래스 수정
        admin.site.register(User, CustomUserAdmin)
    • 관리자 페이지로 접속하여 추가 필드 값이 출력되는지 확인한다.

      • 추가 필드에 값이 정상적으로 입력되는지 확인하자.
  • Email 로그인 기능 추가하기

    • 로그인 기능을 제어하는 것은 AUTHENTICATION_BACKENDS에 설정된 모델 백엔드를 통해 이뤄진다.
    • 커스텀 모델 백엔드를 추가하여 username과 email 모두 가능한 로그인 기능을 만든다.
    1. account 앱에 backends.py를 추가하고 다음과 같이 입력한다.

      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
      from django.contrib.auth import get_user_model

      class CustomUserBackend(ModelBackend):
      def authenticate(self, request, username=None, password=None, **kwargs):
      user = super().authenticate(request, username, password, **kwargs)

      if user:
      return user

      # id 로그인 실패 상황
      # email 로그인 시도
      UserModel = get_user_model()
      # 원래 id 로그인 처리를 할 때 username이 넘어왔을 경우
      # email 변수에 새로 값을 할당하려고
      email = username
      if email is None:
      email = kwargs.get(UserModel.EMAIL_FIELD, kwargs.get('email'))
      try:
      user = UserModel._default_manager.get(email=email)
      except UserModel.DoesNotExist:
      # Run the default password hasher once to reduce the timing
      # difference between an existing and a nonexistent user (#20760).
      UserModel().set_password(password)
      else:
      if user.check_password(password) and self.user_can_authenticate(user):
      return user
    2. settings.py에 아래 항목을 추가한다.

      1
      2
      3
      AUTHENTICATION_BACKENDS = [
      'account.backends.CustomUserBackend',
      ]
    3. 관리자 페이지를 접속하여 이메일로 접속되는지 확인한다.

Share