DevOps/Docker

[Docker] Django App을 Docker 이미지로 빌드하기

TTOII 2022. 5. 12. 21:20
728x90

✔️ Django

Getting started with Django | Django (djangoproject.com)
Writing your first Django app, part 1 | Django documentation | Django (djangoproject.com)

Djnago는 풀스택 웹 프레임워크이다.

 

✔️ Django App 개발 환경 준비

mkdir ~/python/hello-django
cd ~/python/hello-django
python3 -m venv djangoapp
. djangoapp/bin/activate

가상 환경 생성 및 가상 환경 activate

✔️ Django 패키지 설치

(djangoapp)  vagrant@docker  ~/python/hello-django  pip3 install Django
(djangoapp)  vagrant@docker  ~/python/hello-django  pip3 list
Package            Version
------------------ -------
asgiref            3.5.1
backports.zoneinfo 0.2.1
Django             4.0.4
pip                20.0.2
pkg-resources      0.0.0
setuptools         44.0.0
sqlparse           0.4.2

 

✔️ Django 패키지 freeze

(djangoapp)  vagrant@docker  ~/python/hello-django  pip3 freeze > requirements.txt
(djangoapp)  vagrant@docker  ~/python/hello-django  cat requirements.txt
asgiref==3.5.1
backports.zoneinfo==0.2.1
Django==4.0.4
sqlparse==0.4.2

requirements.txt 파일을 만든다.

 

✔️ Django project 구조 생성

Django에서는 project와 app이라는 개념이 있다.
하나의 project안에 여러개의 app이 존재하며 하나의 app마다 기능이 다르다.

$ django-admin startproject mysite

Django는 project를 만들 때 해당 명령어를 내려서 프로젝트의 구조를 만들어준다. ansible-galaxy init과 비슷하다.

(djangoapp)  vagrant@docker  ~/python/hello-django  django-admin startproject mysite
(djangoapp)  vagrant@docker  ~/python/hello-django  ls
djangoapp  mysite  requirements.txt

(djangoapp)  vagrant@docker  ~/python/hello-django  tree mysite
mysite
├── manage.py
└── mysite
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

1 directory, 6 files

 

✔️ Django App 실행

우선 기본 App을 실행해보자

(djangoapp)  vagrant@docker  ~/python/hello-django  cd mysite
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  ls
manage.py  mysite # Django App - 프로젝트와 같은 이름으로 생성된다.
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
May 11, 2022 - 05:43:44
Django version 4.0.4, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Django는 기본적으로 8000번 포트를 사용한다.

아무 설정도 하지 않으면 접근 차단 상태이다. allow host를 세팅해야한다.

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite/mysite  pwd
/home/vagrant/python/hello-django/mysite/mysite
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite/mysite  vi settings.py

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  python3 manage.py runserver 0.0.0.0:8000

 

✔️ Django App 추가 기능

https://docs.djangoproject.com/en/4.0/intro/tutorial01/

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  python manage.py startapp polls 

현재 디렉토리에 polls 라는 디렉토리가 만들어진다.

 

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  ls
db.sqlite3  manage.py  mysite  polls
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  tree polls
polls
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

1 directory, 7 files

polls/views.py

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  vi polls/views.py
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  cat polls/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. Your're at the polls index.")

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite 

polls/urls.py

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  vi polls/urls.py
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  cat polls/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

mysite/urls.py

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  vi mysite/urls.py
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  cat mysite/urls.py
"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

 

 

✔️ Django App을 Docker Image로 빌드하기

✔️ .dockerignore 파일 구성하기

.dockerignore

djangoapp/
Dockerfile
.dockerignore

 

✔️ Dockerfile 작성하기

Dockerfile

FROM python:3.9-buster

# For Slim Buster
#FROM python:3.9-slim-buster
#RUN apt update && apt install -y gcc libc6-dev

# For Alpine Linux
#FROM python:3.9-alpine
#RUN apk add gcc musl-dev

COPY . /app
WORKDIR /app
RUN python3 -m venv venv && . venv/bin/activate
RUN pip3 install -r requirements.txt

WORKDIR /app/mysite
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
EXPOSE 8000

python은 glue 언어라고 해서 다른 언어와 혼합해서 사용할 수 있다.

python package 중에 C 언어로 만든 패키지도 있기 때문에 에러가 발생할 수 있다.
C 언어 빌드를 하다가 library가 존재하지 않아서 gcc에서 오류가 발생하는 경우가 잦다.


적절한 Base Image(여기서는 python:3.9-buster를 사용)를 지정하거나 추가 명령을 실행한다.

알파인이나 슬림 버전 python은 최소한의 bin/lib을 구성하므로 이런 부분을 신경 써야 한다.

 

✔️ Django App 이미지 빌드

(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  docker build -t mydjango .
(djangoapp)  vagrant@docker  ~/python/hello-django/mysite  docker run -d -p 80:8000 mydjango

 

728x90