From 1d4b17dd03b8a7aaf1916919b2bc3e78023b11be Mon Sep 17 00:00:00 2001 From: bmcho Date: Mon, 18 Jul 2022 14:29:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20django=20=EC=84=A4=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20hello=EC=B6=9C=EB=A0=A5=20=EA=B0=80=EB=8A=A5=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C,=20=20nginx=20=EC=85=8B=ED=8C=85=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/hello/__init__.py | 0 apps/hello/admin.py | 3 + apps/hello/apps.py | 6 ++ apps/hello/migrations/__init__.py | 0 apps/hello/models.py | 3 + apps/hello/tests.py | 3 + apps/hello/urls.py | 8 ++ apps/hello/views.py | 7 ++ docker-compose.yml | 32 ++++++++ dockerfile | 20 +++++ ideaconcert/settings.py | 15 +++- ideaconcert/urls.py | 11 ++- nginx/nginx.conf | 22 +++++ poetry.lock | 129 ++++++++++++++++++++++++++++++ pyproject.toml | 17 ++++ requirements.txt | 7 ++ 16 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 apps/hello/__init__.py create mode 100644 apps/hello/admin.py create mode 100644 apps/hello/apps.py create mode 100644 apps/hello/migrations/__init__.py create mode 100644 apps/hello/models.py create mode 100644 apps/hello/tests.py create mode 100644 apps/hello/urls.py create mode 100644 apps/hello/views.py create mode 100644 docker-compose.yml create mode 100644 dockerfile create mode 100644 nginx/nginx.conf create mode 100644 poetry.lock create mode 100644 pyproject.toml create mode 100644 requirements.txt diff --git a/apps/hello/__init__.py b/apps/hello/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/hello/admin.py b/apps/hello/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/apps/hello/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/hello/apps.py b/apps/hello/apps.py new file mode 100644 index 0000000..cd5c231 --- /dev/null +++ b/apps/hello/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class HelloConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.hello' diff --git a/apps/hello/migrations/__init__.py b/apps/hello/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/hello/models.py b/apps/hello/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/apps/hello/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/hello/tests.py b/apps/hello/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/apps/hello/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/hello/urls.py b/apps/hello/urls.py new file mode 100644 index 0000000..d6cfe06 --- /dev/null +++ b/apps/hello/urls.py @@ -0,0 +1,8 @@ + +from django.urls import path + +from . import views + +urlpatterns = [ + path('', views.index, name='index'), +] \ No newline at end of file diff --git a/apps/hello/views.py b/apps/hello/views.py new file mode 100644 index 0000000..1d10699 --- /dev/null +++ b/apps/hello/views.py @@ -0,0 +1,7 @@ +from django.http import HttpResponse +from django.shortcuts import render + +# Create your views here. +def index(request): + return HttpResponse("Hello") + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7e8ee62 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: "3.9" +services: + app: + container_name: app + build: + context: . + dockerfile: dockerfile + env_file: .env + volumes: + - .:/srv/server + restart: always + expose: + - "8000" + networks: + - nginx_bridge + + nginx: + container_name: nginx + image: nginx:latest + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + restart: unless-stopped + ports: + - 80:80 + depends_on: + - app + networks: + - nginx_bridge + +networks: + nginx_bridge: + driver: bridge \ No newline at end of file diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..2588763 --- /dev/null +++ b/dockerfile @@ -0,0 +1,20 @@ +FROM python:3.9-slim-buster + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 +ENV DOCKERIZE_VERSION v0.6.1 + +WORKDIR /srv/server + +COPY . /srv/server + +RUN apt update && \ + apt install -y \ + gcc gfortran musl-dev g++ bash wget + +# 의존성 설치 +RUN pip install --upgrade pip +RUN pip install -r requirements.txt + + +CMD ["gunicorn", "--bind", "0:8000", "ideaconcert.wsgi:application"] \ No newline at end of file diff --git a/ideaconcert/settings.py b/ideaconcert/settings.py index 7ee2a04..a170bad 100644 --- a/ideaconcert/settings.py +++ b/ideaconcert/settings.py @@ -10,7 +10,19 @@ https://docs.djangoproject.com/en/3.2/ref/settings/ """ +import os from pathlib import Path +from django.core.exceptions import ImproperlyConfigured +from dotenv import find_dotenv, load_dotenv + +load_dotenv(find_dotenv()) + +def get_env_variable(var_name): + try: + return os.environ[var_name] + except KeyError: + error_msg = f'Set the {var_name} environment variable' + raise ImproperlyConfigured(error_msg) # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -20,7 +32,7 @@ # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-_mq6zincrrt!36svw&1q79k5flvpi737=yx%frytkghp0xqbuo' +SECRET_KEY = get_env_variable('SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -37,6 +49,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'apps.hello' ] MIDDLEWARE = [ diff --git a/ideaconcert/urls.py b/ideaconcert/urls.py index 149750b..1b942d9 100644 --- a/ideaconcert/urls.py +++ b/ideaconcert/urls.py @@ -14,8 +14,15 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import include, path -urlpatterns = [ + +app_urls = [ path('admin/', admin.site.urls), + path('hello/', include('apps.hello.urls')), +] + + +urlpatterns = [ + path('api/', include(app_urls)), ] diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..f0b6c61 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,22 @@ +worker_processes auto; +events { + worker_connections 1024; +} + +http{ + upstream backend { + server app:8000; + } + + server { + listen 80; + + location / { + proxy_pass http://backend; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + } + } +} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..d3584fa --- /dev/null +++ b/poetry.lock @@ -0,0 +1,129 @@ +[[package]] +name = "asgiref" +version = "3.5.2" +description = "ASGI specs, helper code, and adapters" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] + +[[package]] +name = "backports.zoneinfo" +version = "0.2.1" +description = "Backport of the standard library zoneinfo module" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +tzdata = ["tzdata"] + +[[package]] +name = "django" +version = "4.0.6" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +asgiref = ">=3.4.1,<4" +"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} +sqlparse = ">=0.2.2" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "gunicorn" +version = "20.1.0" +description = "WSGI HTTP Server for UNIX" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] + +[[package]] +name = "python-dotenv" +version = "0.20.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "sqlparse" +version = "0.4.2" +description = "A non-validating SQL parser." +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "tzdata" +version = "2022.1" +description = "Provider of IANA time zone data" +category = "main" +optional = false +python-versions = ">=2" + +[metadata] +lock-version = "1.1" +python-versions = "^3.8" +content-hash = "7937bc9673b7d172cf041dd50e740c06c2bb028d89d000a9aeba907a5a1097c9" + +[metadata.files] +asgiref = [ + {file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"}, + {file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"}, +] +"backports.zoneinfo" = [ + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, + {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, +] +django = [ + {file = "Django-4.0.6-py3-none-any.whl", hash = "sha256:ca54ebedfcbc60d191391efbf02ba68fb52165b8bf6ccd6fe71f098cac1fe59e"}, + {file = "Django-4.0.6.tar.gz", hash = "sha256:a67a793ff6827fd373555537dca0da293a63a316fe34cb7f367f898ccca3c3ae"}, +] +gunicorn = [ + {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, + {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, +] +python-dotenv = [ + {file = "python-dotenv-0.20.0.tar.gz", hash = "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f"}, + {file = "python_dotenv-0.20.0-py3-none-any.whl", hash = "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"}, +] +sqlparse = [ + {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, + {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, +] +tzdata = [ + {file = "tzdata-2022.1-py2.py3-none-any.whl", hash = "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9"}, + {file = "tzdata-2022.1.tar.gz", hash = "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7e2da8b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "ideaconcert" +version = "0.1.0" +description = "" +authors = ["None"] + +[tool.poetry.dependencies] +python = "^3.8" +Django = "^4.0.6" +gunicorn = "^20.1.0" +python-dotenv = "^0.20.0" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..74209c0 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +asgiref==3.5.2; python_version >= "3.8" +backports.zoneinfo==0.2.1; python_version < "3.9" and python_version >= "3.8" +django==4.0.6; python_version >= "3.8" +gunicorn==20.1.0; python_version >= "3.5" +python-dotenv==0.20.0; python_version >= "3.5" +sqlparse==0.4.2; python_version >= "3.8" +tzdata==2022.1; sys_platform == "win32" and python_version >= "3.8"