Skip to content

Releases

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 11 Nov 15:29
  • Database connection pool. Set DATABASE_POOL=1 in .env to reuse
    Postgres connections through psycopg's connection pool, with at most
    DATABASE_POOL_SIZE (4) connections per backend process. The server
    extra of django-stack now installs psycopg[pool]; dstack update
    brings it into an existing project.

Fixes

  • Fixed: under traffic, Postgres refused connections with
    FATAL: sorry, too many clients already and pages answered 500. Django
    kept every connection for 60 seconds, but under ASGI each request runs
    in a new thread, so a kept connection was never reused and they piled
    up past Postgres's 100. DATABASE_URL now sets CONN_MAX_AGE to 0:
    each request closes its connection when it ends. Run dstack update to
    get the new django-stack, and remove a
    DATABASES["default"]["CONN_MAX_AGE"] = 0 workaround from
    settings.py if you added one. (#94)
  • Fixed: when a page failed to render, such as when the database was
    down, the Astro frontend answered with an empty 500 without a
    Content-Type, which iOS Safari offered as a file download. New Astro
    projects get src/pages/500.astro and new Next.js projects
    src/app/global-error.tsx: error pages that call no API, so they show
    even when the backend fails. dstack update adds the page to an existing project
    that has none.
  • Fixed: manage.py wait_for_db with DATABASE_POOL=1 hid a wrong
    password behind a 30-second pool timeout; it now connects without the
    pool and reports it at once.

v0.13.1

Choose a tag to compare

@github-actions github-actions released this 11 Nov 12:09

Fixes

  • Fixed: on Coolify, a project made before 0.12.8 answered 502 (Caddy:
    lookup frontend on 127.0.0.11:53: server misbehaving) and content
    changes never cleared the frontend's page cache. Coolify and Dokploy
    attach services to a network of their own, and a service without a
    networks key then loses the default network, where the frontend
    and backend aliases live. dstack update now adds
    networks: [default] to proxy, worker-prod, umami, db and
    cache in compose.yaml when it is missing; commit it and deploy
    again. New projects list it on every production service.

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 11 Nov 09:18
  • Several projects on one Coolify or Dokploy server. compose.yaml no
    longer publishes host ports for the proxy service, so a second project
    on the same server no longer fails with port is already allocated.
    Coolify and Dokploy reach the proxy over the Docker network, on port 80.
    The ports are in the new compose.ports.yaml, which a server of your own
    loads with COMPOSE_FILE=compose.yaml:compose.ports.yaml in .env.
    dstack production asks where the site runs and writes that line for a
    server of your own (--server, the default without a terminal) and
    leaves it out for a platform (--platform). dstack deploy leaves it
    out for Coolify, Dokploy, Railway and Bunny, and adds it for a server
    over SSH. The deploy workflow copies compose.ports.yaml to the server.
    In an existing project, dstack update moves the ports out of
    compose.yaml and writes compose.ports.yaml. Then:
    • On a server of your own, copy compose.ports.yaml to the server and
      add COMPOSE_FILE=compose.yaml:compose.ports.yaml to its .env
      (shared/.env for a server set up with dstack deploy), or the site
      is not reachable after the next deploy.
    • On Coolify or Dokploy, remove HTTP_PORT and HTTPS_PORT from the
      application's environment variables.

Improvements

  • dstack deploy setup and dstack deploy login remember the last
    address of each platform, such as your Coolify, and offer it again, so you
    press Enter instead of typing it for every project. It is saved in
    ~/.config/dstack/targets.json.

v0.12.10

Choose a tag to compare

@github-actions github-actions released this 11 Nov 07:40

Fixes

  • Fixed: an editor could save a menu link, a call to action button or a
    social link as javascript:..., which ran script for every visitor who
    clicked it. The starter LinkBlock and CallToActionBlock now refuse
    links other than paths and http(s), mailto and tel URLs
    (django_stack.validators.validate_link), and every frontend renders
    these links through the new safeHref of @django-stack/utils (the
    safe_href filter in Django templates). In an existing project, add
    validators=[validate_link] to those fields and wrap the href of the
    call to action and the social links in safeHref(...).
  • Fixed: any stack_preview cookie skipped the content cache of the Astro,
    Next, Nuxt and SvelteKit frontends, so a visitor could send every request
    through to Django. Only a valid preview token does now. In an existing
    project, check the cookie with verifyPreviewToken(process.env.PREVIEW_SECRET, token)
    where the middleware or cachedContent decides on the cache.
  • Fixed: a redirect to a full URL showed an error page on Nuxt, whose
    navigateTo needs external: true for one.
  • Fixed: dstack production --force, dstack settings, dstack config and
    the port moves of dstack dev kept the file mode of an existing .env;
    they now make it readable by its owner only. --email-url with $ or
    # in the password is quoted, so Compose reads it as typed.
  • Fixed: init did not see the leftover volumes of an earlier project's
    local run (dstack run), so the new project's local run failed with
    "password authentication failed for user app".
  • Fixed: the deploy check for tasks that run in the request shared the id
    django_stack.W006 with the Umami check; it is now django_stack.W007.
  • Fixed: TASKS_URL=db:// refused a postgis:// or pgsql://
    DATABASE_URL, and the task statistics then went to a SQLite file per
    container.
  • dstack deploy login warns when the platform's URL is plain http://,
    because the API key then travels unencrypted.
  • The GitHub Actions of the repository and of the generated deploy workflow
    are pinned by commit SHA.
  • Fixed: the content API showed drafts to the read-only key through
    relations. ?expand= of a relation to a model with a draft state, such
    as /api/content.author?expand=posts, listed unpublished posts, a
    forward relation such as ?expand=parent returned a draft page, and a
    filter across such a relation, such as ?posts__title__startswith=,
    told which drafts exist. Expanded relations and links in blocks now
    leave out the drafts the request may not see (null for a single
    relation), and such filters answer 400, unless the request has the
    full-access key or a preview token.
  • Fixed: the preview route of the Astro, Nuxt and SvelteKit frontends and
    previewHandler of @django-stack/next redirected a preview link with
    path=/\example.com to another site. They now redirect only to paths on
    the site. In an existing project, change the check in
    src/pages/preview/index.ts (Astro), server/routes/preview/index.get.ts
    (Nuxt) or src/routes/preview/+server.ts (SvelteKit) to
    /^\/(?![/\\])/.test(path) ? path : "/".
  • Fixed: the generated .github/workflows/deploy.yml wrote the SSH key
    and the registry token into its scripts; it now passes them as
    environment variables.
  • Fixed: the first deploy on Coolify failed with "cannot overwrite
    directory "Caddyfile" with non-directory". Coolify creates the source of
    every bind mount as a directory before it copies the repository, so the
    bind-mounted ./Caddyfile became a directory. The Caddyfile is now in
    caddy/Caddyfile, and the proxy service mounts the ./caddy
    directory at /etc/caddy. dstack deploy on Bunny and Railway reads
    the files of a mounted directory. In an existing project, move
    Caddyfile to caddy/Caddyfile, change the proxy volume in
    compose.yaml to ./caddy:/etc/caddy:ro, and in
    .github/workflows/deploy.yml copy caddy with scp -r instead of
    Caddyfile. On a Coolify server where the deploy already failed, delete
    /data/coolify/applications/<uuid>/Caddyfile.

v0.12.9

Choose a tag to compare

@github-actions github-actions released this 09 Nov 14:36

Changes

  • Changed: the worker's heartbeat, which runs every minute, no longer
    fills the recent runs of the Tasks page. django_stack.studio.HueyAdapter
    leaves it out. The dashboard no longer shows the queued and failed task
    counts. In an existing project, import HueyAdapter from
    django_stack.studio in backend/config/studio.py and remove the two
    TaskStatisticWidget lines.

Fixes

  • Fixed: dstack dev could start the production build of the frontend
    and crash. The dev services had no image key, so Compose named their
    images <project>-backend and <project>-frontend, the same names as
    the prod images; building prod replaced the dev images. The dev
    services in compose.yaml now have their own image names. In an
    existing project, add an image line to the backend, worker and
    frontend services, then run docker compose --profile dev build:

      backend:
        image: <project>-backend-dev
      worker:
        image: <project>-backend-dev
      frontend:
        image: <project>-frontend-dev

v0.12.8

Choose a tag to compare

@github-actions github-actions released this 09 Nov 12:06

Fixes

  • Fixed: on Coolify the site answered 502 because Caddy could not resolve
    frontend or backend. Coolify puts a service without a networks
    key on its own network only, while those names are aliases on the
    default network. The proxy and worker-prod services in
    compose.yaml now list networks: [default]. In an existing project,
    add these lines to both services and deploy again:

        networks: [default]

v0.12.7

Choose a tag to compare

@github-actions github-actions released this 09 Nov 10:51

Fixes

  • Fixed: on Coolify the proxy service failed to start with "not a
    directory" on /etc/caddy/Caddyfile, because Coolify starts the
    services from a directory without the repository's files. dstack deploy setup now turns on Coolify's Preserve repository during
    deployment
    , and dstack deploy turns it on for an application set up
    before. For an application you set up by hand, turn it on in Coolify
    and deploy again.

v0.12.6

Choose a tag to compare

@github-actions github-actions released this 09 Nov 09:26
  • Bunny variables are sent in the shape Bunny takes. dstack deploy env push, and setup when it attaches an existing app, sent the
    variables as a list, and Bunny answered "Validation Error". They are
    now sent as one object of names and values. Bunny's validation errors
    now show the field and the message instead of [object Object].

v0.12.5

Choose a tag to compare

@github-actions github-actions released this 09 Nov 08:49
  • Bunny setup attaches an existing app. dstack deploy setup wrote
    .dstack/deploy.json only when every step succeeded, so a setup that
    stopped halfway left an app behind, and the next setup created another.
    Setup now attaches the app with the project's name, or the one you pick
    in a terminal or pass with --app <name or id>; --app new creates a
    new one.

  • Bunny setup handles a domain that is already registered. When the
    domain was still on the pull zone of an earlier app, Bunny answered
    "The hostname is already registered" after setup had created the new
    app. dstack deploy setup --provider bunny now checks the domain before
    it creates anything and offers to move it to the new app; without a
    terminal, it stops and says which pull zone has it.

v0.12.4

Choose a tag to compare

@github-actions github-actions released this 08 Nov 20:35
  • Health checks answer for any host. Bunny Magic Containers calls
    /readyz on the container's own address, which is not in
    ALLOWED_HOSTS, so Django answered "Invalid HTTP_HOST header" and the
    container never became ready. The new
    django_stack.contrib.health.middleware.HealthCheckMiddleware serves
    /healthz and /readyz before the host check; every other path still
    checks it. In an existing project, add it to MIDDLEWARE in
    config/settings.py, right after django_stack.logs.RequestIdMiddleware.

  • Database passwords with special characters. A database URL pasted
    with a raw @, #, /, ? or % in the password, or written by hand
    in PRODUCTION_DATABASE_URL, was used as it was, so Umami and Django
    could not read the password. init and production now URL-encode the
    user name and password, and an encoded one stays as it is. Run
    dstack production again to fix .env.production.