diff --git a/CHANGELOG.md b/CHANGELOG.md index 6414a57f..b09d5499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to ### Added - ✨(backend) monitor throttling rate failure through sentry #964 +- 🚀(paas) add PaaS deployment scripts, tested on Scalingo #957 ### Changed diff --git a/Procfile b/Procfile new file mode 100644 index 00000000..baed9d65 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: bin/buildpack_start.sh +postdeploy: python manage.py migrate diff --git a/bin/buildpack_postcompile.sh b/bin/buildpack_postcompile.sh new file mode 100755 index 00000000..0bbd7c46 --- /dev/null +++ b/bin/buildpack_postcompile.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -o errexit # always exit on error +set -o pipefail # don't ignore exit codes when piping output + +echo "-----> Running post-compile script" + +# Cleanup +rm -rf docker docs env.d gitlint diff --git a/bin/buildpack_postfrontend.sh b/bin/buildpack_postfrontend.sh new file mode 100755 index 00000000..9f860566 --- /dev/null +++ b/bin/buildpack_postfrontend.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -o errexit # always exit on error +set -o pipefail # don't ignore exit codes when piping output + +echo "-----> Running post-frontend script" + +# Move the frontend build to the nginx root and clean up +mkdir -p build/ +mv src/frontend/dist build/frontend-out + +mv src/backend/* ./ +mv deploy/paas/* ./ + +echo "3.13" > .python-version +echo "." > requirements.txt diff --git a/bin/buildpack_start.sh b/bin/buildpack_start.sh new file mode 100755 index 00000000..64274804 --- /dev/null +++ b/bin/buildpack_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Start the Django backend server +gunicorn -b 0.0.0.0:8000 meet.wsgi:application --log-file - & + +# Start the Nginx server +bin/run & + +# if the current shell is killed, also terminate all its children +trap "pkill SIGTERM -P $$" SIGTERM + +# wait for a single child to finish, +wait -n +# then kill all the other tasks +pkill -P $$ diff --git a/deploy/paas/servers.conf.erb b/deploy/paas/servers.conf.erb new file mode 100644 index 00000000..a649cf2b --- /dev/null +++ b/deploy/paas/servers.conf.erb @@ -0,0 +1,52 @@ +# ERB templated nginx configuration +# see https://doc.scalingo.com/platform/deployment/buildpacks/nginx + +upstream backend_server { + server localhost:8000 fail_timeout=0; +} + +server { + listen <%= ENV["PORT"] %>; + server_name _; + server_tokens off; + + root /app/build/frontend-out; + + # Django rest framework + location ^~ /api/ { + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_redirect off; + proxy_pass http://backend_server; + } + + # Django admin + location ^~ /admin/ { + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_redirect off; + proxy_pass http://backend_server; + } + + # Serve static files with caching + location ~* ^/assets/.*\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 30d; + add_header Cache-Control "public, max-age=2592000"; + } + + # Serve static files + location / { + try_files $uri $uri/ /index.html; + # Add no-cache headers + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; # HTTP 1.0 header for backward compatibility + add_header Expires 0; + } + + # Optionally, handle 404 errors by redirecting to index.html + error_page 404 =200 /index.html; +} diff --git a/src/backend/meet/settings.py b/src/backend/meet/settings.py index 636dda27..4b4a8ba9 100755 --- a/src/backend/meet/settings.py +++ b/src/backend/meet/settings.py @@ -13,11 +13,12 @@ https://docs.djangoproject.com/en/3.1/ref/settings/ # pylint: disable=too-many-lines import json -from os import path +from os import environ, path from socket import gethostbyname, gethostname from django.utils.translation import gettext_lazy as _ +import dj_database_url import sentry_sdk from configurations import Configuration, values from lasuite.configuration.values import SecretFileValue @@ -92,7 +93,9 @@ class Base(Configuration): # Database DATABASES = { - "default": { + "default": dj_database_url.config() + if environ.get("DATABASE_URL") + else { "ENGINE": values.Value( "django.db.backends.postgresql_psycopg2", environ_name="DB_ENGINE", diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml index 14ab34f7..38c24960 100644 --- a/src/backend/pyproject.toml +++ b/src/backend/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "Brotli==1.2.0", "brevo-python==1.2.0", "celery[redis]==5.5.3", + "dj-database-url==3.1.0", "django-configurations==2.5.1", "django-cors-headers==4.9.0", "django-countries==8.0.0",