flake.nix 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. # A Nix flake that sets up a complete Synapse development environment. Dependencies
  2. # for the SyTest (https://github.com/matrix-org/sytest) and Complement
  3. # (https://github.com/matrix-org/complement) Matrix homeserver test suites are also
  4. # installed automatically.
  5. #
  6. # You must have already installed Nix (https://nixos.org) on your system to use this.
  7. # Nix can be installed on Linux or MacOS; NixOS is not required. Windows is not
  8. # directly supported, but Nix can be installed inside of WSL2 or even Docker
  9. # containers. Please refer to https://nixos.org/download for details.
  10. #
  11. # You must also enable support for flakes in Nix. See the following for how to
  12. # do so permanently: https://nixos.wiki/wiki/Flakes#Enable_flakes
  13. #
  14. # Be warned: you'll need over 3.75 GB of free space to download all the dependencies.
  15. #
  16. # Usage:
  17. #
  18. # With Nix installed, navigate to the directory containing this flake and run
  19. # `nix develop --impure`. The `--impure` is necessary in order to store state
  20. # locally from "services", such as PostgreSQL and Redis.
  21. #
  22. # You should now be dropped into a new shell with all programs and dependencies
  23. # availabile to you!
  24. #
  25. # You can start up pre-configured local Synapse, PostgreSQL and Redis instances by
  26. # running: `devenv up`. To stop them, use Ctrl-C.
  27. #
  28. # All state (the venv, postgres and redis data and config) are stored in
  29. # .devenv/state. Deleting a file from here and then re-entering the shell
  30. # will recreate these files from scratch.
  31. #
  32. # You can exit the development shell by typing `exit`, or using Ctrl-D.
  33. #
  34. # If you would like this development environment to activate automatically
  35. # upon entering this directory in your terminal, first install `direnv`
  36. # (https://direnv.net/). Then run `echo 'use flake . --impure' >> .envrc` at
  37. # the root of the Synapse repo. Finally, run `direnv allow .` to allow the
  38. # contents of '.envrc' to run every time you enter this directory. Voilà!
  39. {
  40. inputs = {
  41. # Use the master/unstable branch of nixpkgs. Used to fetch the latest
  42. # available versions of packages.
  43. nixpkgs.url = "github:NixOS/nixpkgs/master";
  44. # Output a development shell for x86_64/aarch64 Linux/Darwin (MacOS).
  45. systems.url = "github:nix-systems/default";
  46. # A development environment manager built on Nix. See https://devenv.sh.
  47. devenv.url = "github:cachix/devenv/v0.6.3";
  48. # Rust toolchain.
  49. rust-overlay.url = "github:oxalica/rust-overlay";
  50. };
  51. outputs = { self, nixpkgs, devenv, systems, rust-overlay, ... } @ inputs:
  52. let
  53. forEachSystem = nixpkgs.lib.genAttrs (import systems);
  54. in {
  55. devShells = forEachSystem (system:
  56. let
  57. overlays = [ (import rust-overlay) ];
  58. pkgs = import nixpkgs {
  59. inherit system overlays;
  60. };
  61. in {
  62. # Everything is configured via devenv - a Nix module for creating declarative
  63. # developer environments. See https://devenv.sh/reference/options/ for a list
  64. # of all possible options.
  65. default = devenv.lib.mkShell {
  66. inherit inputs pkgs;
  67. modules = [
  68. {
  69. # Make use of the Starship command prompt when this development environment
  70. # is manually activated (via `nix develop --impure`).
  71. # See https://starship.rs/ for details on the prompt itself.
  72. starship.enable = true;
  73. # Configure packages to install.
  74. # Search for package names at https://search.nixos.org/packages?channel=unstable
  75. packages = with pkgs; [
  76. # The rust toolchain and related tools.
  77. # This will install the "default" profile of rust components.
  78. # https://rust-lang.github.io/rustup/concepts/profiles.html
  79. #
  80. # NOTE: We currently need to set the Rust version unnecessarily high
  81. # in order to work around https://github.com/matrix-org/synapse/issues/15939
  82. (rust-bin.stable."1.71.1".default.override {
  83. # Additionally install the "rust-src" extension to allow diving into the
  84. # Rust source code in an IDE (rust-analyzer will also make use of it).
  85. extensions = [ "rust-src" ];
  86. })
  87. # The rust-analyzer language server implementation.
  88. rust-analyzer
  89. # GCC includes a linker; needed for building `ruff`
  90. gcc
  91. # Needed for building `ruff`
  92. gnumake
  93. # Native dependencies for running Synapse.
  94. icu
  95. libffi
  96. libjpeg
  97. libpqxx
  98. libwebp
  99. libxml2
  100. libxslt
  101. sqlite
  102. # Native dependencies for unit tests (SyTest also requires OpenSSL).
  103. openssl
  104. xmlsec
  105. # Native dependencies for running Complement.
  106. olm
  107. # For building the Synapse documentation website.
  108. mdbook
  109. # For releasing Synapse
  110. debian-devscripts # (`dch` for manipulating the Debian changelog)
  111. libnotify # (the release script uses `notify-send` to tell you when CI jobs are done)
  112. ];
  113. # Install Python and manage a virtualenv with Poetry.
  114. languages.python.enable = true;
  115. languages.python.poetry.enable = true;
  116. # Automatically activate the poetry virtualenv upon entering the shell.
  117. languages.python.poetry.activate.enable = true;
  118. # Install all extra Python dependencies; this is needed to run the unit
  119. # tests and utilitise all Synapse features.
  120. languages.python.poetry.install.arguments = ["--extras all"];
  121. # Install the 'matrix-synapse' package from the local checkout.
  122. languages.python.poetry.install.installRootPackage = true;
  123. # This is a work-around for NixOS systems. NixOS is special in
  124. # that you can have multiple versions of packages installed at
  125. # once, including your libc linker!
  126. #
  127. # Some binaries built for Linux expect those to be in a certain
  128. # filepath, but that is not the case on NixOS. In that case, we
  129. # force compiling those binaries locally instead.
  130. env.POETRY_INSTALLER_NO_BINARY = "ruff";
  131. # Install dependencies for the additional programming languages
  132. # involved with Synapse development.
  133. #
  134. # * Golang is needed to run the Complement test suite.
  135. # * Perl is needed to run the SyTest test suite.
  136. # * Rust is used for developing and running Synapse.
  137. # It is installed manually with `packages` above.
  138. languages.go.enable = true;
  139. languages.perl.enable = true;
  140. # Postgres is needed to run Synapse with postgres support and
  141. # to run certain unit tests that require postgres.
  142. services.postgres.enable = true;
  143. # On the first invocation of `devenv up`, create a database for
  144. # Synapse to store data in.
  145. services.postgres.initdbArgs = ["--locale=C" "--encoding=UTF8"];
  146. services.postgres.initialDatabases = [
  147. { name = "synapse"; }
  148. ];
  149. # Create a postgres user called 'synapse_user' which has ownership
  150. # over the 'synapse' database.
  151. services.postgres.initialScript = ''
  152. CREATE USER synapse_user;
  153. ALTER DATABASE synapse OWNER TO synapse_user;
  154. '';
  155. # Redis is needed in order to run Synapse in worker mode.
  156. services.redis.enable = true;
  157. # Configure and start Synapse. Before starting Synapse, this shell code:
  158. # * generates a default homeserver.yaml config file if one does not exist, and
  159. # * ensures a directory containing two additional homeserver config files exists;
  160. # one to configure using the development environment's PostgreSQL as the
  161. # database backend and another for enabling Redis support.
  162. process.before = ''
  163. python -m synapse.app.homeserver -c homeserver.yaml --generate-config --server-name=synapse.dev --report-stats=no
  164. mkdir -p homeserver-config-overrides.d
  165. cat > homeserver-config-overrides.d/database.yaml << EOF
  166. ## Do not edit this file. This file is generated by flake.nix
  167. database:
  168. name: psycopg2
  169. args:
  170. user: synapse_user
  171. database: synapse
  172. host: $PGHOST
  173. cp_min: 5
  174. cp_max: 10
  175. EOF
  176. cat > homeserver-config-overrides.d/redis.yaml << EOF
  177. ## Do not edit this file. This file is generated by flake.nix
  178. redis:
  179. enabled: true
  180. EOF
  181. '';
  182. # Start synapse when `devenv up` is run.
  183. processes.synapse.exec = "poetry run python -m synapse.app.homeserver -c homeserver.yaml -c homeserver-config-overrides.d";
  184. # Define the perl modules we require to run SyTest.
  185. #
  186. # This list was compiled by cross-referencing https://metacpan.org/
  187. # with the modules defined in './cpanfile' and then finding the
  188. # corresponding Nix packages on https://search.nixos.org/packages.
  189. #
  190. # This was done until `./install-deps.pl --dryrun` produced no output.
  191. env.PERL5LIB = "${with pkgs.perl536Packages; makePerlPath [
  192. DBI
  193. ClassMethodModifiers
  194. CryptEd25519
  195. DataDump
  196. DBDPg
  197. DigestHMAC
  198. DigestSHA1
  199. EmailAddressXS
  200. EmailMIME
  201. EmailSimple # required by Email::Mime
  202. EmailMessageID # required by Email::Mime
  203. EmailMIMEContentType # required by Email::Mime
  204. TextUnidecode # required by Email::Mime
  205. ModuleRuntime # required by Email::Mime
  206. EmailMIMEEncodings # required by Email::Mime
  207. FilePath
  208. FileSlurper
  209. Future
  210. GetoptLong
  211. HTTPMessage
  212. IOAsync
  213. IOAsyncSSL
  214. IOSocketSSL
  215. NetSSLeay
  216. JSON
  217. ListUtilsBy
  218. ScalarListUtils
  219. ModulePluggable
  220. NetAsyncHTTP
  221. MetricsAny # required by Net::Async::HTTP
  222. NetAsyncHTTPServer
  223. StructDumb
  224. URI
  225. YAMLLibYAML
  226. ]}";
  227. # Clear the LD_LIBRARY_PATH environment variable on shell init.
  228. #
  229. # By default, devenv will set LD_LIBRARY_PATH to point to .devenv/profile/lib. This causes
  230. # issues when we include `gcc` as a dependency to build C libraries, as the version of glibc
  231. # that the development environment's cc compiler uses may differ from that of the system.
  232. #
  233. # When LD_LIBRARY_PATH is set, system tools will attempt to use the development environment's
  234. # libraries. Which, when built against a different glibc version lead, to "version 'GLIBC_X.YY'
  235. # not found" errors.
  236. enterShell = ''
  237. unset LD_LIBRARY_PATH
  238. '';
  239. }
  240. ];
  241. };
  242. });
  243. };
  244. }