-
Notifications
You must be signed in to change notification settings - Fork 0
Containerize Application via Dockerfile #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 12 commits
a1b252c
7db2ad1
0f2be0f
5f7eb5b
3314675
c5ba2b4
7082a8d
3f35757
3944e80
c4359e8
b2ff57d
6848d6d
22f6ee5
8578187
c30f0e1
b078b7e
f8a2311
24dab47
52d0d66
85acb0d
a20783c
6ae436f
b746487
f558b0e
a8e1ac4
73229c4
29863e1
bc6c749
a1abf3f
1460cbf
f9550e8
68e8129
a769a1b
35def21
0eee093
dea4722
57c843a
af185de
af36d4c
1ca8e7a
d5ff410
346e5a5
003dd4b
f5e1b65
9ce235b
fc75d37
87275ff
aa5ef8a
6a1b839
378b1f2
48d4483
dd6eba6
4b9ef3f
73f0233
9342b8a
5fc332e
87bf64f
1a5afb4
e027e45
dd1a97c
eb8beb6
ffe5ab1
f34633b
7fc9fa8
08ca2f5
e2b5004
eafe260
dff722c
b290711
6e33709
37b1520
0204747
3ae8000
4cbca7e
da574ea
8f4b0d0
09d90a2
1b22925
1fd668a
63b9cd1
8720421
d89f9d4
3353f2f
9e78309
8b870dd
0698fa0
966dd8d
2e2f272
506a12f
c0519cc
5abc80d
211ee01
e9818f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,29 @@ | ||||||||||
| FROM python:3.11-slim | ||||||||||
|
|
||||||||||
| # Set the working directory inside the container | ||||||||||
| WORKDIR /app | ||||||||||
|
|
||||||||||
| # Set environment variables | ||||||||||
| # Prevents Python from writing pyc files to disk | ||||||||||
| ENV PYTHONDONTWRITEBYTECODE=1 | ||||||||||
| # Prevents Python from buffering stdout and stderr | ||||||||||
| ENV PYTHONUNBUFFERED=1 | ||||||||||
|
|
||||||||||
| # Upgrade pip | ||||||||||
| RUN pip install --upgrade pip | ||||||||||
|
|
||||||||||
| # Copy the Django project and install dependencies | ||||||||||
| COPY requirements.txt /app/ | ||||||||||
|
|
||||||||||
| # Run this command to install all dependencies | ||||||||||
| RUN pip install --no-cache-dir -r requirements.txt | ||||||||||
|
|
||||||||||
| COPY . /app/ | ||||||||||
|
|
||||||||||
|
hepheir marked this conversation as resolved.
|
||||||||||
| # Schedule health check | ||||||||||
| RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* | ||||||||||
| HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=3 CMD ["curl", "--silent", "http://localhost:8000/health/"] | ||||||||||
|
||||||||||
| HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=3 CMD ["curl", "--silent", "http://localhost:8000/health/"] | |
| HEALTHCHECK --interval=10s --timeout=3s --start-period=30s --retries=3 CMD ["curl", "--silent", "http://localhost:8000/health/"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로컬환경에서 측정한 것이긴 하나 starting에 5s-6s 소요되는 것으로 보이므로, 10s starting-period는 충분한 것으로 사료됩니다. 지금은 위 변경 제안은 기각하고 추후 문제가 생기면 재검토하겠습니다.
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running migrations during the image build (at RUN time) is incorrect. Migrations should be run when the container starts (at runtime), not during the build process, because:
- The database may not be available during build time
- The same image should be deployable to different environments with different database states
- This will cause the build to fail if no database is accessible
Move this to a startup script or use CMD instead. For example:
CMD python manage.py migrate --no-input && gunicorn app.wsgi:application --bind 0.0.0.0:8000Or create a separate entrypoint script that runs migrations before starting gunicorn.
| RUN /app/manage.py migrate --no-input | |
| ENTRYPOINT ["gunicorn", "app.wsgi:application", "--bind", "0.0.0.0:8000"] | |
| CMD python manage.py migrate --no-input && gunicorn app.wsgi:application --bind 0.0.0.0:8000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로컬 SQLite DB를 사용하는 동안에만 필요한 커맨드이므로 지금은 유지하고, 추후 DB 컨테이너 분리시에 migrate 명령을 제거하도록 조치하겠습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
85acb0d 커밋에서 마이그레이션 로직을 조건부로 수행하도록 조치하였습니다.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """ | ||
| ASGI config for app project. | ||
|
|
||
| It exposes the ASGI callable as a module-level variable named ``application``. | ||
|
|
||
| For more information on this file, see | ||
| https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/ | ||
| """ | ||
|
|
||
| import os | ||
|
|
||
| from django.core.asgi import get_asgi_application | ||
|
|
||
| os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') | ||
|
|
||
| application = get_asgi_application() |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,125 @@ | ||||||||||||
| """ | ||||||||||||
| Django settings for app project. | ||||||||||||
|
|
||||||||||||
| Generated by 'django-admin startproject' using Django 5.2.8. | ||||||||||||
|
|
||||||||||||
| For more information on this file, see | ||||||||||||
| https://docs.djangoproject.com/en/5.2/topics/settings/ | ||||||||||||
|
|
||||||||||||
| For the full list of settings and their values, see | ||||||||||||
| https://docs.djangoproject.com/en/5.2/ref/settings/ | ||||||||||||
| """ | ||||||||||||
|
|
||||||||||||
| from pathlib import Path | ||||||||||||
|
|
||||||||||||
| # Build paths inside the project like this: BASE_DIR / 'subdir'. | ||||||||||||
| BASE_DIR = Path(__file__).resolve().parent.parent | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| # Quick-start development settings - unsuitable for production | ||||||||||||
| # See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ | ||||||||||||
|
|
||||||||||||
| # SECURITY WARNING: keep the secret key used in production secret! | ||||||||||||
| SECRET_KEY = 'django-insecure-dulqz#%k5aq8%cdx02%55tm9+2q1b%qogh%2#6jbx3zn4ab5pb' | ||||||||||||
|
|
||||||||||||
| # SECURITY WARNING: don't run with debug turned on in production! | ||||||||||||
| DEBUG = True | ||||||||||||
|
|
||||||||||||
|
||||||||||||
| # WARNING: The default ALLOWED_HOSTS is only suitable for local development. | |
| # In production or containerized environments, you MUST set the ALLOWED_HOSTS environment variable | |
| # to include all hostnames and domains that will access this service (e.g., service names, load balancers, external domains). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| """ | ||
| URL configuration for app project. | ||
|
|
||
| The `urlpatterns` list routes URLs to views. For more information please see: | ||
| https://docs.djangoproject.com/en/5.2/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 path | ||
| import app.views | ||
|
|
||
|
|
||
| urlpatterns = [ | ||
| path('admin/', admin.site.urls), | ||
|
|
||
| # Service Status | ||
| # - `HEALTHCHECK` support for Docker Container | ||
| path('health/', app.views.health), | ||
|
|
||
| # Swagger Support | ||
| path('swagger/', app.views.schema.with_ui('swagger')), | ||
| path('swagger/(?P<format>\\.json|\\.yaml)', app.views.schema.without_ui()), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| from django.http import HttpRequest | ||
| from django.http import HttpResponse | ||
| from django.views.decorators.http import require_http_methods | ||
| from drf_yasg.openapi import Contact | ||
| from drf_yasg.openapi import Info | ||
| from drf_yasg.utils import swagger_auto_schema | ||
|
hepheir marked this conversation as resolved.
|
||
| from drf_yasg.views import get_schema_view | ||
| from rest_framework.permissions import AllowAny | ||
|
|
||
|
|
||
| schema = get_schema_view( | ||
| info=Info( | ||
| title="Time Limit Exceeded :: Authentication API", | ||
| default_version='1.0.0', | ||
| description="", | ||
| contact=Contact(email="202115064@sangmyung.kr"), | ||
| ), | ||
| public=True, | ||
| permission_classes=[AllowAny], | ||
| ) | ||
|
|
||
|
|
||
| @require_http_methods(["GET"]) | ||
| @swagger_auto_schema(method='get') | ||
| def health(request: HttpRequest): | ||
| return HttpResponse(status=200) | ||
|
hepheir marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """ | ||
| WSGI config for app project. | ||
|
|
||
| It exposes the WSGI callable as a module-level variable named ``application``. | ||
|
|
||
| For more information on this file, see | ||
| https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/ | ||
| """ | ||
|
|
||
| import os | ||
|
|
||
| from django.core.wsgi import get_wsgi_application | ||
|
|
||
| os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') | ||
|
|
||
| application = get_wsgi_application() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #!/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', 'app.settings') | ||
| 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() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| django | ||
| djangorestframework | ||
| drf-yasg | ||
| gunicorn |
Uh oh!
There was an error while loading. Please reload this page.