diff --git a/nix/pkgs/baserow/backend/celery.py b/nix/pkgs/baserow/backend/celery.py new file mode 100644 index 0000000000..0c82b0f82f --- /dev/null +++ b/nix/pkgs/baserow/backend/celery.py @@ -0,0 +1,6 @@ +#!/usr/bin/python3 +import sys +from celery.__main__ import main +if __name__ == '__main__': + sys.argv[:] = [sys.argv[0]] + ["-A", "baserow"] + sys.argv[1:] + sys.exit(main()) diff --git a/nix/pkgs/baserow/backend/gunicorn.py b/nix/pkgs/baserow/backend/gunicorn.py new file mode 100644 index 0000000000..d68637b170 --- /dev/null +++ b/nix/pkgs/baserow/backend/gunicorn.py @@ -0,0 +1,6 @@ +#!/usr/bin/python3 +import sys +from gunicorn.app.wsgiapp import run +if __name__ == '__main__': + sys.argv[:] = [sys.argv[0]] + ["-k", "uvicorn.workers.UvicornWorker", "baserow.config.asgi:application"] + sys.argv[1:] + sys.exit(run()) diff --git a/nix/pkgs/baserow/backend/pynixify/overlay.nix b/nix/pkgs/baserow/backend/pynixify/overlay.nix index e3d5f93a41..e6a8900fac 100644 --- a/nix/pkgs/baserow/backend/pynixify/overlay.nix +++ b/nix/pkgs/baserow/backend/pynixify/overlay.nix @@ -15,8 +15,6 @@ self: super: { channels-redis = self.callPackage ./packages/channels-redis { }; - #click = self.callPackage ./packages/click { }; - django-celery-beat = self.callPackage ./packages/django-celery-beat { }; django = self.callPackage ./packages/django { }; diff --git a/nix/pkgs/baserow/backend/pynixify/packages/click/default.nix b/nix/pkgs/baserow/backend/pynixify/packages/click/default.nix deleted file mode 100644 index db99a31209..0000000000 --- a/nix/pkgs/baserow/backend/pynixify/packages/click/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -# WARNING: This file was automatically generated. You should avoid editing it. -# If you run pynixify again, the file will be either overwritten or -# deleted, and you will lose the changes you made to it. - -{ buildPythonPackage, fetchPypi, lib }: - -buildPythonPackage rec { - pname = "click"; - version = "7.1.2"; - - src = fetchPypi { - inherit pname version; - sha256 = "06kbzd6sjfkqan3miwj9wqyddfxc2b6hi7p5s4dvqjb3gif2bdfj"; - }; - - # TODO FIXME - doCheck = false; - - meta = with lib; { - description = "Composable command line interface toolkit"; - homepage = "https://palletsprojects.com/p/click/"; - }; -} diff --git a/nix/pkgs/baserow/backend/pynixify/packages/uvicorn/default.nix b/nix/pkgs/baserow/backend/pynixify/packages/uvicorn/default.nix index 5117c52717..342f051c0c 100644 --- a/nix/pkgs/baserow/backend/pynixify/packages/uvicorn/default.nix +++ b/nix/pkgs/baserow/backend/pynixify/packages/uvicorn/default.nix @@ -2,7 +2,7 @@ # If you run pynixify again, the file will be either overwritten or # deleted, and you will lose the changes you made to it. -{ asgiref, buildPythonPackage, click, fetchPypi, h11, lib }: +{ asgiref, buildPythonPackage, click, fetchPypi, h11, lib, websockets, httptools, uvloop, watchgod, python-dotenv, pyyaml }: buildPythonPackage rec { pname = "uvicorn"; @@ -13,7 +13,7 @@ buildPythonPackage rec { sha256 = "1zyana0yf3m8xkm8ihk7m19wv56gnj1jc61mwb9jhrx83kfw18yr"; }; - propagatedBuildInputs = [ asgiref click h11 ]; + propagatedBuildInputs = [ asgiref click h11 websockets httptools uvloop watchgod python-dotenv pyyaml ]; # TODO FIXME doCheck = false; diff --git a/nix/pkgs/baserow/default.nix b/nix/pkgs/baserow/default.nix index 8f02a2b827..662075eda6 100644 --- a/nix/pkgs/baserow/default.nix +++ b/nix/pkgs/baserow/default.nix @@ -91,12 +91,21 @@ in prePatch = '' # Yeet. Just assume everything is installed in the environment already. > requirements/base.txt + + substituteInPlace src/baserow/config/settings/base.py \ + --replace 'APPLICATION_TEMPLATES_DIR = os.path.join(BASE_DIR, "../../../templates")' "APPLICATION_TEMPLATES_DIR = '$out/share/baserow/templates'" ''; postInstall = '' comm -23 <(find $src/src/baserow/ -type d | sed "s,$src/src/baserow/,," | sort) <(find $out/${python.sitePackages}/baserow/ -type d | sed "s,$out/${python.sitePackages}/baserow/,," | sort) | while read missingDir; do test -e "$out/${python.sitePackages}/baserow/$missingDir" && continue cp -R "$src/src/baserow/$missingDir" "$out/${python.sitePackages}/baserow/$missingDir" done + + install -d -m 0755 $out/share/baserow + cp -R "$src/templates" "$out/share/baserow/templates" + + install -m 0755 ${./backend/gunicorn.py} $out/bin/baserow-gunicorn + install -m 0755 ${./backend/celery.py} $out/bin/baserow-celery ''; propagatedBuildInputs = oldAttrs.propagatedBuildInputs ++ (with python.pkgs; [ baserow-premium-backend diff --git a/ops/nixos/lib/baserow.nix b/ops/nixos/lib/baserow.nix new file mode 100644 index 0000000000..b2c0b11746 --- /dev/null +++ b/ops/nixos/lib/baserow.nix @@ -0,0 +1,191 @@ +{ depot, pkgs, lib, ... }: + +let + inherit (depot.nix.pkgs) baserow; + + environment = { + DJANGO_SETTINGS_MODULE = "baserow.config.settings.base"; + PUBLIC_WEB_FRONTEND_URL = "https://baserow.lukegb.com"; + PUBLIC_BACKEND_URL = "https://api.baserow.lukegb.com"; + PRIVATE_BACKEND_URL = "http://localhost:28100"; + MEDIA_URL = "https://baserow-media.zxcvbnm.ninja/"; + MJML_SERVER_HOST = "localhost"; + MEDIA_ROOT = "/var/lib/baserow/media"; + + SECRET_KEY = "zKBu7MIzBki5S3rResh5Vj0kG7Fl0b27OUYCDJvRxe7fWJUcAHL1cR70hZuqECnszFVwSgxv1ZHBaHv6"; + + DATABASE_HOST = ""; + DATABASE_PASSWORD = ""; + REDIS_HOST = "localhost"; + }; + baserow-util = pkgs.stdenv.mkDerivation { + name = "baserow-util"; + dontUnpack = true; + dontBuild = true; + nativeBuildInputs = with pkgs; [ makeWrapper ]; + baserow = baserow.backend; + installPhase = '' + install -d -m 0755 $out/bin + makeWrapper $baserow/bin/baserow $out/bin/baserow \ + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: val: "--set-default '${name}' '${val}' \\") environment)} + ''; + }; +in +{ + environment.systemPackages = [ baserow-util ]; + + users.groups.baserow = {}; + users.users.baserow = { + group = "baserow"; + isSystemUser = true; + }; + + systemd.tmpfiles.rules = [ + "d /var/lib/baserow 0755 baserow baserow -" + "d /var/lib/baserow/media 0750 baserow baserow -" + ]; + + services.postgresql = { + enable = true; + ensureUsers = [{ + name = "baserow"; + ensurePermissions = { + "DATABASE baserow" = "ALL PRIVILEGES"; + }; + }]; + ensureDatabases = [ "baserow" ]; + }; + services.redis.enable = true; + + systemd.services.baserow-mjml-tcpserver = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + ExecStart = "${baserow.mjml-tcpserver}/bin/mjml-tcpserver --port=28101 --host=127.0.0.1 --mjml.minify=true --mjml.validationLevel=strict"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + systemd.services.baserow-frontend = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + inherit environment; + + serviceConfig = { + ExecStart = "${baserow.web-frontend}/bin/baserow-web-frontend --hostname 127.0.0.1 --port 28102"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + systemd.services.baserow-backend = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + inherit environment; + + serviceConfig = { + ExecStart = "${baserow.backend}/bin/baserow-gunicorn -w 5 -b 127.0.0.1:28100 --log-level=debug"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + systemd.services.baserow-worker-celery = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + inherit environment; + + serviceConfig = { + ExecStart = "${baserow.backend}/bin/baserow-celery worker -l INFO -Q celery"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + systemd.services.baserow-worker-export = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + inherit environment; + + serviceConfig = { + ExecStart = "${baserow.backend}/bin/baserow-celery worker -l INFO -Q export"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + systemd.services.baserow-worker-beat = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + inherit environment; + + serviceConfig = { + ExecStart = "${baserow.backend}/bin/baserow-celery beat -l INFO -S redbeat.RedBeatScheduler"; + User = "baserow"; + Group = "baserow"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "on-failure"; + }; + }; + + services.nginx.recommendedProxySettings = true; + services.nginx.recommendedTlsSettings = true; + services.nginx.virtualHosts = { + "baserow.lukegb.com" = { + enableACME = true; + forceSSL = true; + extraConfig = '' + proxy_read_timeout 1800s; + client_max_body_size 0; + chunked_transfer_encoding on; + ''; + locations."/" = { + proxyPass = "http://127.0.0.1:28102"; + }; + }; + "api.baserow.lukegb.com" = { + enableACME = true; + forceSSL = true; + extraConfig = '' + proxy_read_timeout 1800s; + client_max_body_size 0; + chunked_transfer_encoding on; + ''; + locations."/" = { + proxyPass = "http://127.0.0.1:28100"; + proxyWebsockets = true; + }; + }; + "baserow-media.zxcvbnm.ninja" = { + enableACME = true; + forceSSL = true; + + root = "/var/lib/baserow/media"; + locations."/user_files" = { + root = "/var/lib/baserow/media"; + extraConfig = '' + add_header Content-disposition "attachment; filename=$1"; + ''; + }; + locations."/export_files" = { + root = "/var/lib/baserow/media"; + extraConfig = '' + add_header Content-disposition "attachment; filename=$1"; + ''; + }; + }; + }; +} diff --git a/ops/nixos/totoro/default.nix b/ops/nixos/totoro/default.nix index 8d01683f36..cdee4af9b0 100644 --- a/ops/nixos/totoro/default.nix +++ b/ops/nixos/totoro/default.nix @@ -12,6 +12,7 @@ in { ../lib/whitby-distributed.nix ../lib/twitternuke.nix ../lib/quotes.bfob.gg.nix + ../lib/baserow.nix ]; boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];