Metadata-Version: 2.4
Name: dsd-cloudron
Version: 2026.7.2
Summary: A plugin for django-simple-deploy, supporting deployments to Cloudron.
Author-email: Jack Linke <jacklinke@gmail.com>
License-Expression: MIT
Project-URL: GitHub, https://github.com/omenapps/dsd-cloudron
Keywords: django,deployment,cloudron
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: django>=4.2
Requires-Dist: pluggy>=1.5.0
Requires-Dist: django-simple-deploy>=1.4.0
Requires-Dist: cookiecutter>=2.5
Provides-Extra: dev
Requires-Dist: black>=24.1.0; extra == "dev"
Requires-Dist: build>=1.2.1; extra == "dev"
Requires-Dist: coverage>=7.4; extra == "dev"
Requires-Dist: pytest>=8.3.0; extra == "dev"
Requires-Dist: pytest-cookies>=0.7.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: twine>=6.1.0; extra == "dev"
Provides-Extra: bake
Requires-Dist: celery>=5.3; extra == "bake"
Requires-Dist: django-redis>=5.4; extra == "bake"
Requires-Dist: django-allauth[mfa,socialaccount]>=65; extra == "bake"
Requires-Dist: crispy-bootstrap5>=2024.2; extra == "bake"
Requires-Dist: django-htmx>=1.17; extra == "bake"
Requires-Dist: django-ninja>=1.1; extra == "bake"
Requires-Dist: django-storages[boto3]>=1.14; extra == "bake"
Provides-Extra: docs
Requires-Dist: sphinx>=7; extra == "docs"
Requires-Dist: myst-parser>=2; extra == "docs"
Requires-Dist: furo; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Requires-Dist: sphinx-design; extra == "docs"
Dynamic: license-file

# dsd-cloudron

A [django-simple-deploy](https://django-simple-deploy.readthedocs.io) plugin that
configures and deploys Django projects to [Cloudron](https://cloudron.io). One
install serves two audiences:

- **Retrofit** an existing project: `python manage.py deploy --location <subdomain>`
- **Greenfield** a new project: `dsd-cloudron new "My App"`

Both render the same Cloudron artifact set (manifest, Dockerfile, start.sh,
supervisor configs, nginx, settings glue) through one packaging core.

Documentation: https://dsd-cloudron.readthedocs.io

## Install

```bash
pip install dsd-cloudron
npm install -g cloudron
cloudron login my.example.com
```

## Retrofit an existing Django project

```bash
pip install django-simple-deploy dsd-cloudron
python manage.py deploy --location blog          # config only
python manage.py deploy --location blog --automate-all   # config + install
```

Infra addons (PostgreSQL, Redis, sendmail) are on by default. The app-intrusive
ones are opt-in: `--celery` generates a Celery app module wired to the Redis
broker; `--sso` renders the Cloudron OIDC addon and a django-allauth provider
config and adds the dependency, then prints the steps to finish wiring allauth
into `INSTALLED_APPS`/`urls.py` and run `migrate` (a project scaffolded with
`dsd-cloudron new --sso` gets that wiring automatically). Useful flags:
`--health-check-path`, `--memory-limit`, `--app-id`, `--force-overwrite`,
`--no-redis`, `--no-sendmail`.

## Scaffold a new project

```bash
dsd-cloudron new "My App" --celery --sso
cd my_app
cloudron install -l my-app
```

## The control surface

The generated files ARE the configuration. Edit and re-deploy:

- `CloudronManifest.json` - addons, `memoryLimit`, `httpPort`, `healthCheckPath`.
  `healthCheckPath` must return a 2xx response or the install fails its health
  check. Greenfield ships a `/healthz/` view that returns 200.
- `<project>/cloudron_settings.py` - the Django glue, gated on
  `CLOUDRON_APP_ORIGIN` so it is inert during local development. Drop a
  `/app/data/custom_settings.py` on the server for ad-hoc overrides; it runs only
  when owned by `root` (create it via `cloudron exec` as `root:cloudron` mode 640),
  so a file the app could write itself is skipped.
- `Dockerfile`, `start.sh`, `nginx.conf`, `supervisor/` - the runtime.

Re-running `manage.py deploy` is safe but not silently idempotent: the settings
block is guarded, and rendered artifacts are skip-if-present (regenerate with
`--force-overwrite`).

## Iterate

```bash
# edit code or config, then:
cloudron update --app <subdomain>
cloudron logs --app <subdomain> -f
```

`/app/data` and the Postgres/Redis addons persist across updates; `migrate` runs
on every start.

## First sign-in

A local `admin` account is created on the first install; its generated password
is saved on the server at `/app/data/.initial_admin_password`. Read it with
`cloudron exec --app <subdomain> -- cat /app/data/.initial_admin_password` during
the first-boot window - the file is removed automatically on the next start once
the app is initialized (if you miss it, reset with `manage.py changepassword
admin` via `cloudron exec`). Sign in at `/admin/` and change it. With `--sso`,
sign in with your Cloudron account; the local `admin` is a break-glass account
for promoting your user.

## License

MIT. See LICENSE.
