diff --git a/.env b/.env index 1f8e41b185..e16784221f 100644 --- a/.env +++ b/.env @@ -14,7 +14,5 @@ SMTP_TLS=False SMTP_PORT=1025 # Postgres -POSTGRES_SERVER=localhost -POSTGRES_DB=app -POSTGRES_USER=postgres POSTGRES_PASSWORD=changethis +DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/app diff --git a/backend/app/alembic/env.py b/backend/app/alembic/env.py index fb993cf48c..919eebf5de 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 75c9fae271..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 @@ -27,23 +28,16 @@ class Settings(BaseSettings): PROJECT_NAME: str SENTRY_DSN: HttpUrl | None = None - POSTGRES_SERVER: str - POSTGRES_PORT: int = 5432 - POSTGRES_USER: str - POSTGRES_PASSWORD: str = "" - POSTGRES_DB: str = "" + DATABASE_URL: PostgresDsn - @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, - ) + @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 @@ -85,7 +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) - self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD) + 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/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 b785dd9675..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,10 +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://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