Files
upstream-zulip/docs/production/management-commands.md
upstream-mirror 64898b2c79
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

201 lines
8.4 KiB
Markdown

# Management commands
Sometimes, you need to modify or inspect Zulip data from the command
line. To help with this, Zulip ships with over 100 command-line tools
implemented using the [Django management commands
framework][django-management].
Because management commands require server shell access, Zulip Cloud
users will need to contact support for situations requiring them.
## Running management commands
:::{important}
If you are using [Docker](docker.md), management commands are run
inside the container; see {doc}`docker:how-to/compose-commands` for
Docker Compose deployments and {doc}`docker:how-to/helm-commands`
for Helm deployments.
:::
Start by logging in as the `zulip` user on the Zulip server. Then run
them as follows:
```bash
cd /home/zulip/deployments/current
# Start by reading the help
./manage.py <command_name> --help
# Once you've determined this is the command for you, run it!
./manage.py <command_name> <args>
```
A full list of commands is available via `./manage.py help`; you'll
primarily want to use those in the `[zerver]` section as those are the
ones specifically built for Zulip.
As a warning, some of them are designed for specific use cases and may
cause problems if run in other situations. If you're not sure, it's
worth reading the documentation (or the code, usually available at
`zerver/management/commands/`; they're generally very simple programs).
### Accessing an organization's `string_id`
Since Zulip supports hosting multiple organizations on a single
server, many management commands require you specify which
organization ("realm") you'd like to modify, either via numerical or
string ID (usually the subdomain).
You can see all the organizations on your Zulip server using
`./manage.py list_realms`.
```console
zulip@zulip:~$ /home/zulip/deployments/current/manage.py list_realms
id string_id name
-- --------- ----
1 zulipinternal None
2 Zulip Community
```
(Note that every Zulip server has a special `zulipinternal` realm
containing system-internal bots like `Notification Bot`; you are
unlikely to ever need to interact with that realm.)
Unless you are
[hosting multiple organizations on your Zulip server](multiple-organizations.md),
your single Zulip organization on the root domain will have the empty
string (`''`) as its `string_id`. So you can run, for example:
```console
zulip@zulip:~$ /home/zulip/deployments/current/manage.py show_admins -r ''
```
Otherwise, the `string_id` will correspond to the organization's
subdomain. E.g., on `it.zulip.example.com`, use
`/home/zulip/deployments/current/manage.py show_admins -r it`.
## manage.py shell
If you need to query or edit data directly in the Zulip database, the
best way to do this is with Django's built-in management shell.
You can get an IPython shell with full access to code within the Zulip
project using `manage.py shell`, e.g., you can do the following to
change a user's email address:
```console
$ cd /home/zulip/deployments/current/
$ ./manage.py shell
In [1]: user_profile = get_user_profile_by_email("email@example.com")
In [2]: do_change_user_delivery_email(user_profile, "new_email@example.com")
```
Any Django tutorial can give you helpful advice on querying and
formatting data from Zulip's tables for inspection; Zulip's own
[new feature tutorial](../tutorials/new-feature-tutorial.md) should help
you understand how the codebase is organized.
We recommend against directly editing objects and saving them using
Django's `object.save()`. While this will save your changes to the
database, for most objects, in addition to saving the changes to the
database, one may also need to flush caches, notify the apps and open
browser windows, and record the change in Zulip's `RealmAuditLog`
audit history table. For almost any data change you want to do, there
is already a function in `zerver.actions` with a name like
`do_change_full_name` that updates that field and notifies clients
correctly.
For convenience, Zulip automatically imports `zerver.models`
into every management shell; if you need to
access other functions, you'll need to import them yourself.
## Other useful manage.py commands
There are dozens of useful management commands under
`zerver/management/commands/`. We detail a few here:
- `./manage.py help`: Lists all available management commands.
- `./manage.py dbshell`: If you're more comfortable with raw SQL than
Python, this will open a PostgreSQL SQL shell connected to the Zulip
server's database. Beware of changing data; editing data directly
with SQL will often not behave correctly because PostgreSQL doesn't
know to flush Zulip's caches or notify browsers of changes.
- `./manage.py send_custom_email`: Can be used to send an email to a set
of users. The `--help` documents how to run it from a
`manage.py shell` for use with more complex programmatically
computed sets of users.
- `./manage.py send_password_reset_email`: Sends password reset email(s)
to one or more users.
- `./manage.py change_realm_subdomain`: Change subdomain of a realm.
- `./manage.py change_user_email`: Change a user's email address.
- `./manage.py change_user_role`: Can change a user's role
(easier done [via the
UI](https://zulip.com/help/user-roles)) or give bots the
`can_forge_sender` permission, which is needed for certain special API features.
- `./manage.py export_single_user`: does a limited version of the [main
export tools](export-and-import.md) containing just
the messages accessible by a single user.
- `./manage.py unarchive_channel`:
[Reactivates](https://zulip.com/help/archive-a-channel#unarchiving-archived-channels)
an archived channel.
- `./manage.py reactivate_realm`: Reactivates a realm.
- `./manage.py deactivate_user`: Deactivates a user. This can be done
more easily in Zulip's organization administrator UI.
- `./manage.py delete_user`: Completely delete a user from the database.
For most purposes, deactivating users is preferred, since that does not
alter message history for other users.
See the `./manage.py delete_user --help` documentation for details.
- `./manage.py reset_authentication_attempt_count`: If a user failed authentication
attempts too many times and further attempts are disallowed by the rate limiter,
this can be used to reset the limit.
All of our management commands have internal documentation available
via `manage.py command_name --help`.
## Custom management commands
Zulip supports several mechanisms for running custom code on a
self-hosted Zulip server:
- Using an existing [integration][integrations] or writing your own
[webhook integration][webhook-integrations] or [bot][writing-bots].
- Writing a program using the [Zulip API][zulip-api].
- [Modifying the Zulip server][modifying-zulip].
- Using the interactive [management shell](#managepy-shell),
documented above, for one-time work or prototyping.
- Writing a custom management command, detailed here.
Custom management commands are Python 3 programs that run inside
Zulip's context, so that they can access its libraries, database, and
code freely. They can be the best choice when you want to run custom
code that is not permitted by Zulip's security model (and thus can't
be done more easily using the [REST API][zulip-api]) and that you
might want to run often (and so the interactive `manage.py shell` is
not suitable, though we recommend using the management shell to
prototype queries).
Our developer documentation on [writing management
commands][management-commands-dev] explains how to write them.
Simply writing the command inside a `deployments/` directory is not
ideal, because a new such directory is created every time you upgrade
the Zulip server.
Instead, we recommend deploying custom management commands either via
the [modifying Zulip][modifying-zulip] process or by storing them in
`/etc/zulip` (so they are included in
[backups](export-and-import.md#backups)) and then
symlinking them into
`/home/zulip/deployments/current/zerver/management/` after each
upgrade.
[modifying-zulip]: modify.md
[writing-bots]: https://zulip.com/api/writing-bots
[integrations]: https://zulip.com/integrations
[zulip-api]: https://zulip.com/api/rest
[webhook-integrations]: ../webhooks/incoming-webhooks-overview.md
[management-commands-dev]: ../subsystems/management-commands.md
[django-management]: https://docs.djangoproject.com/en/5.0/ref/django-admin/#django-admin-and-manage-py