Skip to content

Commit

Permalink
add latest fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jsatt committed Jan 15, 2021
1 parent a6e632b commit f6f7712
Show file tree
Hide file tree
Showing 18 changed files with 2,842 additions and 135 deletions.
File renamed without changes.
20 changes: 11 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
FROM python:3.8
FROM python:3.8-slim-buster

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV POETRY_VIRTUALENVS_CREATE=0
ENV USER=app_user

RUN adduser --uid 1000 --gecos --quiet --disabled-password app_user
RUN adduser --uid 1000 --gecos --quiet --disabled-password $USER

RUN mkdir -p /usr/src/app \
&& chown app_user.app_user /usr/src/app
&& chown $USER.$USER /usr/src/app
WORKDIR /usr/src/app

COPY --chown=app_user requirements.txt ./
COPY --chown=$USER pyproject.toml poetry.lock ./

ARG PIP_ARGS=
ARG POETRY_ARGS=
RUN set -eux \
&& apt update \
&& apt upgrade -y \
&& apt install -y curl\
&& pip3 install -r requirements.txt $PIP_ARGS \
&& pip3 install poetry \
&& poetry install --no-root --no-interaction $POETRY_ARGS \
&& apt autoremove -y \
&& rm -rf /root/.cache/pip /var/cache/apt
&& rm -rf /root/.cache/pip /root/.cache/pypoetry /var/cache/apt

COPY --chown=app_user . .
COPY --chown=$USER . .

USER app_user
USER $USER

CMD ["/usr/local/bin/gunicorn", "base_app.asgi:application", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]

7 changes: 7 additions & 0 deletions base_app/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pythonjsonlogger.jsonlogger import JsonFormatter


class CustomJsonFormatter(JsonFormatter):
def add_fields(self, log_record, record, message_dict): # pragma: no cover
super().add_fields(log_record, record, message_dict)
log_record['severity'] = record.levelname
74 changes: 56 additions & 18 deletions base_app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from utils.environment import Env

BASE_DIR = (environ.Path(__file__) - 2)()
env = environ.Env(os.path.join(BASE_DIR, '.env'))
env = Env(os.path.join(BASE_DIR, '.env'))

BASE_URL = env.str('BASE_URL', default='localhost')
TESTING = env.bool('TESTING', default=False)
Expand Down Expand Up @@ -113,6 +113,40 @@
},
]

session_engine = env.str('SESSION_ENGINE', default='cache')
if session_engine == 'cache':
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'sessions'
CACHES['sessions'] = env.cache_opts('SESSION_CACHE_URL', default='dummycache://', options={
'OPTIONS': {'SERIALIZER': 'django_redis.serializers.json.JSONSerializer'},
})
elif session_engine == 'db':
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
else:
SESSION_ENGINE = session_engine

# FILE STORAGE
media_storage_backend = env.str('MEDIA_STORAGE_BACKEND', default='local')
MEDIA_ROOT = env.str('MEDIA_ROOT', default='')
MEDIA_URL = env.str('MEDIA_URL', default='')

if media_storage_backend == 'local':
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'

elif media_storage_backend == 'google':
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = env.str('MEDIA_STORAGE_BUCKET')
GS_LOCATION = env.str('MEDIA_STORAGE_LOCATION', default='')
GS_PROJECT_ID = env.str('MEDIA_STORAGE_PROJECT_ID', default=None)
GS_FILE_OVERWRITE = False

static_storage_backend = env.str('STATIC_STORAGE_BACKEND', default='local')
STATIC_ROOT = env.str('STATIC_ROOT', default='static/')
STATIC_URL = env.str('STATIC_URL', default='/static/')

if static_storage_backend == 'local':
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'

# LOGGING
log_level = env.str('LOG_LEVEL', default='INFO')
log_formatter = env.str('LOG_FORMATTER', default='plain')
Expand All @@ -125,7 +159,7 @@
'disable_existing_loggers': False,
'formatters': {
'json': {
'class': 'pythonjsonlogger.jsonlogger.JsonFormatter',
'class': 'base_app.logging.CustomJsonFormatter',
'format': log_format,
},
'plain': {
Expand Down Expand Up @@ -187,7 +221,7 @@
#########
# SENTRY
#########
if USE_SENTRY:
if USE_SENTRY and not TESTING:
import sentry_sdk
from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.django import DjangoIntegration
Expand All @@ -212,46 +246,48 @@
#########
# DATADOG
#########
if USE_DATADOG:
DATADOG_SERVICE = env.str('DD_SERVICE', default='base_app')
DATADOG_ENVIRONMENT = env.str('DD_ENV', default='development')
DATADOG_TAGS = env.list('DD_TAGS', default=[])

if USE_DATADOG and not TESTING:
import datadog
from ddtrace import config as dd_config

datadog_service = env.str('DD_SERVICE', default='base_app')
datadog_environment = env.str('DD_ENV', default='development')
datadog_version = env.str('DD_VERSION', default='')
datadog_agent_hostname = env.str('DD_AGENT_SERVICE_HOST', default='localhost')
datadog_agent_port = env.str('DD_AGENT_SERVICE_PORT', default='8125')
datadog_statsd_port = env.str('DD_STATSD_SERVICE_PORT', default='8126')
datadog_tags = env.list('DD_TAGS', default=[])

dd_tracer.configure(
enabled=True,
hostname=datadog_agent_hostname,
port=datadog_agent_port,
dogstatsd_url=f'udp://{datadog_agent_hostname}:{datadog_statsd_port}',
)
dd_tracer.set_tags({
'env': datadog_environment,
'env': DATADOG_ENVIRONMENT,
'version': datadog_version,
**dict(t.split(':') for t in datadog_tags),
**dict(t.split(':') for t in DATADOG_TAGS),
})
dd_config.analytics_enabled = True
dd_config.health_metrics_enabled = True
dd_config.celery['analytics_enabled'] = True
dd_config.celery['distributed_tracing'] = True
dd_config.celery['producer_service_name'] = f'{datadog_service}-celery-queue'
dd_config.celery['worker_service_name'] = f'{datadog_service}-celery'
dd_config.celery['producer_service_name'] = f'{DATADOG_SERVICE}-celery-queue'
dd_config.celery['worker_service_name'] = f'{DATADOG_SERVICE}-celery'
dd_config.django['analytics_enabled'] = True
dd_config.django['cache_service_name'] = f'{datadog_service}-cache'
dd_config.django['database_service_name_prefix'] = f'{datadog_service}-'
dd_config.django['service_name'] = datadog_service
dd_config.django['cache_service_name'] = f'{DATADOG_SERVICE}-cache'
dd_config.django['database_service_name_prefix'] = f'{DATADOG_SERVICE}-'
dd_config.django['service_name'] = DATADOG_SERVICE
dd_config.postgres['analytics_enabled'] = True
dd_config.requests['analytics_enabled'] = True

datadog.initialize(
statsd_host=datadog_agent_hostname,
statsd_port=datadog_statsd_port,
statsd_namespace=datadog_service,
statsd_constant_tags=datadog_tags,
statsd_namespace=DATADOG_SERVICE,
statsd_constant_tags=DATADOG_TAGS,
)
else:
dd_tracer.configure(enabled=False)
Expand All @@ -277,8 +313,8 @@
'fanout_prefix': True,
'fanout_patterns': True,
}
CELERY_BROKER_URL = env.str('CELERY_BROKER_URL', default='dummycache://')
CELERY_RESULT_BACKEND = env.str('CELERY_RESULT_BACKEND', default='dummycache://')
CELERY_BROKER_URL = env.str('CELERY_BROKER_URL', default='redis://127.0.0.1:6379/2')
CELERY_RESULT_BACKEND = env.str('CELERY_RESULT_BACKEND', default='redis://127.0.0.1:6379/3')
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_ACKS_LATE = True
CELERY_TIMEZONE = TIME_ZONE
Expand All @@ -289,5 +325,7 @@
# TESTS
#########
if TESTING:
TEST_RUNNER = 'utils.test.PytestTestRunner'
CELERY_TASK_ALWAYS_EAGER = True
CELERY_TASK_EAGER_PROPAGATES = True
LOGGING['handlers']['console']['level'] = 'CRITICAL' # type: ignore[index] # mypy mistakes dict for object
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ services:
- db
tty: true
ports:
- "${COMPOSE_WEB_PORT:-8002}:8000"
- "${COMPOSE_WEB_PORT:-8000}:8000"

task_worker:
<<: *app-common
Expand Down
Loading

0 comments on commit f6f7712

Please sign in to comment.