1{
2 lib,
3 stdenv,
4 nodejs-slim,
5 bundlerEnv,
6 nixosTests,
7 yarn-berry,
8 callPackage,
9 ruby,
10 writeShellScript,
11 brotli,
12 python3,
13
14 # Allow building a fork or custom version of Mastodon:
15 pname ? "mastodon",
16 version ? srcOverride.version,
17 patches ? [ ],
18 # src is a package
19 srcOverride ? callPackage ./source.nix { inherit patches; },
20 gemset ? ./. + "/gemset.nix",
21 yarnHash ? srcOverride.yarnHash,
22 yarnMissingHashes ? srcOverride.yarnMissingHashes,
23}:
24
25stdenv.mkDerivation rec {
26 inherit pname version;
27
28 src = srcOverride;
29
30 mastodonGems = bundlerEnv {
31 name = "${pname}-gems-${version}";
32 inherit version gemset ruby;
33 gemdir = src;
34 };
35
36 mastodonModules = stdenv.mkDerivation (finalAttrs: {
37 pname = "${pname}-modules";
38 inherit src version;
39
40 missingHashes = yarnMissingHashes;
41 yarnOfflineCache = yarn-berry.fetchYarnBerryDeps {
42 inherit src;
43 hash = yarnHash;
44 missingHashes = yarnMissingHashes;
45 };
46
47 nativeBuildInputs = [
48 nodejs-slim
49 yarn-berry
50 yarn-berry.yarnBerryConfigHook
51 mastodonGems
52 mastodonGems.wrappedRuby
53 brotli
54 python3
55 ];
56
57 RAILS_ENV = "production";
58 NODE_ENV = "production";
59
60 buildPhase = ''
61 runHook preBuild
62
63 export SECRET_KEY_BASE_DUMMY=1
64
65 patchShebangs bin
66
67 bundle exec rails assets:precompile
68
69 rm -rf node_modules/.cache
70
71 # Remove workspace "package" as it contains broken symlinks
72 # See https://github.com/NixOS/nixpkgs/issues/380366
73 rm -rf node_modules/@mastodon
74
75 # Remove execute permissions
76 find public/assets -type f ! -perm 0555 \
77 -exec chmod 0444 {} ';'
78
79 # Create missing static gzip and brotli files
80 find public/assets -type f -regextype posix-extended -iregex '.*\.(css|html|js|json|svg)' \
81 -exec gzip --best --keep --force {} ';' \
82 -exec brotli --best --keep {} ';'
83
84 gzip --best --keep public/packs/sw.js
85 brotli --best --keep public/packs/sw.js
86
87 runHook postBuild
88 '';
89
90 installPhase = ''
91 runHook preInstall
92
93 mkdir -p $out/public
94 cp -r node_modules $out/node_modules
95 cp -r public/assets $out/public
96 cp -r public/packs $out/public
97
98 runHook postInstall
99 '';
100 });
101
102 propagatedBuildInputs = [ mastodonGems.wrappedRuby ];
103 nativeBuildInputs = [ brotli ];
104 buildInputs = [
105 mastodonGems
106 nodejs-slim
107 ];
108
109 buildPhase = ''
110 runHook preBuild
111
112 ln -s $mastodonModules/node_modules node_modules
113 ln -s $mastodonModules/public/assets public/assets
114 ln -s $mastodonModules/public/packs public/packs
115
116 patchShebangs bin/
117 for b in $(ls $mastodonGems/bin/)
118 do
119 if [ ! -f bin/$b ]; then
120 ln -s $mastodonGems/bin/$b bin/$b
121 fi
122 done
123
124 # Remove execute permissions
125 find public/emoji -type f ! -perm 0555 \
126 -exec chmod 0444 {} ';'
127
128 # Create missing static gzip and brotli files
129 find public -maxdepth 1 -type f -regextype posix-extended -iregex '.*\.(js|txt)' \
130 -exec gzip --best --keep --force {} ';' \
131 -exec brotli --best --keep {} ';'
132 find public/emoji -type f -name '*.svg' \
133 -exec gzip --best --keep --force {} ';' \
134 -exec brotli --best --keep {} ';'
135 ln -s assets/500.html.gz public/500.html.gz
136 ln -s assets/500.html.br public/500.html.br
137 ln -s packs/sw.js.gz public/sw.js.gz
138 ln -s packs/sw.js.br public/sw.js.br
139
140 rm -rf log
141 ln -s /var/log/mastodon log
142 ln -s /tmp tmp
143
144 runHook postBuild
145 '';
146
147 installPhase =
148 let
149 run-streaming = writeShellScript "run-streaming.sh" ''
150 # NixOS helper script to consistently use the same NodeJS version the package was built with.
151 ${nodejs-slim}/bin/node ./streaming
152 '';
153 in
154 ''
155 runHook preInstall
156
157 mkdir -p $out
158 mv .{env*,ruby*} $out/
159 mv * $out/
160 ln -s ${run-streaming} $out/run-streaming.sh
161
162 runHook postInstall
163 '';
164
165 passthru = {
166 tests.mastodon = nixosTests.mastodon;
167 # run with: nix-shell ./maintainers/scripts/update.nix --argstr package mastodon
168 updateScript = ./update.sh;
169 };
170
171 meta = with lib; {
172 description = "Self-hosted, globally interconnected microblogging software based on ActivityPub";
173 homepage = "https://joinmastodon.org";
174 license = licenses.agpl3Plus;
175 platforms = [
176 "x86_64-linux"
177 "i686-linux"
178 "aarch64-linux"
179 ];
180 maintainers = with maintainers; [
181 happy-river
182 erictapen
183 izorkin
184 ghuntley
185 ];
186 };
187}