From c215eb4e66c9ad39337ffa9a16c1b97b1a54578f Mon Sep 17 00:00:00 2001 From: Patrick Arminio Date: Fri, 13 Feb 2026 16:28:23 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Migrate=20to=20`DATABA?= =?UTF-8?q?SE=5FURL`=20instead=20of=20separate=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shortcake-Parent: master --- .env | 3 +++ backend/app/alembic/env.py | 2 +- backend/app/core/config.py | 19 +------------------ backend/app/core/db.py | 2 +- compose.yml | 12 ++---------- 5 files changed, 8 insertions(+), 30 deletions(-) diff --git a/.env b/.env index 1d44286e25..1e73d045f4 100644 --- a/.env +++ b/.env @@ -38,6 +38,9 @@ POSTGRES_DB=app POSTGRES_USER=postgres POSTGRES_PASSWORD=changethis +# Database URL for the backend (uses localhost for local dev, overridden in compose.yml for Docker) +DATABASE_URL=postgresql+psycopg://postgres:changethis@localhost:5432/app + SENTRY_DSN= # Configure these with your own Docker registry images diff --git a/backend/app/alembic/env.py b/backend/app/alembic/env.py index 5e2c22f844..7f407fabb9 100755 --- a/backend/app/alembic/env.py +++ b/backend/app/alembic/env.py @@ -31,7 +31,7 @@ def get_url(): - return str(settings.SQLALCHEMY_DATABASE_URI) + return str(settings.DATABASE_URL) def run_migrations_offline(): diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 650b9f7910..49a70aa3d6 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -50,23 +50,7 @@ def all_cors_origins(self) -> list[str]: PROJECT_NAME: str SENTRY_DSN: HttpUrl | None = None - POSTGRES_SERVER: str - POSTGRES_PORT: int = 5432 - POSTGRES_USER: str - POSTGRES_PASSWORD: str = "" - POSTGRES_DB: str = "" - - @computed_field # type: ignore[prop-decorator] - @property - def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: - return PostgresDsn.build( - scheme="postgresql+psycopg", - username=self.POSTGRES_USER, - password=self.POSTGRES_PASSWORD, - host=self.POSTGRES_SERVER, - port=self.POSTGRES_PORT, - path=self.POSTGRES_DB, - ) + DATABASE_URL: PostgresDsn SMTP_TLS: bool = True SMTP_SSL: bool = False @@ -108,7 +92,6 @@ def _check_default_secret(self, var_name: str, value: str | None) -> None: @model_validator(mode="after") def _enforce_non_default_secrets(self) -> Self: self._check_default_secret("SECRET_KEY", self.SECRET_KEY) - self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD) self._check_default_secret( "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD ) diff --git a/backend/app/core/db.py b/backend/app/core/db.py index ba991fb36d..f19ac0d3bf 100644 --- a/backend/app/core/db.py +++ b/backend/app/core/db.py @@ -4,7 +4,7 @@ from app.core.config import settings from app.models import User, UserCreate -engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI)) +engine = create_engine(str(settings.DATABASE_URL)) # make sure all SQLModel models are imported (app.models) before initializing DB diff --git a/compose.yml b/compose.yml index 2488fc007b..870a8bc3c3 100644 --- a/compose.yml +++ b/compose.yml @@ -69,11 +69,7 @@ services: - SMTP_USER=${SMTP_USER} - SMTP_PASSWORD=${SMTP_PASSWORD} - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL} - - POSTGRES_SERVER=db - - POSTGRES_PORT=${POSTGRES_PORT} - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_USER=${POSTGRES_USER?Variable not set} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} + - DATABASE_URL=postgresql+psycopg://${POSTGRES_USER?Variable not set}:${POSTGRES_PASSWORD?Variable not set}@db:${POSTGRES_PORT}/${POSTGRES_DB} - SENTRY_DSN=${SENTRY_DSN} backend: @@ -102,11 +98,7 @@ services: - SMTP_USER=${SMTP_USER} - SMTP_PASSWORD=${SMTP_PASSWORD} - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL} - - POSTGRES_SERVER=db - - POSTGRES_PORT=${POSTGRES_PORT} - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_USER=${POSTGRES_USER?Variable not set} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} + - DATABASE_URL=postgresql+psycopg://${POSTGRES_USER?Variable not set}:${POSTGRES_PASSWORD?Variable not set}@db:${POSTGRES_PORT}/${POSTGRES_DB} - SENTRY_DSN=${SENTRY_DSN} healthcheck: From 90974b48154346434a570ebc604d019197013897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 11 Aug 2026 19:22:54 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20env=20vars?= =?UTF-8?q?=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 7 +------ backend/app/core/config.py | 12 ++++++++++++ compose.yml | 11 +++-------- deployment.md | 2 -- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.env b/.env index 5f24a3396c..e16784221f 100644 --- a/.env +++ b/.env @@ -14,10 +14,5 @@ SMTP_TLS=False SMTP_PORT=1025 # Postgres -POSTGRES_SERVER=localhost -POSTGRES_DB=app -POSTGRES_USER=postgres POSTGRES_PASSWORD=changethis - -# Database URL for the backend (uses localhost for local dev, overridden in compose.yml for Docker) -DATABASE_URL=postgresql+psycopg://postgres:changethis@localhost:5432/app +DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/app diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 935ed7dbbb..1f3c2873c2 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -6,6 +6,7 @@ HttpUrl, PostgresDsn, computed_field, + field_validator, model_validator, ) from pydantic_settings import BaseSettings, SettingsConfigDict @@ -29,6 +30,15 @@ class Settings(BaseSettings): SENTRY_DSN: HttpUrl | None = None DATABASE_URL: PostgresDsn + @field_validator("DATABASE_URL", mode="before") + @classmethod + def _use_psycopg_driver(cls, value: str | PostgresDsn) -> str: + database_url = str(value) + for scheme in ("postgres://", "postgresql://"): + if database_url.startswith(scheme): + return database_url.replace(scheme, "postgresql+psycopg://", 1) + return database_url + SMTP_TLS: bool = True SMTP_SSL: bool = False SMTP_PORT: int = 587 @@ -69,6 +79,8 @@ def _check_default_secret(self, var_name: str, value: str | None) -> None: @model_validator(mode="after") def _enforce_non_default_secrets(self) -> Self: self._check_default_secret("SECRET_KEY", self.SECRET_KEY) + for host in self.DATABASE_URL.hosts(): + self._check_default_secret("DATABASE_URL password", host["password"]) self._check_default_secret( "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD ) diff --git a/compose.yml b/compose.yml index 0bc90124b4..dd549712e7 100644 --- a/compose.yml +++ b/compose.yml @@ -20,7 +20,7 @@ services: db: image: postgres:18 healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + test: ["CMD-SHELL", "pg_isready -U postgres -d app"] interval: 10s retries: 5 start_period: 30s @@ -29,8 +29,7 @@ services: - app-db-data:/var/lib/postgresql environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Variable not set} - - POSTGRES_USER=${POSTGRES_USER:?Variable not set} - - POSTGRES_DB=${POSTGRES_DB:?Variable not set} + - POSTGRES_DB=app adminer: image: adminer @@ -62,11 +61,7 @@ services: SMTP_USER: ${SMTP_USER:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-} EMAILS_FROM_EMAIL: ${EMAILS_FROM_EMAIL} - POSTGRES_SERVER: db - POSTGRES_DB: ${POSTGRES_DB:?Variable not set} - POSTGRES_USER: ${POSTGRES_USER:?Variable not set} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Variable not set} - DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:?Variable not set}:${POSTGRES_PASSWORD:?Variable not set}@db:${POSTGRES_PORT:-5432}/${POSTGRES_DB} + DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:?Variable not set}@db:5432/app SENTRY_DSN: ${SENTRY_DSN:-} healthcheck: diff --git a/deployment.md b/deployment.md index 83be48adc0..331ccbac17 100644 --- a/deployment.md +++ b/deployment.md @@ -80,8 +80,6 @@ You can set several other environment variables: * `SMTP_USER`: The SMTP server user to send emails. * `SMTP_PASSWORD`: The SMTP server password to send emails. * `EMAILS_FROM_EMAIL`: The email account to send emails from. -* `POSTGRES_USER`: The Postgres user, you can leave the default. -* `POSTGRES_DB`: The database name to use for this application. You can leave the default of `app`. * `SENTRY_DSN`: The DSN for Sentry, if you are using it. ## GitHub Actions Environment Variables