Improve development docker compose (#324)

* 🐛(docker) stop ALL services when running make stop

* ✨(docker) make sure backend is healthy before exiting docker compose up

* 🧑‍💻 (docker) use default user and not root for healthchecks

* ➖(backend) Remove dockerflow

* ✨(backend) add healthcheck route, and suppress healthcheck access logs

* 🚨(backend) ignore monkey patching

* 🚨(backend) coderabbitai + linter fixes

* 🚚(backend) remove version in healthz route

* 🔨(docker) use python http lib instead of curl and remove curl from dockerfile
This commit is contained in:
Stanislas Bruhière
2025-09-02 12:10:52 +02:00
committed by GitHub
parent 233e412ccd
commit 38439b95ce
8 changed files with 38 additions and 37 deletions
+3 -3
View File
@@ -134,11 +134,11 @@ logs: ## display all services logs (follow mode)
.PHONY: logs
start: ## start all development services
@$(COMPOSE) up --force-recreate --build -d frontend-dev backend-dev celery-dev mta-in
@$(COMPOSE) up --force-recreate --build -d frontend-dev backend-dev celery-dev mta-in --wait
.PHONY: start
start-minimal: ## start minimal services (backend, frontend, keycloak and DB)
@$(COMPOSE) up --force-recreate --build -d backend-db frontend-dev keycloak
@$(COMPOSE) up --force-recreate --build -d backend-db frontend-dev keycloak --wait
.PHONY: start-minimal
status: ## an alias for "docker compose ps"
@@ -146,7 +146,7 @@ status: ## an alias for "docker compose ps"
.PHONY: status
stop: ## stop all development services
@$(COMPOSE) stop
@$(COMPOSE) --profile "*" stop
.PHONY: stop
restart: ## restart all development services
-1
View File
@@ -4,7 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/_config.sh"
_dc_run \
-e DJANGO_CONFIGURATION=Test \
-e DJANGO_ENABLE_DOCKERFLOW=0 \
--no-deps \
backend-dev \
python manage.py spectacular \
+12 -2
View File
@@ -6,7 +6,7 @@ services:
ports:
- "8912:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 1s
timeout: 2s
retries: 300
@@ -100,6 +100,11 @@ services:
volumes:
- ./src/backend:/app
- ./data/static:/data/static
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request as u; u.urlopen('http://localhost:8000/healthz/', timeout=1)"]
interval: 3s
retries: 3
start_period: 10s
depends_on:
postgresql:
condition: service_healthy
@@ -135,11 +140,16 @@ services:
volumes:
- ./src/backend:/app
- ./data/static:/data/static
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request as u; u.urlopen('http://localhost:8000/healthz/', timeout=1)"]
interval: 3s
retries: 3
start_period: 10s
depends_on:
postgresql:
condition: service_healthy
restart: true
backend-poetry:
profiles:
- tools
-10
View File
@@ -547,8 +547,6 @@ class Base(Configuration):
environ_prefix=None,
)
ENABLE_DOCKERFLOW = values.BooleanValue(default=True)
# AI
AI_API_KEY = values.Value(None, environ_name="AI_API_KEY", environ_prefix=None)
AI_BASE_URL = values.Value(None, environ_name="AI_BASE_URL", environ_prefix=None)
@@ -618,14 +616,6 @@ class Base(Configuration):
"api_url": "/api/v1.0",
}
# pylint: disable=invalid-name
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Add dockerflow if ENABLE_DOCKERFLOW is True
if self.ENABLE_DOCKERFLOW:
self.INSTALLED_APPS += ["dockerflow.django"]
self.MIDDLEWARE += ["dockerflow.django.middleware.DockerflowMiddleware"]
# pylint: disable=invalid-name
@property
def ENVIRONMENT(self):
+6
View File
@@ -4,6 +4,7 @@ from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.http import HttpResponse
from django.urls import include, path, re_path
from drf_spectacular.views import (
@@ -15,6 +16,11 @@ from drf_spectacular.views import (
urlpatterns = [
path(settings.ADMIN_URL, admin.site.urls),
path("", include("core.urls")),
path(
"healthz/",
lambda _: HttpResponse("OK"),
name="healthcheck",
),
]
if settings.DEBUG:
+15
View File
@@ -11,6 +11,21 @@ import os
from configurations.wsgi import get_wsgi_application
# pylint: disable=all
# Suppress access logs for healthcheck route
try:
import django.core.servers.basehttp
class QuietWSGIRequestHandler(django.core.servers.basehttp.WSGIRequestHandler):
def log_message(self, format, *args):
path = getattr(self, "path", "")
if path.strip("/") == "healthz":
return
super().log_message(format, *args)
django.core.servers.basehttp.WSGIRequestHandler = QuietWSGIRequestHandler
except ImportError:
pass
# pylint: enable=all
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "messages.settings")
os.environ.setdefault("DJANGO_CONFIGURATION", "Development")
+2 -20
View File
@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand.
[[package]]
name = "aiofiles"
@@ -1102,24 +1102,6 @@ idna = ["idna (>=3.7)"]
trio = ["trio (>=0.23)"]
wmi = ["wmi (>=1.5.1)"]
[[package]]
name = "dockerflow"
version = "2024.4.2"
description = "Python tools and helpers for Mozilla's Dockerflow"
optional = false
python-versions = "<4,>=3.7"
groups = ["main"]
files = [
{file = "dockerflow-2024.4.2-py2.py3-none-any.whl", hash = "sha256:b9f92455449ba46555f57db34cccefc4c49d3533c67793624ab7e80a1625caa7"},
{file = "dockerflow-2024.4.2.tar.gz", hash = "sha256:f4216a3a809093860d7b2db84ba0a25c894cb8eb98b74f4f6a04badbc4f6b0a4"},
]
[package.extras]
django = ["django"]
fastapi = ["asgiref", "fastapi"]
flask = ["blinker", "flask"]
sanic = ["sanic"]
[[package]]
name = "drf-spectacular"
version = "0.28.0"
@@ -3578,4 +3560,4 @@ dev = ["django-extensions", "drf-spectacular-sidecar", "flower", "pip-audit", "p
[metadata]
lock-version = "2.1"
python-versions = ">=3.13,<4.0"
content-hash = "22260b6b6ae4581ad82aaa98baf1b138d2cf63b0f2a7e101be56b2b72d8768a4"
content-hash = "a9c4fa07cc7fb32814d33932d885c48f715939de2f09eaae42fca64457cdbc81"
-1
View File
@@ -43,7 +43,6 @@ dependencies = [
"djangorestframework==3.15.2",
"dkimpy==1.1.8",
"dnspython==2.7.0",
"dockerflow==2024.4.2",
"drf_spectacular==0.28.0",
"opensearch-py==2.8.0",
"factory_boy==3.3.1",