// 함수의 이름을 메모리에 저장
// dart는 return type을 정하지 않아도 됨
add(){
	print("더하기 함수입니다.")
}
// var 생략 가능
add2(var n1,n2){
	print(n1 + n2);
}

void main(){
	// 저장된 함수 호출
	add();
    add2(3, 5);
}

자료형을 알고 있을땐 선언하는 것을 권장

dart는 오버로딩이 되지 않음

기본값 할당 가능

{ 매개변수} 로 선택적으로 사용 가능

return의 자료형을 모를땐 dynamic 사용

// 기본값 할당 가능
// { } 선택적으로 매개변수 사용 가능
void add({int n1 = 1, var n2 = 1}) {
	print(n1 + n2);
}

void main(){
	add(n1:10);
}
함수를 변수에 저장 가능 Function 타입 사용
// 함수가 1급 객체이기 때문에 전달 가능
Function add = ({int n1 = 1, var n2 = 1}) {
	return n1 + n2;
}

void hello(Function t) {
	t();
}

void main() {
	hello(add);
}

var 과 dynamic 의 차이

var 는 실행 시에 타입이 고정

main(){	
    var num = 10;
	num = '안녕'; // 오류 발생
}

dynamic은 실행 시에 타입이 고정되지 않음

main(){
    dynamic sum = 20;
    sum = '안녕';
}

조건문

bool isRunning = true; // false

String name;

void main(){
	// if 조건문
    if (isRunning){
    	print("참");
    } else {
    	print("거짓");
    }
    
    // 삼항 연산자 (변수 = 조건 ? 데이터1 : 데이터2 )
    String s = isRunning ? "참" : "거짓";
    
    print("결과 ${s}");
    
    // 엘비스(Elvis) 연산자 null 값 확인
    String data = name; // data = null
    // data가 null일때 data = 홍길동
    String data = name ?? '홍길동';
    
}
728x90

'Study > Dart' 카테고리의 다른 글

[Dart] 클래스  (0) 2021.06.04
[Dart] final 과 const 차이  (0) 2021.06.04
[Dart] 반복문과 깊은 복사  (0) 2021.06.04
[Dart] 익명함수와 화살표 함수  (0) 2021.06.04
[Dart] 기본자료형  (0) 2021.06.03

 variable type

1급 객체

클래스 안이나 메스드 안에 위치하는 것 뿐만 아니라 최상단에 위치 가능

함수의 파라메터로 전달 가능, 메모리에 로딩 가능함

동적으로 메모리 할당 -> 실행될때 크기가 정해짐

var name = "문자열";
var num = 1;
var fNum = 1.5;
var list = ["apple","banana"];

//map 자료형
var user = {
	"id":1,
    "username":"ssar"
}

void main(){
	print(name);
    print(num);
    print(fNum);
    print(list);
    print(list[0]);
    //찾을땐 key값으로 찾음
    print(user["id"]);
}

void main() 이 실행되기 전에 var 를 먼저 읽음

그렇기에 main안에서 찾을 수 있음

 

자료형 할당

dynamic == java의 object 즉, 모든 타입

문자열 " " , ' ' 가능

문자열 사이 + 보다는 ${ } 를 권장

String name = "문자열";
int num = 1;
double fNum = 1.5;

// bool 타입
bool isRunning = true; // false

// collection type (어떤 데이터가 순차적으로 저장)
List<String> list = ["apple","banana"];

//map 자료형
Map<String,dynamic> user = {
	"id":1,
    "username":"ssar"
}

void main(){

	print(name);
    print(num);
    print(fNum);
    print(list);
    print(list[0]);
    //찾을땐 key값으로 찾음
    print(user["id"]);
    
    // + 대신에 %{ }를 사용하는 것을 권장
    print("유저네임은 " + user["username"]);
    print("유저네임은 %{user["username"]}");
}

참고

https://www.youtube.com/watch?v=Uby2fofxFls&list=PL93mKxaRDidGEaUXprXqhNvSW02xCjLZI&index=6 

 

728x90

'Study > Dart' 카테고리의 다른 글

[Dart] 클래스  (0) 2021.06.04
[Dart] final 과 const 차이  (0) 2021.06.04
[Dart] 반복문과 깊은 복사  (0) 2021.06.04
[Dart] 익명함수와 화살표 함수  (0) 2021.06.04
[Dart] 메서드(함수)  (0) 2021.06.03

Compile

사람이 이해하는 언어를 컴퓨터가 이해하는 언어로 바꿔주는 과정

정적언어인 경우 가능함 - C언어, Java ...

즉, 변수 Type이 존재

변수의 타입이 존재해야 내가 만든 변수의 크기를 알 수 있고 그래야 메모리의 사이즈를 측정하고 기계에 의해 실행 가능

Interpreter

소스코드를 한 줄씩 읽어서 바로 실행하는 방식

동적언어인 경우 가능 - python, javascript ... 

변수의 Type을 모름

JIT(Just In Time)

1.  중간언어로 컴파일

가상 머신(JVM..) 위에서 작동하는 파일로 컴파일

2. VM에 의해 인터프리터로 실행

중간언어 -> os에 맞게 컴파일 실행

실제 개발

미리 모든 것을 개발하고 컴파일하는 것이 아니라 실행 속도가 느림

그렇기에 개발 환경에서 사용

AOT(Ahead-Of-Time compile)

운영체제에 맞춰 컴파일

배포환경에서 사용


아래의 영상을 보고 정리한 글

https://www.youtube.com/watch?v=NATSWdq2AvU&list=PL93mKxaRDidGEaUXprXqhNvSW02xCjLZI&index=5

 

728x90

'Study > Computer Science' 카테고리의 다른 글

동기 / 비동기 & 블로킹 / 논블로킹  (0) 2021.06.08

배포 진행 순서

1. docker swarm init 초기화

2. django에서 보안 사항들을 docker secrets에 저장

3. docker secrets에 저장한 보안 사항들을 배포할때 django project로 불러오기

4. docker image를 만들기위한 Dockerfile 생성

4-1. portainer에서 docker image 생성

5. docker stack를 위한 docker-compose.yml 생성

6. docker stack 생성 및 실행

1. docker swarm init 초기화

https://docs.docker.com/engine/reference/commandline/swarm_init/

 

docker swarm init

docker swarm init: Initialize a swarm. The docker engine targeted by this command becomes a manager in the newly created single-node swarm.

docs.docker.com

docker swarm init

2. django에서 보안 사항들을 docker secrets에 저장

portainer -> secrets -> add secrets

아래와 같이 django secret key 등 생성

3. docker secrets에 저장한 보안 사항들을 배포할때 django project로 불러오기

django secrets 에 저장한 내용은 /run/secrets/ 위치에 저장됨

settings.py 나 deploy.py 등 배포에 사용할 환경파일에서 파일을 읽어 사용

# docker secrets의 파일 읽어오기

def read_secret(secret_name):
    file = open("/run/secrets/" + secret_name)
    secret = file.read()
    secret = secret.rstrip().lstrip()
    file.close()

    return secret

# 실제 사용
SECRET_KEY = read_secret("DJANGO_SECRET_KEY")

4. docker image를 만들기위한 Dockerfile 생성

- 파이썬 3.9 버전 위에서

FROM python:3.9.0

- /home 폴더 위치로 이동하여 (없으면 생성)

WORKDIR /home/

- github에서 프로젝트 소스코드를 가져와서 다운

RUN git clone [https://github.com/{user}/{project}.git](https://github.com/mugon-dev/django-pinterest.git)

- 다운받은 폴더로 이동하여

WORKDIR /home/[project](https://github.com/mugon-dev/django-pinterest.git)/

- 라이브러리를 설치하고

RUN pip install -r requirements.txt

- container에 8000번 포트를 열어주고

EXPOSE 8000

- 배포 환경으로 실행하는데 static파일들을 한 곳에 모으고, migrate하고 8000번 포트에 bind해서 실행

CMD ["bash", "-c", "python manage.py collectstatic --noinput --settings=config.settings.deploy && python manage.py migrate --settings=config.settings.deploy && gunicorn --env DJANGO_SETTINGS_MODULE=config.settings.deploy config.wsgi --bind 0.0.0.0:8000"]

4-1. portainer 에서 docker image 만들기

portainer -> images -> build a new image

upload 탭에서 위에서 만든 Dockerfile 불러와 생성

5. docker stack를 위한 docker-compose.yml 생성

# docer compose 버전
version: "3.7"
# docker service 생성
services:
# nginx container 생성
  nginx:
  # nginx image 불러오기
    image: nginx:1.19.5
    # nginx가 속할 network
    networks:
      - network
    # voluems 정의
    volumes:
    # 내가 올린 nginx.conf를 nginx폴더의 nginx.conf와 연결
      - /home/django_course/nginx.conf:/etc/nginx/nginx.conf
      # volumes에 저장할 파일들의 경로
      - static-volume:/data/static
      - media-volume:/data/media
    # nginx가 사용할 ports
    ports:
      - 80:80
  # django container 생성
  # container name은 nginx.conf에서 hostname과 동일하게 작성
  django_container_gunicorn:
    # 위에서 만든 image 불러오기
    image: django_test_image:5
    # 장고가 속할 네트워크
    networks:
      - network
    # volumes에 저장할 파일들의 경로
    volumes:
      - static-volume:/home/django-pinterest/staticfiles
      - media-volume:/home/django-pinterest/media
    # 위에서 저장한 django secrets에서 가져올 파일
    secrets:
      - MYSQL_PASSWORD
      - DJANGO_SECRET_KEY
  # mariadb container 생성
  # container name은 djago settings의 host명과 동일하게 작성
  mariadb:
      # 사용할 이미지
    image: mariadb:10.5
    # 사용할 네트워크
    networks:
      - network
    # volumes에 저장할 db 데이터
    volumes:
      - maria-database:/var/lib/mysql
    # 위에서 저장한 django secrets에서 가져올 파일
    secrets:
      - MYSQL_PASSWORD
      - MYSQL_ROOT_PASSWORD
    # maria db의 환경변수
    # docker secrets에서 패스워드 가져오기
    environment:
      MYSQL_DATABASE: django
      MYSQL_USER: django
      MYSQL_PASSWORD_FILE: /run/secrets/MYSQL_PASSWORD
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/MYSQL_ROOT_PASSWORD

# 사용할 네트워크
networks:
  network:

# 사용할 volume
volumes:
  static-volume:
  media-volume:
  maria-database:

# 사용할 secrets
secrets:
  DJANGO_SECRET_KEY:
    external: true
  MYSQL_PASSWORD:
    external: true
  MYSQL_ROOT_PASSWORD:
    external: true

6. docker stack 생성 및 실행

portainer -> stack -> add stack

upload 탭에서 위에서 만든 docker-compose.yml 불러와서 생성

7. 확인

portainer -> swarm -> go to cluster visulizer

728x90

'Study > Django' 카테고리의 다른 글

[Django] gunicorn  (0) 2021.05.28
[Django] 배포를 위한 환경파일 분리  (0) 2021.05.28
[Django] field lookup  (0) 2021.05.25
[Django] decorator  (0) 2021.05.25
[Django] code formatting black 설치 및 적용  (0) 2021.05.20

CGI Common Gateway Interface

웹 서버 프로그램의 기능의 주체는 미리 준비된 정보를 이용자(클라이언트)의 요구에 응답해 보내는 것이다. 그 때문에 서버 프로그램 그룹에서는 정보를 그 장소에서 동적으로 생성하고 클라이언트에 송신하려하는 조합을 작성하는 것이 불가능했다. 서버 프로그램에서 다른 프로그램을 불러내고, 그 처리 결과를 클라이언트에 송신하는 방법이 고안되었다. 이를 실현하기 위한 서버 프로그램과 외부 프로그램과의 연계법을 정한 것이 CGI이다

여러 언어들이 사용자들의 다양한 요청을 이해할 수 있게 "이 문(인터페이스)을 지나면 이러한 형태가 됩니다"하고 정해놓은 규약이자 프로그램

WSGI Web Server Gateway Interface

파이썬 스크립트가 웹 서버와 통신하기 위해 만들어진 인터페이스

CGI를 설명한 것과 같이 웹서버에서의 요청을 해석하여 파이썬 응용프로그램에 던지는 역할

Gunicorn이나 uWSGI는 Apache나 nginx로 들어오는 HttpRequest를 Python이 이해할 수 있게
동시통역하여 던져주는 애들

Gunicorn 설치

https://gunicorn.org/

 

Gunicorn - Python WSGI HTTP Server for UNIX

Deployment Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use nginx. Here's an example to help you get started with using nginx: server { listen 80; server_name example.org; access_log /var

gunicorn.org

pip install gunicorn
  • Replace runserver -> gunicorn command
gunicorn myproject.wsgi
  • Dockerfile cmd 변경
CMD ["gunicorn", "myproject.wsgi", "--bind", "0.0.0.0:8000"]
728x90

패키지 생성

project를 시작할때 만든 settings.py의 위치에서 settings package를 생성

settings.py 이동

settings.py 를 base.py로 이름 변경 후 settings 패키지로 이동

local, deploy 파일 생성

settings 패키지안에 local.py, deploy.py 생성

환경변수 분리

공통 사항은 base.py

  • apps
  • static path ...

로컬 환경은 local.py

  • local에서 사용하는 db
  • debug, allowed host 등

배포 환경은 deploy.py

  • docker secrets 에서 가져오는 비밀번호 및 키
  • 배포환경에서 사용하는 db
# local.py

import os, environ
from .base import *

env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env(env_file=os.path.join(BASE_DIR, ".env"))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env("DEBUG")

ALLOWED_HOSTS = ["*"]


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}
# deploy.py

import os, environ
from .base import *

# docker secrets에서 가져오는 비밀키
def read_secret(secret_name):
    file = open("/run/secrets/" + secret_name)
    secret = file.read()
    secret = secret.rstrip().lstrip()
    file.close()

    return secret


env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env(env_file=os.path.join(BASE_DIR, ".env"))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = read_secret("DJANGO_SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ["*"]


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "django",
        "USER": "django",
        "PASSWORD": read_secret("MYSQL_PASSWORD"),
        "HOST": "mariadb",
        "PORT": "3306",
    }
}

manage.py 설정

아래의 os.environ.setdefault 부분 수정

두번째 인자에 python manage.py runserver 명령어를 사용할때 실행할 파일 연결

# root 폴더의 manage.py

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == "__main__":
    main()

배포 파일 실행

아래와 같이 runserver 에 --settings 옵션을 줘서 실행

python manage.py runserver --settings=config.settings.deploy
728x90

'Study > Django' 카테고리의 다른 글

[Docker] portainer를 활용한 docker secrets, swarm, stack, image  (0) 2021.05.28
[Django] gunicorn  (0) 2021.05.28
[Django] field lookup  (0) 2021.05.25
[Django] decorator  (0) 2021.05.25
[Django] code formatting black 설치 및 적용  (0) 2021.05.20

+ Recent posts