@django-stack/cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/bin.js +660 -347
- package/dist/index.d.ts +51 -6
- package/dist/index.js +1 -1
- package/dist/{production-DIj9yRcg.js → production-CGkI7oNe.js} +641 -57
- package/package.json +1 -1
- package/templates/backend/Dockerfile +4 -2
- package/templates/backend/pyproject.toml +1 -1
- package/templates/base/README.md +9 -4
- package/templates/base/compose.yaml +19 -9
- package/templates/base/env.example +23 -4
- package/templates/frontend-astro/package.json +1 -1
- package/templates/frontend-next/package.json +3 -3
- package/templates/frontend-nuxt/package.json +2 -2
- package/templates/frontend-sveltekit/package.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@django-stack/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "The production-ready Django, batteries included stack. Create and manage DjangoStack projects: a Django backend, a frontend, Postgres and Docker Compose in one command.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Leon van der Grient",
|
|
@@ -25,10 +25,12 @@ RUN --mount=type=cache,target=/root/.cache/uv \
|
|
|
25
25
|
|
|
26
26
|
# Development runs as root, so files the container writes into the mounted
|
|
27
27
|
# source (such as new migrations) work on every host. Production does not.
|
|
28
|
+
# The entrypoint runs with sh, so it works without the executable bit (the
|
|
29
|
+
# mounted source keeps the host's file modes).
|
|
28
30
|
FROM deps AS dev
|
|
29
31
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
30
32
|
uv sync --no-install-project
|
|
31
|
-
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
33
|
+
ENTRYPOINT ["sh", "/app/entrypoint.sh"]
|
|
32
34
|
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
|
|
33
35
|
|
|
34
36
|
FROM base AS prod
|
|
@@ -41,5 +43,5 @@ USER app
|
|
|
41
43
|
EXPOSE 8000
|
|
42
44
|
HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=5 \
|
|
43
45
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/readyz', timeout=4)"
|
|
44
|
-
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
46
|
+
ENTRYPOINT ["sh", "/app/entrypoint.sh"]
|
|
45
47
|
CMD ["gunicorn", "config.asgi:application", "--worker-class", "uvicorn_worker.UvicornWorker", "--bind", "0.0.0.0:8000", "--workers", "3", "--access-logfile", "-", "--no-control-socket"]
|
|
@@ -5,7 +5,7 @@ description = "The Django backend of {{project_name}}."
|
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
dependencies = [
|
|
7
7
|
"Django>=6.1,<6.2",
|
|
8
|
-
"django-stack[server,s3]>=0.
|
|
8
|
+
"django-stack[server,s3]>=0.8.0",
|
|
9
9
|
"django-headless[schema]>=1.1.1",
|
|
10
10
|
"django-content-studio[images,huey]>=1.11.0",
|
|
11
11
|
]
|
package/templates/base/README.md
CHANGED
|
@@ -6,7 +6,9 @@ A website with a Django backend and a frontend built with {{frontend_label}}, cr
|
|
|
6
6
|
- [Django Headless](https://djangoheadless.org) serves the content API.
|
|
7
7
|
- [Django Content Studio](https://djangocontentstudio.org) is the admin.
|
|
8
8
|
- [{{frontend_label}}]({{frontend_url}}) renders the site.
|
|
9
|
-
- Postgres stores the content
|
|
9
|
+
- Postgres stores the content, and by default also the cache and the task
|
|
10
|
+
queue (`CACHE_URL` and `TASKS_URL` in `.env`); Valkey can take those over
|
|
11
|
+
with the `valkey` profile.
|
|
10
12
|
|
|
11
13
|
## Start
|
|
12
14
|
|
|
@@ -16,9 +18,12 @@ You need Docker.
|
|
|
16
18
|
docker compose up --build
|
|
17
19
|
```
|
|
18
20
|
|
|
19
|
-
- Site: http://localhost:
|
|
20
|
-
- Admin: http://localhost:
|
|
21
|
-
- Outgoing mail: http://localhost:
|
|
21
|
+
- Site: http://localhost:{{site_port}}
|
|
22
|
+
- Admin: http://localhost:{{site_port}}/admin/ (user `admin`, password `ADMIN_PASSWORD` in `.env`)
|
|
23
|
+
- Outgoing mail: http://localhost:{{mail_port}}
|
|
24
|
+
|
|
25
|
+
The ports are `SITE_PORT` and `MAIL_PORT` in `.env`. When you change
|
|
26
|
+
`SITE_PORT`, change `SITE_URL` and `BACKEND_URL` with it.
|
|
22
27
|
|
|
23
28
|
The first start migrates the database, creates the admin user and adds demo
|
|
24
29
|
content. Edit a page in the admin, publish, and reload the site.
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
#
|
|
3
3
|
# COMPOSE_PROFILES in .env picks the services:
|
|
4
4
|
# dev,db `docker compose up` on a laptop: dev servers with hot reload,
|
|
5
|
-
# http://localhost:3000, Mailpit at http://localhost:8025
|
|
5
|
+
# http://localhost:3000, Mailpit at http://localhost:8025 (the
|
|
6
|
+
# *_PORT variables in .env change the ports).
|
|
6
7
|
# prod,db `docker compose up -d` on a server: production images behind
|
|
7
8
|
# Caddy on ports 80 and 443, with automatic HTTPS and daily backups.
|
|
8
9
|
# Leave out `db` to use an external Postgres through DATABASE_URL, and add
|
|
9
10
|
# `s3` in development for a local S3 service (see .env). `analytics` runs
|
|
10
|
-
# Umami for page analytics
|
|
11
|
+
# Umami for page analytics, `valkey` the Valkey service for CACHE_URL or
|
|
12
|
+
# TASKS_URL.
|
|
11
13
|
#
|
|
12
14
|
# The frontend only receives the variables it needs: never the full-access
|
|
13
15
|
# API key or the database password.
|
|
@@ -42,6 +44,7 @@ x-backend-depends: &backend-depends
|
|
|
42
44
|
required: false
|
|
43
45
|
cache:
|
|
44
46
|
condition: service_healthy
|
|
47
|
+
required: false
|
|
45
48
|
s3:
|
|
46
49
|
condition: service_started
|
|
47
50
|
required: false
|
|
@@ -72,7 +75,7 @@ services:
|
|
|
72
75
|
- ./backend:/app
|
|
73
76
|
- media:/app/media
|
|
74
77
|
ports:
|
|
75
|
-
- "127.0.0.1
|
|
78
|
+
- "127.0.0.1:${BACKEND_PORT:-8000}:8000"
|
|
76
79
|
depends_on: *backend-depends
|
|
77
80
|
healthcheck: *backend-health
|
|
78
81
|
restart: unless-stopped
|
|
@@ -87,6 +90,9 @@ services:
|
|
|
87
90
|
volumes:
|
|
88
91
|
- ./backend:/app
|
|
89
92
|
- media:/app/media
|
|
93
|
+
# 0 with TASKS_URL=immediate://: tasks run in the request.
|
|
94
|
+
deploy:
|
|
95
|
+
replicas: ${TASK_WORKERS:-1}
|
|
90
96
|
depends_on:
|
|
91
97
|
backend:
|
|
92
98
|
condition: service_healthy
|
|
@@ -102,7 +108,7 @@ services:
|
|
|
102
108
|
- ./frontend:/app
|
|
103
109
|
- frontend_node_modules:/app/node_modules
|
|
104
110
|
ports:
|
|
105
|
-
- "127.0.0.1
|
|
111
|
+
- "127.0.0.1:${SITE_PORT:-3000}:3000"
|
|
106
112
|
depends_on:
|
|
107
113
|
backend:
|
|
108
114
|
condition: service_healthy
|
|
@@ -112,11 +118,12 @@ services:
|
|
|
112
118
|
profiles: [dev]
|
|
113
119
|
image: axllent/mailpit:v1.27
|
|
114
120
|
ports:
|
|
115
|
-
- "127.0.0.1
|
|
121
|
+
- "127.0.0.1:${MAIL_PORT:-8025}:8025"
|
|
116
122
|
restart: unless-stopped
|
|
117
123
|
|
|
118
124
|
# A local S3 service, so development runs the same storage code as
|
|
119
|
-
# production with S3. Files are public at http://localhost:8333/<bucket
|
|
125
|
+
# production with S3. Files are public at http://localhost:8333/<bucket>/
|
|
126
|
+
# (S3_PORT).
|
|
120
127
|
s3:
|
|
121
128
|
profiles: [s3]
|
|
122
129
|
image: chrislusf/seaweedfs:4.52
|
|
@@ -124,7 +131,7 @@ services:
|
|
|
124
131
|
volumes:
|
|
125
132
|
- s3data:/data
|
|
126
133
|
ports:
|
|
127
|
-
- "127.0.0.1
|
|
134
|
+
- "127.0.0.1:${S3_PORT:-8333}:8333"
|
|
128
135
|
restart: unless-stopped
|
|
129
136
|
|
|
130
137
|
# Production -------------------------------------------------------------
|
|
@@ -181,6 +188,7 @@ services:
|
|
|
181
188
|
healthcheck:
|
|
182
189
|
disable: true
|
|
183
190
|
deploy:
|
|
191
|
+
replicas: ${TASK_WORKERS:-1}
|
|
184
192
|
resources:
|
|
185
193
|
limits:
|
|
186
194
|
memory: 512M
|
|
@@ -292,9 +300,11 @@ services:
|
|
|
292
300
|
memory: 1G
|
|
293
301
|
restart: unless-stopped
|
|
294
302
|
|
|
295
|
-
#
|
|
296
|
-
# evicted when memory runs out, so queued
|
|
303
|
+
# Valkey (the valkey profile), for CACHE_URL or TASKS_URL redis://cache.
|
|
304
|
+
# Only keys with an expiry are evicted when memory runs out, so queued
|
|
305
|
+
# tasks are never dropped.
|
|
297
306
|
cache:
|
|
307
|
+
profiles: [valkey]
|
|
298
308
|
image: valkey/valkey:8-alpine
|
|
299
309
|
user: valkey
|
|
300
310
|
command: ["valkey-server", "--save", "", "--appendonly", "no", "--maxmemory", "200mb", "--maxmemory-policy", "volatile-lru"]
|
|
@@ -8,7 +8,8 @@ PROJECT_NAME={{project_name}}
|
|
|
8
8
|
# dev,db development on this machine
|
|
9
9
|
# prod,db production on a server
|
|
10
10
|
# Leave out `db` when DATABASE_URL points to an external Postgres; add `s3`
|
|
11
|
-
# in development for the local S3 service. `analytics` runs Umami
|
|
11
|
+
# in development for the local S3 service. `analytics` runs Umami, `valkey`
|
|
12
|
+
# the Valkey service.
|
|
12
13
|
COMPOSE_PROFILES=dev,db
|
|
13
14
|
|
|
14
15
|
# The public URL of the site. In development the frontend's dev server also
|
|
@@ -17,6 +18,15 @@ COMPOSE_PROFILES=dev,db
|
|
|
17
18
|
SITE_URL=http://localhost:3000
|
|
18
19
|
BACKEND_URL=http://localhost:3000
|
|
19
20
|
|
|
21
|
+
# The ports of the development services on this machine: the site with the
|
|
22
|
+
# admin, the backend, Mailpit and the local S3 service. `init` and
|
|
23
|
+
# `dstack dev` move to free ones when these are in use, and change the
|
|
24
|
+
# URLs above with SITE_PORT.
|
|
25
|
+
SITE_PORT=3000
|
|
26
|
+
BACKEND_PORT=8000
|
|
27
|
+
MAIL_PORT=8025
|
|
28
|
+
S3_PORT=8333
|
|
29
|
+
|
|
20
30
|
# Behind the proxy of a platform such as Coolify or Dokploy, which gets the
|
|
21
31
|
# certificate, Caddy serves plain HTTP on port 80 to it instead:
|
|
22
32
|
# CADDY_ADDRESS=:80 TRUSTED_PROXIES=private_ranges NUM_PROXIES=2
|
|
@@ -33,9 +43,18 @@ POSTGRES_USER=app
|
|
|
33
43
|
POSTGRES_PASSWORD={{secret:postgres}}
|
|
34
44
|
DATABASE_URL=postgres://app:{{secret:postgres}}@db:5432/app
|
|
35
45
|
|
|
36
|
-
# Cache
|
|
37
|
-
#
|
|
38
|
-
|
|
46
|
+
# Cache and task queue: db:// keeps them in tables in the database, so
|
|
47
|
+
# nothing else runs. For the Valkey service add `valkey` to COMPOSE_PROFILES
|
|
48
|
+
# and use redis://cache:6379/0 (the cache) or redis://cache:6379/1 (the
|
|
49
|
+
# tasks). CACHE_URL=locmem:// is a cache per process. TASKS_URL=immediate://
|
|
50
|
+
# runs tasks in the request, with TASK_WORKERS=0 to stop the worker; there
|
|
51
|
+
# are no daily backups then.
|
|
52
|
+
CACHE_URL=db://
|
|
53
|
+
TASKS_URL=db://
|
|
54
|
+
TASK_WORKERS=1
|
|
55
|
+
|
|
56
|
+
# Mail. In production, EMAIL_URL is your SMTP server, such as
|
|
57
|
+
# smtp+tls://user:password@smtp.example.com:587.
|
|
39
58
|
EMAIL_URL=smtp://mailpit:1025
|
|
40
59
|
DEFAULT_FROM_EMAIL={{project_name}} <noreply@localhost>
|
|
41
60
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@django-headless/client": "^1.1.1",
|
|
16
|
-
"@django-stack/next": "^0.
|
|
17
|
-
"@django-stack/react": "^0.
|
|
18
|
-
"@django-stack/utils": "^0.
|
|
16
|
+
"@django-stack/next": "^0.8.0",
|
|
17
|
+
"@django-stack/react": "^0.8.0",
|
|
18
|
+
"@django-stack/utils": "^0.8.0",
|
|
19
19
|
"next": "^16.4.4",
|
|
20
20
|
"react": "^19.3.1",
|
|
21
21
|
"react-dom": "^19.3.1",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@django-headless/client": "^1.1.1",
|
|
18
|
-
"@django-stack/utils": "^0.
|
|
19
|
-
"@django-stack/vue": "^0.
|
|
18
|
+
"@django-stack/utils": "^0.8.0",
|
|
19
|
+
"@django-stack/vue": "^0.8.0",
|
|
20
20
|
"nuxt": "^4.6.3",
|
|
21
21
|
"nuxt-security": "^2.7.0",
|
|
22
22
|
"vue": "^3.5.44",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@django-headless/client": "^1.1.1",
|
|
22
|
-
"@django-stack/svelte": "^0.
|
|
23
|
-
"@django-stack/utils": "^0.
|
|
22
|
+
"@django-stack/svelte": "^0.8.0",
|
|
23
|
+
"@django-stack/utils": "^0.8.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@sveltejs/adapter-node": "^6.0.1",
|