A packaging of Zulip server for NixOS
  • Nix 94.3%
  • Python 5.7%
Find a file
stuebinm 99af7c43ce
All checks were successful
Lints / lints (x86_64-linux) (pull_request) Successful in 9s
Check workflows / lints (x86_64-linux) (pull_request) Successful in 11s
Nixos tests / zulip-backup (x86_64-linux) (pull_request) Successful in 3m9s
Nixos tests / zulip-tornado (x86_64-linux) (pull_request) Successful in 3m9s
Nixos tests / zulip-monitoring (x86_64-linux) (pull_request) Successful in 3m32s
Nixos tests / zulip (x86_64-linux) (pull_request) Successful in 4m1s
Nixos tests / zulip-restart (x86_64-linux) (pull_request) Successful in 3m57s
nix-zulip: add nodejs to PATH
Zulip 12.0 added support for [Jdenticon](https://github.com/zulip/zulip/pull/36920)
to generate avatars as an alternative to gravatar, and which is now the new
default.

This requires that the `node' binary is available to `uwsgi', which it
previously was not, leading to failure in the /accounts/register endpoint:

    uwsgi[2456078]: 2026-05-15 09:18:28.462 ERR  [django.request] Internal Server Error: /accounts/register/
    uwsgi[2456078]: Traceback (most recent call last):
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
    uwsgi[2456078]:     response = get_response(request)
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/site-packages/django/core/handlers/base.py", line 197, in _get_response
    uwsgi[2456078]:     response = wrapped_callback(request, *callback_args, **callback_kwargs)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/decorator.py", line 129, in wrapper
    uwsgi[2456078]:     return func(request, *args, **kwargs)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/views/registration.py", line 276, in accounts_register
    uwsgi[2456078]:     return registration_helper(*args, **kwargs)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/lib/typed_endpoint.py", line 548, in _wrapped_view_func
    uwsgi[2456078]:     return_value = view_func(request, *args, **kwargs)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/views/registration.py", line 833, in registration_helper
    uwsgi[2456078]:     user_profile = do_create_user(
    uwsgi[2456078]:         email,
    uwsgi[2456078]:     ...<15 lines>...
    uwsgi[2456078]:         external_auth_id_dict=external_auth_id_dict,
    uwsgi[2456078]:     )
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/contextlib.py", line 85, in inner
    uwsgi[2456078]:     return func(*args, **kwds)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/actions/create_user.py", line 552, in do_create_user
    uwsgi[2456078]:     generate_and_upload_jdenticon_avatar(user_profile, str(realm.uuid), future=False)
    uwsgi[2456078]:     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/lib/avatar.py", line 231, in generate_and_upload_jdenticon_avatar
    uwsgi[2456078]:     image_data = generate_avatar_jdenticon(jdenticon_key, medium=False)
    uwsgi[2456078]:   File "/nix/store/8dq0w3bhv899619bz2ani8xm4rj8kdv8-zulip-12.0/zerver/lib/avatar.py", line 207, in generate_avatar_jdenticon
    uwsgi[2456078]:     stdout = subprocess.check_output(command)
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/subprocess.py", line 472, in check_output
    uwsgi[2456078]:     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
    uwsgi[2456078]:            ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:                **kwargs).stdout
    uwsgi[2456078]:                ^^^^^^^^^
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/subprocess.py", line 554, in run
    uwsgi[2456078]:     with Popen(*popenargs, **kwargs) as process:
    uwsgi[2456078]:          ~~~~~^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/subprocess.py", line 1039, in __init__
    uwsgi[2456078]:     self._execute_child(args, executable, preexec_fn, close_fds,
    uwsgi[2456078]:     ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:                         pass_fds, cwd, env,
    uwsgi[2456078]:                         ^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:     ...<5 lines>...
    uwsgi[2456078]:                         gid, gids, uid, umask,
    uwsgi[2456078]:                         ^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:                         start_new_session, process_group)
    uwsgi[2456078]:                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    uwsgi[2456078]:   File "/nix/store/gc1b8ck1jfqbbc4814lkvjz36l3n6bxl-python3-3.13.12-env/lib/python3.13/subprocess.py", line 1991, in _execute_child
    uwsgi[2456078]:     raise child_exception_type(errno_num, err_msg, err_filename)
    uwsgi[2456078]: FileNotFoundError: [Errno 2] No such file or directory: 'node'
2026-05-15 18:12:16 +02:00
.forgejo/workflows feat: revamp dev workflow 2026-04-30 18:11:25 +02:00
LICENSES zulip-prometheus-exporter: init at 0.1.0 2025-08-06 17:16:15 -07:00
nix nix-zulip: add nodejs to PATH 2026-05-15 18:12:16 +02:00
.envrc pluralize attributes 2025-08-29 16:48:53 -07:00
.gitignore add nixos test for zulip 2025-08-06 21:21:34 -07:00
engage.toml feat: revamp dev workflow 2026-04-30 18:11:25 +02:00
README.md feat(lappverk): init tooling 2026-04-01 11:36:21 +02:00
REUSE.toml start the project 2025-08-06 13:35:47 -07:00
shell.nix feat(shell): add shell.nix 2025-12-01 10:56:51 +01:00
treefmt.toml start the project 2025-08-06 13:35:47 -07:00

nix-zulip

This repository packages Zulip for Nix and NixOS.

Updating

  1. Bump the version in the zulip-server package and the other dependencies (you can use nix-update for that)

  2. Check if any dependency changed from the upstream pyproject.toml

  3. [Optional] Compare version requirements from uv.lock and

  4. Create a new patchset using lappverk. A typical workflow looks like (for 11.2 -> 11.4 update):

    pushd nix/packages/zulip-server
    lappverk checkout @/patches-11.2
    lappverk init patch-series @/patches-11.4 --base 11.4
    pushd $(lappverk checkout nix/packages/zulip-server/patches-11.4)
    git cherry-pick lappverk/base/patches-11.2..lappverk/patches-11.2
    
    # resolve (or --skip) any conflicts that come up, as per usual...
    # then, once the whole series has been cherry-picked
    
    lappverk export @/patches-11.4
    popd
    popd
    

    This workflow is encoded in the lappverk-start-rebase OLD_TAG NEW_TAG and lappverk-finish-rebase bash functions exported by the shell.

  5. Run the tests with engage