1112 TIL

looggi·2022년 11월 12일
1

스파르타 내배캠 AI-3

목록 보기
63/130

💣 목요일 타임어택 다시 해보기

✔️ UserSerializer 정의하기

❌ 오류1 : str 은 save라는 속성이 없다

➜ 비밀번호 해싱 후 유저를 저장해야하는데( user.save() ) 비밀번호 변수를( password.save() ) 저장하려고 함
➜ 그런데도 db에 저장이 돼서 같은 email로 회원가입은 불가능함 단 패스워드는 해싱 후 저장하지 않았으므로 입력한 그대로 저장됨
➜ 저장이 되는 이유는 보내는 순간 super().create(validated_data)에서 db에 저장하기 때문

❌ 오류2 : 어떤 instance object도 반환하지 않음

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields ='__all__'
    def create(self, validated_data):
        print(validated_data)
        user = super().create(validated_data)
        print(user)
        password = user.password
        user.set_password(password)
        user.save() #정답
        # password.save() #오류1
        # return user #오류2

➜ create 함수에 return값을 주지 않음
➜ 유저를 리턴하지 않더라도 save()에서 db에 (해싱된 패스워드까지)저장했기 때문에 같은 email로 가입을 시도하면 회원가입은 실패하게 됨

✔️ .env 적용해보기

https://django-environ.readthedocs.io/en/latest/quickstart.html

➡️ settings.py 설정

import environ
import os

env = environ.Env(
    # set casting, default value
    DEBUG=(bool, True)
)

# Set the project base directory
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Take environment variables from .env file
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))

DEBUG = env('DEBUG')
SECRET_KEY = env('SECRET_KEY')
DATABASES = {
    'default': env.db(),

    'extra': env.db_url(
        'SQLITE_URL',
        default='sqlite:////tmp/my-tmp-sqlite.db'
    )
}

➡️ .env 파일 설정

  • .env 파일을 루트 디렉토리에 만들고 다음과같이 환경변수를 입력해준다
DEBUG=True
SECRET_KEY='django-insecure-6)4as^*^uu=^4n!^hlg=jblm0w22fblm4@$k*k!7gvw&y-8_c4'
DATABASE_URL="sqlite://../db.sqlite3"

❌ 오류

  • 1번째 시도
# DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR /'db.sqlite3'}}

➜ 처음엔 그냥 시크릿키나 디버그처럼 세팅파일에 있는 걸 그대로 긁어오면 되는 줄 알았는데

➜ 이런 오류가 계속 났다. 그래서

# DATABASES = {
#     'default': dj_database_url.config(
#         default=env('DATABASE_URL')
#     )
# }
# DATABASE_URL="sqlite://../db.sqlite3"

➜ 이걸 시도해봤는데 DATABASES부분이 invalid line이라고 나오면서 작동이 됐다. 유효하지 않은 부분이라서 지워줌

근데 사실 공식문서에 보면 .env파일에 환경변수를 DATABASES가 아니라 DATABASE_URL이 예시로 나와있긴 한데 구글링한거랑 막 섞어서 생각하다보니까 혼선이 생긴 게 아닌가 싶다.. 구글링을 어느만큼 하는 게 좋은 걸까흠

  • SQLite URL contains host component '..', it will be ignored 라고 뜨는 부분이 있는데 이 부분이
    https://pypi.org/project/dj-database-url/
    ➜ 여기에 나오는 것처럼 sqlite:///Path라면 ..을 지워버려도 될 것 같아서 지우고 완성! 참고로 sqlite경로(Path)는 그냥 sqlite3였다(db.sqlite3 우클릭해서 copy Path)

  • 배포할 때는 env파일을 이렇게 두가지 만들어서 테스트하기도 하는구나.. 하면서 이만..
    https://mugon-devlog.tistory.com/41


🐰 토끼반 알고리즘

🥕 내적 - 멋있는 답들 공부해보기

def solution(a, b):

    return sum([x*y for x, y in zip(a,b)])

➜ zip : 2개 이상의 iterable 객체를 인자로 받고 데이터를 튜플 형식으로 짝지어줌
길이가 달라도 가능하지만 짧은 iterable객체를 기준으로 짝지어지고 남는 건 버려짐
dict() 함수에 zip을 이용해서 key, value를 짝지어 묶은 튜플을 넣으면 쉽게 딕셔너리를 생성하는 것도 가능


🐋 DOCKER 2주차 5~7

🦀 docker-compose로 컨테이너 생성하기

  • sudo docker rm -f 컨테이너id : 컨테이너의 구동여부와 무관하게 강제 삭제
  • vi docker-compose.yml
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.
# 버전이 다르면 아래 작성해야하는 형식도 달라짐

services: # 어떤 컨테이너를 만들지 정의하는 구간
  example: # 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
    container_name: example # 컨테이너 이름을 지정합니다.
    image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정합니다.
    restart: always # 컨테이너가 종료됐을 때(도커 재시작시) 다시 실행시켜 줍니다. 항상 실행하도록~
  • sudo docker compose up -d : 도커 컴포즈로 컨테이너 실행 d는 백그라운드로 실행하겠다는 의미
  • sudo docker compose stop : 컨테이너 중지 (status : exited)
    ➜ sudo docker compose start : stop한 컨테이너 재시작 (status : Up)/ 컨테이너 id 동일
  • sudo docker compose down : 컨테이너 중지/ ps시 아무것도 없음
    ➜ sudo docker compose up -d : down한 컨테이너 재시작 (status : Up)/ 컨테이너 id 다름

🦀 포트포워딩 설정하기

  • docker run으로 생성한 컨테이너는 public ipv4로 서버 접속이 됐지만
    docker-compose 로 생성한 컨테이너는 접속이 안됨 ➜ 포트포워딩 설정 필요
  • 포트 포워딩 : 포트에 대응되는 서비스로 전달
    서비스: 프로토콜 포함 db, django, nginx등
    ex) 80:8000 외부에서 80포트로 접속했을 때 해당 컨테이너의 8000번 포트로 접속
    웹브라우저에서 기본적으로 설정해줌
  • yml파일에 image 아래 작성
    띄어쓰기 안하면 services.example.ports must be a list라고 에러남
ports:
  - 80:80
  • sudo docker compose restart
  • sudo docker compose logs : 지금까지 찍힌 로그 확인
  • sudo docker compose logs -f: 실시간으로 찍힌 로그까지 확인가능
  • ctrl + c로 탈출

🦀 volume이 없다면..

컨테이너가 종료될 때 변경된 데이터가 모두 초기화됨

✔️ 실습)

  • 컨테이너 접속하기
    ➜ sudo docker exec -it $container_name /bin/bash : 해당 이름의 컨테이너로 접속(여기선 example)
    ➜ sudo docker exec -it $container_id /bin/bash : 해당 id의 컨테이너로 접속
  • root@2af8bcc8ceb4:/usr/local/apache2# : 접속하면 뜨는 명령어 라인/ 여기에 이제 아래 명령어 입력
  • echo "test" >> /usr/local/apache2/htdocs/index.html : test라는 문구를 페이지에 추가
  • exit : 컨테이너 나가기
  • down/up의 명령어를 사용해서 컨테이너를 재시작하게되면 test 문구 삭제됨

🦀 volume 사용법

특정 경로의 데이터들이 컨테이너 내부가 아닌 host에 저장이 됨

  • docker volume 종류
    • volume : docker엔진이 관리하는 영역에 저장 (host의 /var/lib/docker/volumes/)
      중요도 높은 파일을 사용자가 접근하지 못하게할 때/ 컨테이너간 파일 공유할 때 사용
    • bind mount : 사용자가 지정한 경로에 데이터가 저장됨
      설정파일/소스코드를 프로젝트-컨테이너가 공유할 때 사용
    • tmpfs mount : 많은 양의 데이터를 임시로 저장하거나 저장하면 안되는 정보를 다룰 때 사용
  • 볼륨 조회하기
    • sudo ls -l /var/lib/docker/volumes/(잘 쓰지 않는 방법)
    • sudo docker volume ls : 볼륨 목록 조회
    • sudo docker volume inspect $volume_name : 자세하게 보고싶을 때
      ➜ $volumename은 목록 조회시 나오는 ubuntu가 붙은 이름
  • 사용하지 않는 docker volume 삭제하기
    docker compose down/ docker rm으로 도커 컨테이너가 삭제되어도 docker volume은 남아있어 리소스 낭비가 될 수 있다 ➜ sudo docker volume prune ➜ y

✔️ 실습) bind mount

  • 호스트 경로에 있는 파일이나 디렉토리를 컨테이너 내부에 공유
  • 호스트에서 수정해도 컨테이너에 반영이 되고
    컨테이너에서 수정해도 호스트에 반영이 됨
  • yml 파일 수정
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.

services:
  example: 
    container_name: example 
    image: 'httpd:latest' 
    ports: 
      - 80:80 
    volumes: 
      - ./example_http_code/:/usr/local/apache2/htdocs/ 
    restart: always 

➜ ./ : 현재 경로 = docker-compose파일 경로
➜ host 경로 : 컨테이너 경로(볼륨이 될 경로 = index.html있던 경로와 동일)

✔️ 실습) docker volume

docker 엔진이 관리하는 경로에 데이터가 저장됨

  • yml 파일 수정
version: '3.8' 

volumes: # 볼륨 정의(생성) {설정사항}
  example_http_code: {} 

services:
  example: 
    container_name: example 
    image: 'httpd:latest' 
    ports: 
      - 80:80 
    volumes: 
      - example_http_code:/usr/local/apache2/htdocs/ 
      # 위에서 정의한 볼륨 : 컨테이너 내부 디렉토리
    restart: always 
  • volumes에서 정의한 볼륨은 컨테이너 내부의 디렉토리(도커영역의 볼륨을 생성함)로 bind mount와 저장위치가 달라서 이전 bind mount 실습에서 작성했던 내용들은 보이지 않음(덮어씌워지거나 사라진 것은 아님)
profile
looooggi

0개의 댓글