-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/production containers #87
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
Changes from all commits
f1a5a47
57fc4bc
7c748d1
60be35d
952c439
e511b3b
45c1292
45c2f61
7007365
00a810d
360a576
e5b0fc3
8673a59
c7f38aa
2e82d7b
b015206
253986b
fabcd30
9a42984
bc0ec89
99d8546
e236164
5203182
a2cabe4
fc5ccfe
35bd17c
9831d5a
5622b83
3c8f01c
8013bad
02726cd
189acc7
1fbd233
3a37f4d
39e5516
edf371f
6e65a73
145b074
044eee3
b1f03d6
ec0e9e0
6f51348
11c3925
8afaf24
0538d9c
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,5 @@ | ||
| POSTGRES_USER= | ||
| POSTGRES_PASSWORD= | ||
| POSTGRES_DB= | ||
| DJANGO_SECRET_KEY= | ||
| APP_VERSION= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,24 @@ | ||
| FROM python:3.11 | ||
| FROM python:3.11-slim-trixie | ||
|
|
||
| # Set environment variables. | ||
| ENV PYTHONDONTWRITEBYTECODE=1 | ||
| ENV PYTHONUNBUFFERED=1 | ||
|
|
||
| # Install dependencies. | ||
| RUN apt update | ||
| RUN pip install gunicorn | ||
|
|
||
| WORKDIR /usr/src/app/backend | ||
| COPY requirements.txt . | ||
| RUN pip install -U pip pip-tools && pip-sync | ||
| RUN pip install -r requirements.txt --no-cache-dir | ||
|
|
||
| # Set working directory. | ||
| WORKDIR /usr/src/app | ||
|
|
||
| # Copy project files. | ||
| COPY . . | ||
|
|
||
| CMD python manage.py check && \ | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved this to the compose file so this Dockerfile can be used for both prod (with Gunicorn) and dev (Django dev server). The dev container does not need Gunicorn, of course, but that is a small price to pay for having one container that serves both profiles.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of using the same image for development and production. In development, I want all images to derive from buildpack-deps in order to save disk space. In production, it is preferable to go for leaner images. If I have to start using those leaner images in development, I will end up with lots of disjoint images on disk that are small in themselves but that effectively make me pay multiple times for software that I tend to use in nearly every project.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Point taken. I definitely support the idea of splitting them up. |
||
| python manage.py migrate && \ | ||
| python manage.py runserver --settings glue --pythonpath .. 0.0.0.0:8000 | ||
| # Create a directory for Gunicorn logs (production). | ||
| RUN mkdir -p /usr/src/app/logs | ||
|
|
||
| # Expose port. | ||
| EXPOSE 8000 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,107 +1,110 @@ | ||
| INSTALLED_APPS = [ | ||
| "django.contrib.admin", | ||
| "django.contrib.auth", | ||
| "django.contrib.contenttypes", | ||
| "django.contrib.sessions", | ||
| "django.contrib.messages", | ||
| "livereload", | ||
| "django.contrib.staticfiles", | ||
| "rest_framework", | ||
| "django.contrib.sites", | ||
| "rest_framework.authtoken", | ||
| "dj_rest_auth", | ||
| "dj_rest_auth.registration", | ||
| "allauth", | ||
| "allauth.account", | ||
| # Required for deleting accounts, but not actually used, | ||
| # cf. https://github.com/iMerica/dj-rest-auth/pull/110. | ||
| "allauth.socialaccount", | ||
| "user", | ||
| "revproxy", | ||
| "problem", | ||
| "annotation", | ||
| ] | ||
|
|
||
| MIDDLEWARE = [ | ||
| "django.middleware.security.SecurityMiddleware", | ||
| "django.contrib.sessions.middleware.SessionMiddleware", | ||
| "django.middleware.locale.LocaleMiddleware", | ||
| "django.middleware.common.CommonMiddleware", | ||
| "django.middleware.csrf.CsrfViewMiddleware", | ||
| "django.contrib.auth.middleware.AuthenticationMiddleware", | ||
| "django.contrib.messages.middleware.MessageMiddleware", | ||
| "django.middleware.clickjacking.XFrameOptionsMiddleware", | ||
| "allauth.account.middleware.AccountMiddleware", | ||
| ] | ||
|
|
||
| # Internationalization | ||
| # https://docs.djangoproject.com/en/3.0/topics/i18n/ | ||
| LANGUAGES = [ | ||
| ("en", "English"), | ||
| ("nl", "Nederlands"), | ||
| ] | ||
| LANGUAGE_CODE = "en" | ||
|
|
||
| TIME_ZONE = "Europe/Amsterdam" | ||
|
|
||
| USE_I18N = True | ||
|
|
||
| USE_TZ = True # Authentication | ||
| REST_FRAMEWORK = { | ||
| "DEFAULT_AUTHENTICATION_CLASSES": [ | ||
| "rest_framework.authentication.TokenAuthentication", | ||
| "rest_framework.authentication.SessionAuthentication", | ||
| ] | ||
| } | ||
|
|
||
| AUTH_USER_MODEL = "user.User" | ||
| ACCOUNT_EMAIL_VERIFICATION = "mandatory" | ||
| ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"] | ||
|
|
||
| SITE_ID = 1 | ||
| SITE_NAME = "langpro_annotator" | ||
|
|
||
| # Remove this setting in production! | ||
| EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" | ||
|
|
||
| HOST = "localhost:8000" | ||
|
|
||
| REST_AUTH = { | ||
| "USER_DETAILS_SERIALIZER": "user.serializers.CustomUserDetailsSerializer", | ||
| } | ||
|
|
||
| LOGGING = { | ||
| "version": 1, | ||
| "disable_existing_loggers": False, | ||
| "formatters": { | ||
| "verbose": { | ||
| "format": "{levelname} {asctime} {module} {message}", | ||
| "style": "{", | ||
| }, | ||
| "simple": { | ||
| "format": "{levelname} {message}", | ||
| "style": "{", | ||
| }, | ||
| }, | ||
| "handlers": { | ||
| "console": { | ||
| "level": "INFO", | ||
| "class": "logging.StreamHandler", | ||
| "formatter": "simple", | ||
| }, | ||
| }, | ||
| "loggers": { | ||
| "django": { | ||
| "handlers": ["console"], | ||
| "level": "INFO", | ||
| "propagate": False, | ||
| }, | ||
| "LangProAnnotator": { | ||
| "handlers": ["console"], | ||
| "level": "INFO", | ||
| "propagate": False, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| LANGPRO_URL = "http://localhost:8080" | ||
| import os | ||
|
|
||
|
|
||
| INSTALLED_APPS = [ | ||
| "django.contrib.admin", | ||
| "django.contrib.auth", | ||
| "django.contrib.contenttypes", | ||
| "django.contrib.sessions", | ||
| "django.contrib.messages", | ||
| "livereload", | ||
| "django.contrib.staticfiles", | ||
| "rest_framework", | ||
| "django.contrib.sites", | ||
| "rest_framework.authtoken", | ||
| "dj_rest_auth", | ||
| "dj_rest_auth.registration", | ||
| "allauth", | ||
| "allauth.account", | ||
| # Required for deleting accounts, but not actually used, | ||
| # cf. https://github.com/iMerica/dj-rest-auth/pull/110. | ||
| "allauth.socialaccount", | ||
| "user", | ||
| "revproxy", | ||
| "problem", | ||
| "annotation", | ||
| ] | ||
|
|
||
| MIDDLEWARE = [ | ||
| "django.middleware.security.SecurityMiddleware", | ||
| "django.contrib.sessions.middleware.SessionMiddleware", | ||
| "django.middleware.locale.LocaleMiddleware", | ||
| "django.middleware.common.CommonMiddleware", | ||
| "django.middleware.csrf.CsrfViewMiddleware", | ||
| "django.contrib.auth.middleware.AuthenticationMiddleware", | ||
| "django.contrib.messages.middleware.MessageMiddleware", | ||
| "django.middleware.clickjacking.XFrameOptionsMiddleware", | ||
| "allauth.account.middleware.AccountMiddleware", | ||
| ] | ||
|
|
||
| # Internationalization | ||
| # https://docs.djangoproject.com/en/3.0/topics/i18n/ | ||
| LANGUAGES = [ | ||
| ("en", "English"), | ||
| ("nl", "Nederlands"), | ||
| ] | ||
| LANGUAGE_CODE = "en" | ||
|
|
||
| TIME_ZONE = "Europe/Amsterdam" | ||
|
|
||
| USE_I18N = True | ||
|
|
||
| USE_TZ = True # Authentication | ||
| REST_FRAMEWORK = { | ||
| "DEFAULT_AUTHENTICATION_CLASSES": [ | ||
| "rest_framework.authentication.TokenAuthentication", | ||
| "rest_framework.authentication.SessionAuthentication", | ||
| ] | ||
| } | ||
|
|
||
| AUTH_USER_MODEL = "user.User" | ||
| ACCOUNT_EMAIL_VERIFICATION = "mandatory" | ||
| ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"] | ||
|
|
||
| SITE_ID = 1 | ||
| SITE_NAME = "langpro_annotator" | ||
|
|
||
| # Remove this setting in production! | ||
| EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" | ||
|
|
||
| HOST = "localhost:8000" | ||
|
|
||
| REST_AUTH = { | ||
| "USER_DETAILS_SERIALIZER": "user.serializers.CustomUserDetailsSerializer", | ||
| } | ||
|
|
||
| LOGGING = { | ||
| "version": 1, | ||
| "disable_existing_loggers": False, | ||
| "formatters": { | ||
| "verbose": { | ||
| "format": "{levelname} {asctime} {module} {message}", | ||
| "style": "{", | ||
| }, | ||
| "simple": { | ||
| "format": "{levelname} {message}", | ||
| "style": "{", | ||
| }, | ||
| }, | ||
| "handlers": { | ||
| "console": { | ||
| "level": "INFO", | ||
| "class": "logging.StreamHandler", | ||
| "formatter": "simple", | ||
| }, | ||
| }, | ||
| "loggers": { | ||
| "django": { | ||
| "handlers": ["console"], | ||
| "level": "INFO", | ||
| "propagate": False, | ||
| }, | ||
| "LangProAnnotator": { | ||
| "handlers": ["console"], | ||
| "level": "INFO", | ||
| "propagate": False, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| LANGPRO_URL = os.environ.get('LANGPRO_CONTAINER') or 'http://localhost:8080' |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your wish to have one You can a best of both worlds: inject a separate |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| from django.views.decorators.csrf import ensure_csrf_cookie | ||
| from django.http import JsonResponse | ||
|
|
||
| @ensure_csrf_cookie | ||
| def csrf_token(request): | ||
| return JsonResponse({"detail": "CSRF cookie set"}) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ Django>=4.0.1,<5 | |
| djangorestframework | ||
| django-livereload-server | ||
| django-revproxy>=0.10.0 | ||
| psycopg2 | ||
| psycopg2-binary | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When using
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://www.psycopg.org/docs/install.html#psycopg-vs-psycopg-binary If we can make it work with the source package, that is probably better. The slimmer the image, the more tools you have to install yourself in the Dockerfile, generally.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, I'll get it to work with the source package! 👍 |
||
| pytest | ||
| pytest-django | ||
| pytest-xdist | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.