Repository navigation
Releases
v0.14.0
- Database connection pool. Set
DATABASE_POOL=1in.envto reuse
Postgres connections through psycopg's connection pool, with at most
DATABASE_POOL_SIZE(4) connections per backend process. Theserver
extra ofdjango-stacknow installspsycopg[pool];dstack update
brings it into an existing project.
Fixes
- Fixed: under traffic, Postgres refused connections with
FATAL: sorry, too many clients alreadyand 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_URLnow setsCONN_MAX_AGEto 0:
each request closes its connection when it ends. Rundstack updateto
get the newdjango-stack, and remove a
DATABASES["default"]["CONN_MAX_AGE"] = 0workaround from
settings.pyif 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 getsrc/pages/500.astroand new Next.js projects
src/app/global-error.tsx: error pages that call no API, so they show
even when the backend fails.dstack updateadds the page to an existing project
that has none. - Fixed:
manage.py wait_for_dbwithDATABASE_POOL=1hid a wrong
password behind a 30-second pool timeout; it now connects without the
pool and reports it at once.
v0.13.1
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
networkskey then loses thedefaultnetwork, where thefrontend
andbackendaliases live.dstack updatenow adds
networks: [default]toproxy,worker-prod,umami,dband
cacheincompose.yamlwhen it is missing; commit it and deploy
again. New projects list it on every production service.
v0.13.0
- Several projects on one Coolify or Dokploy server.
compose.yamlno
longer publishes host ports for theproxyservice, so a second project
on the same server no longer fails withport is already allocated.
Coolify and Dokploy reach the proxy over the Docker network, on port 80.
The ports are in the newcompose.ports.yaml, which a server of your own
loads withCOMPOSE_FILE=compose.yaml:compose.ports.yamlin.env.
dstack productionasks 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 deployleaves it
out for Coolify, Dokploy, Railway and Bunny, and adds it for a server
over SSH. The deploy workflow copiescompose.ports.yamlto the server.
In an existing project,dstack updatemoves the ports out of
compose.yamland writescompose.ports.yaml. Then:- On a server of your own, copy
compose.ports.yamlto the server and
addCOMPOSE_FILE=compose.yaml:compose.ports.yamlto its.env
(shared/.envfor a server set up withdstack deploy), or the site
is not reachable after the next deploy. - On Coolify or Dokploy, remove
HTTP_PORTandHTTPS_PORTfrom the
application's environment variables.
- On a server of your own, copy
Improvements
dstack deploy setupanddstack deploy loginremember 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
Fixes
- Fixed: an editor could save a menu link, a call to action button or a
social link asjavascript:..., which ran script for every visitor who
clicked it. The starterLinkBlockandCallToActionBlocknow refuse
links other than paths andhttp(s),mailtoandtelURLs
(django_stack.validators.validate_link), and every frontend renders
these links through the newsafeHrefof@django-stack/utils(the
safe_hreffilter in Django templates). In an existing project, add
validators=[validate_link]to those fields and wrap thehrefof the
call to action and the social links insafeHref(...). - Fixed: any
stack_previewcookie 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 withverifyPreviewToken(process.env.PREVIEW_SECRET, token)
where the middleware orcachedContentdecides on the cache. - Fixed: a redirect to a full URL showed an error page on Nuxt, whose
navigateToneedsexternal: truefor one. - Fixed:
dstack production --force,dstack settings,dstack configand
the port moves ofdstack devkept the file mode of an existing.env;
they now make it readable by its owner only.--email-urlwith$or
#in the password is quoted, so Compose reads it as typed. - Fixed:
initdid 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.W006with the Umami check; it is nowdjango_stack.W007. - Fixed:
TASKS_URL=db://refused apostgis://orpgsql://
DATABASE_URL, and the task statistics then went to a SQLite file per
container. dstack deploy loginwarns when the platform's URL is plainhttp://,
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=parentreturned 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 (nullfor 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
previewHandlerof@django-stack/nextredirected a preview link with
path=/\example.comto 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) orsrc/routes/preview/+server.ts(SvelteKit) to
/^\/(?![/\\])/.test(path) ? path : "/". - Fixed: the generated
.github/workflows/deploy.ymlwrote 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./Caddyfilebecame a directory. The Caddyfile is now in
caddy/Caddyfile, and theproxyservice mounts the./caddy
directory at/etc/caddy.dstack deployon Bunny and Railway reads
the files of a mounted directory. In an existing project, move
Caddyfiletocaddy/Caddyfile, change theproxyvolume in
compose.yamlto./caddy:/etc/caddy:ro, and in
.github/workflows/deploy.ymlcopycaddywithscp -rinstead of
Caddyfile. On a Coolify server where the deploy already failed, delete
/data/coolify/applications/<uuid>/Caddyfile.
v0.12.9
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, importHueyAdapterfrom
django_stack.studioinbackend/config/studio.pyand remove the two
TaskStatisticWidgetlines.
Fixes
-
Fixed:
dstack devcould start the production build of the frontend
and crash. The dev services had noimagekey, so Compose named their
images<project>-backendand<project>-frontend, the same names as
the prod images; building prod replaced the dev images. The dev
services incompose.yamlnow have their own image names. In an
existing project, add animageline to thebackend,workerand
frontendservices, then rundocker compose --profile dev build:backend: image: <project>-backend-dev worker: image: <project>-backend-dev frontend: image: <project>-frontend-dev
v0.12.8
Fixes
-
Fixed: on Coolify the site answered 502 because Caddy could not resolve
frontendorbackend. Coolify puts a service without anetworks
key on its own network only, while those names are aliases on the
defaultnetwork. Theproxyandworker-prodservices in
compose.yamlnow listnetworks: [default]. In an existing project,
add these lines to both services and deploy again:networks: [default]
v0.12.7
Fixes
- Fixed: on Coolify the
proxyservice 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 setupnow turns on Coolify's Preserve repository during
deployment, anddstack deployturns 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
- 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
-
Bunny setup attaches an existing app.
dstack deploy setupwrote
.dstack/deploy.jsononly 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 newcreates 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 bunnynow 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
-
Health checks answer for any host. Bunny Magic Containers calls
/readyzon 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.HealthCheckMiddlewareserves
/healthzand/readyzbefore the host check; every other path still
checks it. In an existing project, add it toMIDDLEWAREin
config/settings.py, right afterdjango_stack.logs.RequestIdMiddleware. -
Database passwords with special characters. A database URL pasted
with a raw@,#,/,?or%in the password, or written by hand
inPRODUCTION_DATABASE_URL, was used as it was, so Umami and Django
could not read the password.initandproductionnow URL-encode the
user name and password, and an encoded one stays as it is. Run
dstack productionagain to fix.env.production.