Get loomio server to start
Crashes immediately on hitting any route because vue js stuff is not compiled yet.
This commit is contained in:
parent
b339a30b23
commit
8d707f9a53
|
@ -20,11 +20,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1710889954,
|
"lastModified": 1724334015,
|
||||||
"narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=",
|
"narHash": "sha256-5sfvc0MswIRNdRWioUhG58rGKGn2o90Ck6l6ClpwQqA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b",
|
"rev": "6d204f819efff3d552a88d0a44b5aaaee172b784",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
(import ./modules/overlay.nix)
|
(import ./modules/overlay.nix)
|
||||||
|
./modules/loomio.nix
|
||||||
./hosts/test/configuration.nix
|
./hosts/test/configuration.nix
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
users.users.nixosvmtest.group = "nixosvmtest";
|
users.users.nixosvmtest.group = "nixosvmtest";
|
||||||
users.groups.nixosvmtest = {};
|
users.groups.nixosvmtest = {};
|
||||||
|
|
||||||
users.groups.loomio = {};
|
services.loomio = {
|
||||||
users.users.loomio = {
|
enable = true;
|
||||||
description = "User to run loomio";
|
encyrptedCredentials = ./loomio-credentials.yml.enc;
|
||||||
group = "loomio";
|
credentialEncryptionKeyFile = ./loomio-master.key;
|
||||||
isSystemUser = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
|
@ -32,23 +31,9 @@
|
||||||
ensureUsers = [{
|
ensureUsers = [{
|
||||||
name = "loomio";
|
name = "loomio";
|
||||||
ensureDBOwnership = true;
|
ensureDBOwnership = true;
|
||||||
# ensurePermissions = { "DATABASE loomio" = "ALL PRIVILEGES"; };
|
ensureClauses.superuser = true;
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.loomio = {
|
|
||||||
enable = true;
|
|
||||||
after = [ "basic.target" ];
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
User = "loomio";
|
|
||||||
Restart = "always";
|
|
||||||
ExecStart = "${pkgs.loomio}/bin/loomio";
|
|
||||||
};
|
|
||||||
environment = {
|
|
||||||
DATABASE_URL = "postgresql://localhost/loomio";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "23.11";
|
system.stateVersion = "23.11";
|
||||||
}
|
}
|
||||||
|
|
1
hosts/test/loomio-credentials.yml.enc
Normal file
1
hosts/test/loomio-credentials.yml.enc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1LR0cmifVLl04EAAtWPaoBhy85l6u7pGPjiSheUe/vkKbu3S3MK4XV6vBOmGnki4yMrOvdpvpLomnlCxCxEyOYcDRtBh3LkgZ3+9Bx37IcRHfgobzWVG/ik1/ZA4w2zbo8u/oJD6/gtuJNXBTkWNgpo4/WCJddxrzbF1Jo/FawT/ecwPO5898x/VBZn79rMFqcSJ2NKY4noOhOr2+EosFBjEkU7T5QVag64WQDT5/Np2vVhFWPvCgyoXziKTjBpCIUE9dDcA7HFIPgZ5nZXIwdSmVdAN3cA1zDlQMGqA27R4tt9zuRkPCvnfNvfuuVp9FHuok7tUTFPNR6v6NPzvHNceHugUvFF9zu33MAl8tH9j5W3Wd7zPVxuYp9nU8nHPmQF5DlPUoqUERLq/0biF7+F/4KGkNl+DFkZW--EGCnUuZJQoZORDG3--UsPRfjEX4LFxe6ECg8uR9Q==
|
1
hosts/test/loomio-master.key
Normal file
1
hosts/test/loomio-master.key
Normal file
|
@ -0,0 +1 @@
|
||||||
|
dd587169f25e5ed7e391a511da13f491
|
|
@ -1,12 +1,116 @@
|
||||||
{lib, ...}:
|
{pkgs, lib, config, ...}:
|
||||||
{
|
let
|
||||||
|
cfg = config.services.loomio;
|
||||||
|
package = pkgs.loomio;
|
||||||
|
|
||||||
|
env = {
|
||||||
|
RAILS_ENV = "production";
|
||||||
|
BUNDLE_FORCE_RUBY_PLATFORM = "true";
|
||||||
|
|
||||||
|
LOOMIO_DATABASE = "loomio";
|
||||||
|
LOOMIO_ENCRYPTED_CREDENTIALS_PATH = cfg.encyrptedCredentials;
|
||||||
|
};
|
||||||
|
cfgService = {
|
||||||
|
User = "loomio";
|
||||||
|
Group = "loomio";
|
||||||
|
WorkingDirectory = package;
|
||||||
|
StateDirectory = "loomio";
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [];
|
imports = [];
|
||||||
options = {
|
options = {
|
||||||
enable = lib.mkEnableOption "loomio";
|
services.loomio = {
|
||||||
|
enable = lib.mkEnableOption "loomio";
|
||||||
|
encyrptedCredentials = lib.mkOption {
|
||||||
|
description = "Credentials required to run loomio";
|
||||||
|
type = lib.types.path;
|
||||||
|
};
|
||||||
|
credentialEncryptionKeyFile = lib.mkOption {
|
||||||
|
description = "File containing encryption key for the encyptedCredentials";
|
||||||
|
type = lib.types.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
|
users.groups.loomio = {};
|
||||||
|
users.users.loomio = {
|
||||||
|
description = "User to run loomio";
|
||||||
|
group = "loomio";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.loomio-init-dirs = {
|
||||||
|
enable = true;
|
||||||
|
after = ["network.target" ];
|
||||||
|
serviceConfig = cfgService // {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
cat > /var/lib/loomio/.secrets_env <<EOF
|
||||||
|
RAILS_MASTER_KEY=$(cat ${cfg.credentialEncryptionKeyFile})
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.loomio-init-db = {
|
||||||
|
enable = true;
|
||||||
|
after = ["network.target" "postgresql.service" "loomio-init-dirs.service" ];
|
||||||
|
requires = [ "postgresql.service" "loomio-init-dirs.service" ];
|
||||||
|
serviceConfig = cfgService // {
|
||||||
|
Type = "oneshot";
|
||||||
|
EnvironmentFile = [ "/var/lib/loomio/.secrets_env" ];
|
||||||
|
};
|
||||||
|
environment = env;
|
||||||
|
path = [package config.services.postgresql.package];
|
||||||
|
script = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
result="$(psql -t --csv -c \
|
||||||
|
"select count(*) from pg_class c \
|
||||||
|
join pg_namespace s on s.oid = c.relnamespace \
|
||||||
|
where s.nspname not in ('pg_catalog', 'pg_toast', 'information_schema') \
|
||||||
|
and s.nspname not like 'pg_temp%';")" || error_code=$?
|
||||||
|
if [ "''${error_code:-0}" -ne 0 ]; then
|
||||||
|
echo "Failure checking if database is seeded. psql gave exit code $error_code"
|
||||||
|
exit "$error_code"
|
||||||
|
fi
|
||||||
|
if [ "$result" -eq 0 ]; then
|
||||||
|
echo "Seeding database"
|
||||||
|
SAFETY_ASSURED=1 rails db:schema:load
|
||||||
|
rails db:seed
|
||||||
|
else
|
||||||
|
echo "Migrating database (this might be a noop)"
|
||||||
|
rails db:migrate
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.loomio = {
|
systemd.services.loomio = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
after = [ "network.target" "loomio-init-db.service" ];
|
||||||
|
requires = [ "loomio.socket" "loomio-init-db.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = cfgService // {
|
||||||
|
Type = "notify";
|
||||||
|
TimeoutStartSec = 120;
|
||||||
|
WatchdogSec = 10;
|
||||||
|
Restart = "always";
|
||||||
|
ExecStart = "${package}/bin/puma -C config/puma.rb";
|
||||||
|
EnvironmentFile = [ "/var/lib/loomio/.secrets_env" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = env // {
|
||||||
|
PORT="3000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sockets.loomio = {
|
||||||
|
listenStreams = ["0.0.0.0:3000"];
|
||||||
|
socketConfig = {
|
||||||
|
NoDelay = true;
|
||||||
|
ReusePort = true;
|
||||||
|
Backlog = 1024;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
21
pkg/loomio/creds.patch
Normal file
21
pkg/loomio/creds.patch
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
diff --git a/.gitignore b/.gitignore
|
||||||
|
index 75bb667202..db91658d32 100644
|
||||||
|
--- a/.gitignore
|
||||||
|
+++ b/.gitignore
|
||||||
|
@@ -97,3 +97,5 @@ yarn-error.log*
|
||||||
|
|
||||||
|
# Ruby bundle and gems
|
||||||
|
/vendor
|
||||||
|
+
|
||||||
|
+/config/master.key
|
||||||
|
diff --git a/config/environments/production.rb b/config/environments/production.rb
|
||||||
|
index 05f46dad87..de8fbf9168 100644
|
||||||
|
--- a/config/environments/production.rb
|
||||||
|
+++ b/config/environments/production.rb
|
||||||
|
@@ -95,4 +95,6 @@ Rails.application.configure do
|
||||||
|
|
||||||
|
# Do not dump schema after migrations.
|
||||||
|
config.active_record.dump_schema_after_migration = false
|
||||||
|
+
|
||||||
|
+ config.credentials.content_path = ENV['LOOMIO_ENCRYPTED_CREDENTIALS_PATH']
|
||||||
|
end
|
|
@ -1,8 +1,20 @@
|
||||||
{stdenv, writeText, callPackage, bundlerEnv, ruby_3_2 }:
|
{stdenv,
|
||||||
|
writeShellScriptBin,
|
||||||
|
writeText,
|
||||||
|
symlinkJoin,
|
||||||
|
callPackage,
|
||||||
|
bundlerEnv,
|
||||||
|
ruby_3_2,
|
||||||
|
postgresql
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
gemfile-patch = callPackage ./gemfile-patch.nix {};
|
gemfile-patch = callPackage ./gemfile-patch.nix {};
|
||||||
src = callPackage ./source.nix { patches = [gemfile-patch];};
|
src = callPackage ./source.nix {
|
||||||
|
patches = [
|
||||||
|
gemfile-patch
|
||||||
|
./creds.patch
|
||||||
|
];
|
||||||
|
};
|
||||||
gems = bundlerEnv {
|
gems = bundlerEnv {
|
||||||
name = "loomio-env";
|
name = "loomio-env";
|
||||||
ruby = ruby_3_2;
|
ruby = ruby_3_2;
|
||||||
|
@ -12,28 +24,39 @@ let
|
||||||
|
|
||||||
databaseConfig = writeText "database.yml" ''
|
databaseConfig = writeText "database.yml" ''
|
||||||
production:
|
production:
|
||||||
url: <%= ENV['DATABASE_URL'] %>
|
adapter: postgresql
|
||||||
|
database: <%= ENV['LOOMIO_DATABASE'] %>
|
||||||
|
host: /var/run/postgresql
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in stdenv.mkDerivation {
|
in stdenv.mkDerivation {
|
||||||
name = "loomio";
|
name = "loomio";
|
||||||
inherit src;
|
inherit src;
|
||||||
|
nativeBuildInputs = [ gems gems.wrappedRuby ];
|
||||||
buildInputs = [gems ruby_3_2];
|
buildInputs = [gems ruby_3_2];
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
cp ${databaseConfig} config/database.yml
|
||||||
|
cp ${./puma.rb} config/puma.rb
|
||||||
|
|
||||||
|
export BUNDLE_FORCE_RUBY_PLATFORM=true
|
||||||
|
${gems}/bin/bundle exec bootsnap precompile --gemfile app/ lib/
|
||||||
|
|
||||||
|
patchShebangs bin/
|
||||||
|
|
||||||
|
for b in $(ls ${gems}/bin/)
|
||||||
|
do
|
||||||
|
if [ ! -f bin/$b ]; then
|
||||||
|
ln -s ${gems}/bin/$b bin/$b
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/{bin,share/loomio}
|
mkdir -p $out
|
||||||
cp -r * $out/share/loomio
|
cp -r * $out
|
||||||
bin=$out/bin/loomio
|
|
||||||
cp ${databaseConfig} $out/share/loomio/config/database.yml
|
|
||||||
cat > $bin <<EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
export BUNDLE_FORCE_RUBY_PLATFORM=true
|
|
||||||
export RAILS_ENV=production
|
|
||||||
${gems}/bin/bundle exec rake -f $out/share/loomio/Rakefile db:prepare
|
|
||||||
${gems}/bin/bundle exec puma -C $out/share/loomio/config/puma.rb
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x $bin
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{fetchurl}:
|
{fetchurl}:
|
||||||
fetchurl {
|
fetchurl {
|
||||||
url = "https://github.com/akshaymankar/loomio/commit/528641fd04135a186232568fbf9a4717e2053e86.patch";
|
url = "https://github.com/akshaymankar/loomio/commit/e8d4c448dd448658aceeaf715b5ea601ee111c03.patch";
|
||||||
hash = "sha256-sg/4U72gZHoTYepZ4dIQlyC4YBjU5+YgIKI/Oj+XlRs=";
|
hash = "sha256-ruONUFWQ/0V+I9x6nV7wNr5xz1QMUPVvLR1xT6gBVRU=";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -818,7 +818,7 @@
|
||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["http://rubygems.org"];
|
remotes = ["http://rubygems.org"];
|
||||||
sha256 = "0szml3n6ql6wzl5fq2rcl1w9iksz4zb68p7cbbwkwc5kkp34ikgx";
|
sha256 = "07139870npj59jnl8vmk39ja3gdk3fb5z9vc0lf32y2h891hwqsi";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.17.0";
|
version = "1.17.0";
|
||||||
|
@ -991,7 +991,7 @@
|
||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["http://rubygems.org"];
|
remotes = ["http://rubygems.org"];
|
||||||
sha256 = "00jg44v6az86mmh8gmr5l4lvryjhzla29qs4qi1gcdcqx2b7xlhk";
|
sha256 = "1mnxzcq8kmyfb9bkzqnp019d1hx1vprip3yzdkkha6b3qz5rgg9r";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "3.25.3";
|
version = "3.25.3";
|
||||||
|
@ -1045,7 +1045,7 @@
|
||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["http://rubygems.org"];
|
remotes = ["http://rubygems.org"];
|
||||||
sha256 = "0xkpyc0hmb20xznyh1i1m093r1swni9wfmss0hks67fy6s6kmsr2";
|
sha256 = "03z8yq0z228g6xxxq6s2mmslpv6psrdmi30dpmhysr4px16d897n";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.62.0";
|
version = "1.62.0";
|
||||||
|
@ -1387,6 +1387,16 @@
|
||||||
};
|
};
|
||||||
version = "1.1.5";
|
version = "1.1.5";
|
||||||
};
|
};
|
||||||
|
mini_portile2 = {
|
||||||
|
groups = ["default" "development" "test"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["http://rubygems.org"];
|
||||||
|
sha256 = "1q1f2sdw3y3y9mnym9dhjgsjr72sq975cfg5c4yx7gwv8nmzbvhk";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.8.7";
|
||||||
|
};
|
||||||
minitest = {
|
minitest = {
|
||||||
groups = ["default" "development" "test"];
|
groups = ["default" "development" "test"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
|
@ -1503,12 +1513,12 @@
|
||||||
version = "2.7.0";
|
version = "2.7.0";
|
||||||
};
|
};
|
||||||
nokogiri = {
|
nokogiri = {
|
||||||
dependencies = ["racc"];
|
dependencies = ["mini_portile2" "racc"];
|
||||||
groups = ["default" "development" "test"];
|
groups = ["default" "development" "test"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["http://rubygems.org"];
|
remotes = ["http://rubygems.org"];
|
||||||
sha256 = "1aiz5hg2pfjnk756f2zd0723m3wq30gkmishmc76jwn51yw341v3";
|
sha256 = "15gysw8rassqgdq3kwgl4mhqmrgh7nk2qvrcqp4ijyqazgywn6gq";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.16.7";
|
version = "1.16.7";
|
||||||
|
|
26
pkg/loomio/puma.rb
Normal file
26
pkg/loomio/puma.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
max_threads_count = ENV['RAILS_MAX_THREADS'] || ENV['MAX_THREADS'] || 5
|
||||||
|
min_threads_count = ENV['RAILS_MIN_THREADS'] || ENV['MIN_THREADS'] || max_threads_count
|
||||||
|
threads min_threads_count, max_threads_count
|
||||||
|
|
||||||
|
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
||||||
|
#
|
||||||
|
port ENV.fetch("PORT") { 3000 }
|
||||||
|
|
||||||
|
# Specifies the `environment` that Puma will run in.
|
||||||
|
#
|
||||||
|
environment ENV.fetch("RAILS_ENV") { "development" }
|
||||||
|
|
||||||
|
# Specifies the number of `workers` to boot in clustered mode.
|
||||||
|
# Workers are forked web server processes. If using threads and workers together
|
||||||
|
# the concurrency of the application would be max `threads` * `workers`.
|
||||||
|
# Workers do not work on JRuby or Windows (both of which do not support
|
||||||
|
# processes).
|
||||||
|
#
|
||||||
|
workers ENV['PUMA_WORKERS'] || ENV['WEB_CONCURRENCY'] || 0
|
||||||
|
|
||||||
|
# Use the `preload_app!` method when specifying a `workers` number.
|
||||||
|
# This directive tells Puma to first boot the application and load code
|
||||||
|
# before forking the application. This takes advantage of Copy On Write
|
||||||
|
# process behavior so workers use less memory.
|
||||||
|
#
|
||||||
|
preload_app!
|
|
@ -99,7 +99,7 @@ in
|
||||||
inherit version;
|
inherit version;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
SOURCE_DIR="$(nix-build --no-out-link -E '(import <nixpkgs> {}).callPackage ./source.nix {}')"
|
SOURCE_DIR="$(nix-build --no-out-link -E 'let pkgs = import <nixpkgs> {}; in pkgs.callPackage ./source.nix { patches = [(pkgs.callPackage ./gemfile-patch.nix {})]; }')"
|
||||||
|
|
||||||
echo "Creating gemset.nix"
|
echo "Creating gemset.nix"
|
||||||
BUNDLE_FORCE_RUBY_PLATFORM=true bundix --lockfile="$SOURCE_DIR/Gemfile.lock" --gemfile="$SOURCE_DIR/Gemfile"
|
BUNDLE_FORCE_RUBY_PLATFORM=true bundix --lockfile="$SOURCE_DIR/Gemfile.lock" --gemfile="$SOURCE_DIR/Gemfile"
|
||||||
|
|
Loading…
Reference in a new issue