Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,37 +124,40 @@ jobs:
echo 'CONN_MAX_AGE=60' >> docker.prod.env
echo 'CONN_HEALTH_CHECKS="true"' >> docker.prod.env
echo 'SANDBOX_DISABLE_PROC="true"' >> docker.prod.env
echo 'ALLOWED_HOSTS="backend,localhost,127.0.0.1"' >> docker.prod.env
echo 'ALLOWED_HOSTS="backend,backend-green,backend-blue,localhost,127.0.0.1"' >> docker.prod.env
echo 'USE_SANDBOX_JAIL="on"' >> docker.prod.env
echo 'CI=true' >> docker.prod.env

- name: Comment out SSL server configuration from nginx
run: |
sed -i '/{{HTTPS_SERVER_BLOCK_START}}/,/{{HTTPS_SERVER_BLOCK_END}}/s/^/#/' nginx/production.conf
sed -i '/{{HTTPS_SERVER_BLOCK_START}}/,/{{HTTPS_SERVER_BLOCK_END}}/s/^/#/' nginx/production/default.conf

- name: Bring up postgres and nginx containers
run: |
cp ./nginx/production/runtime/geo.conf.example ./nginx/production/runtime/geo.conf
cp ./nginx/production/runtime/upstream.conf.example ./nginx/production/runtime/upstream.conf
docker compose -f docker-compose.prod.yaml build nginx
docker compose -f docker-compose.prod.yaml up -d postgres nginx
timeout 15s docker compose -f docker-compose.prod.yaml logs -f || true
docker compose logs nginx | grep "ready for start up"
! docker compose logs nginx | grep -q "nginx-1 exited with code"

- name: Build and bring up up backend container
run: |
docker compose -f docker-compose.prod.yaml build backend
docker compose -f docker-compose.prod.yaml up -d backend
docker compose -f docker-compose.prod.yaml build backend-blue
docker compose -f docker-compose.prod.yaml up -d backend-blue
timeout 15s docker compose -f docker-compose.prod.yaml logs -f || true

- name: Build and bring up up frontend container
run: |
docker compose -f docker-compose.prod.yaml build frontend
docker compose -f docker-compose.prod.yaml up -d frontend
docker compose -f docker-compose.prod.yaml build frontend-blue
docker compose -f docker-compose.prod.yaml up -d frontend-blue
timeout 15s docker compose -f docker-compose.prod.yaml logs -f || true

- name: Sanity check the endpoints
run: |
curl --silent http://localhost:8080/ | head -c 256
curl --silent http://localhost:8000/api/ | jq
curl --silent http://localhost/healthz | jq
curl --silent http://localhost/api/healthz | jq

- name: Shut everything down
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ docker.prod.env
send_update.py
update.sh
.venv/
nginx/production/runtime/*.conf
!nginx/production/runtime/*.conf.example
.deploy.env
1 change: 1 addition & 0 deletions backend/coreapp/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def middleware(request: HttpRequest) -> Response:
def is_public_get_request(req: Request) -> bool:
public_paths = [
"/api/compiler",
"/api/healthz$",
"/api/library",
"/api/platform",
"/api/preset",
Expand Down
8 changes: 8 additions & 0 deletions backend/coreapp/tests/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@


class RequestTests(APITestCase):
def test_health_check_is_stateless(self) -> None:
response = self.client.get(reverse("healthz"), HTTP_USER_AGENT="browser")

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {"ok": True})
self.assertEqual(Profile.objects.count(), 0)
self.assertNotIn("sessionid", response.cookies)

def test_cookie_less_current_user_does_not_create_profile(self) -> None:
"""
Ensure that a passive current-user read does not create a session profile.
Expand Down
2 changes: 2 additions & 0 deletions backend/coreapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from coreapp.views import (
compiler,
health,
library,
platform,
preset,
Expand All @@ -22,6 +23,7 @@
urlpatterns = [
*router.urls,
path("compiler", compiler.CompilerDetail.as_view(), name="compiler"),
path("healthz", health.HealthCheck.as_view(), name="healthz"),
path(
"compiler/<str:platform>/<str:compiler>",
compiler.SingleCompilerDetail.as_view(),
Expand Down
15 changes: 15 additions & 0 deletions backend/coreapp/views/health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.db import connection
from rest_framework import status
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView


class HealthCheck(APIView):
def get(self, request: Request) -> Response:
try:
connection.ensure_connection()
except Exception:
return Response({"ok": False}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

return Response({"ok": True})
2 changes: 0 additions & 2 deletions backend/docker_prod_entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ until nc -z ${DB_HOST} ${DB_PORT} > /dev/null; do
sleep 1
done

uv run /backend/manage.py migrate

if [ -z "$CI" ]; then
uv run manage.py clearsessions
uv run /backend/housekeeping.py
Expand Down
Loading