wip: cleanup, more docs

This commit is contained in:
teutat3s 2023-06-12 15:28:17 +02:00
parent af3c949181
commit 232d6d3f41
Signed by: teutat3s
GPG key ID: 4FA1D3FA524F22C1
10 changed files with 171 additions and 176 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
result result
*.qcow2 *.qcow2
.direnv

View file

@ -1,10 +1,46 @@
# Erpnext on NixOS
### Cachix
Using the https://pub-solar.cachix.org binary cache:
```
cachix use pub-solar
```
Or manually add the following lines to your `~/.config/nix/nix.conf`:
```
substituters = https://cache.nixos.org/ https://pub-solar.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= pub-solar.cachix.org-1:ZicXIxKgdxMtgSJECWR8iihZxHRvu8ObL4n2cuBmtos=
```
Pushing to the https://pub-solar.cachix.org binary cache (in this example, we push the
package `run-erpnext` and its dependencies):
```
nix develop
nix build --json .#run-erpnext \
| jq -r '.[].outputs | to_entries[].value' \
| cachix push pub-solar
```
### NixOS VM
```
nix build '.#nixosConfigurations.test-vm.config.system.build.vm'
./result/bin/run-nixos-vm
# In the VM, use root & empty password to login
# Watch erpnext startup:
# journalctl -fu erpnext.service
# Open http://localhost:8081 in your browser
# User: Administrator
# Password: admin
```
### Docker
``` ```
docker run -d --name erpnext-redis-socketio -p 12311:6379 redis:latest docker run -d --name erpnext-redis-socketio -p 12311:6379 redis:latest
docker run -d --name erpnext-redis-queue -p 6379:6379 redis:latest docker run -d --name erpnext-redis-queue -p 6379:6379 redis:latest
docker run -d --name erpnext-db -p 3306:3306 -e MARIADB_ROOT_PASSWORD=password -e MARIADB_DATABASE=erpnext -e MARIADB_USER=erpnext -e MARIADB_PASSWORD=erpnext mariadb:latest --collation-server=utf8mb4_unicode_ci docker run -d --name erpnext-db -p 3306:3306 -e MARIADB_ROOT_PASSWORD=password -e MARIADB_DATABASE=erpnext -e MARIADB_USER=erpnext -e MARIADB_PASSWORD=erpnext mariadb:latest --collation-server=utf8mb4_unicode_ci
nix build .#runErpNext nix build .#run-erpnext
./result/bin/runErpNext ./result/bin/run-erpnext
# new terminal # new terminal
nix shell nixpkgs#nginx nix shell nixpkgs#nginx
@ -13,3 +49,12 @@ nginx -c /tmp/erpnext/nginx-erpnext.conf -g "daemon off;"
# User: Administrator # User: Administrator
# Password: admin # Password: admin
``` ```
### Links:
- https://erpnext.com
- https://docs.erpnext.com/docs/v14/user/manual/en/setting-up
- https://discuss.frappe.io/t/installing-the-docker-image-on-a-local-machine-without-letsencrypt-so-we-can-access-it-with-http-localhost/87585/7
- https://github.com/frappe/frappe_docker/blob/main/images/production/Containerfile
- https://github.com/frappe/bench
- https://github.com/frappe/erpnext
- https://github.com/frappe/frappe

View file

@ -1,5 +1,28 @@
{ {
"nodes": { "nodes": {
"devshell": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1685972731,
"narHash": "sha256-VpwVUthxs3AFgvWxGTHu+KVDnS/zT3xkCtmjX2PjNQs=",
"owner": "numtide",
"repo": "devshell",
"rev": "6b2554d28d46bfa6e24b941e999a145760dad0e1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1685655444, "lastModified": 1685655444,
@ -16,26 +39,10 @@
"type": "github" "type": "github"
} }
}, },
"pip2nix": {
"flake": false,
"locked": {
"lastModified": 1681921436,
"narHash": "sha256-jrUOMhpOFxrgCXNgMWz475nKZdMiSQb0+nbaIqQORSM=",
"owner": "nix-community",
"repo": "pip2nix",
"rev": "2ad8bd4c841116a1b9ab7853a53ed2d38e0ab93f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "pip2nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"devshell": "devshell",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"pip2nix": "pip2nix",
"systems": "systems" "systems": "systems"
} }
}, },

View file

@ -2,42 +2,71 @@
description = "Dev Setup"; description = "Dev Setup";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.systems.url = "github:nix-systems/default";
inputs.pip2nix = {
url = "github:nix-community/pip2nix";
flake = false;
};
outputs = {nixpkgs, systems, pip2nix, ...}: inputs.systems.url = "github:nix-systems/default";
inputs.devshell.url = "github:numtide/devshell";
inputs.devshell.inputs.nixpkgs.follows = "nixpkgs";
inputs.devshell.inputs.systems.follows = "systems";
outputs = {self, nixpkgs, systems, devshell }:
let let
eachSystem = nixpkgs.lib.genAttrs (import systems); eachSystem = nixpkgs.lib.genAttrs (import systems);
pkgs = import nixpkgs { # Nixpkgs instantiated for system types in nix-systems
system = "x86_64-linux"; nixpkgsFor = eachSystem (system:
overlays = [ import nixpkgs {
(import ./python-overlay.nix) inherit system;
(import ./overlay.nix) overlays = [
]; self.overlays.default
}; self.overlays.pythonOverlay
devshell.overlays.default
];
}
);
in in
{ {
packages = eachSystem (system: { overlays = {
devEnv = pkgs.buildEnv { default = (import ./overlay.nix);
name = "erpnext-nix-dev-env"; pythonOverlay = (import ./python-overlay.nix);
paths = [ };
pkgs.dasel devShells = eachSystem (system:
let
pkgs = nixpkgsFor.${system};
in
{
default = pkgs.devshell.mkShell {
# Add additional packages you'd like to be available in your devshell
# PATH here
devshell.packages = with pkgs; [
]; ];
commands = [
{
help = pkgs.cachix.meta.description;
name = pkgs.cachix.pname;
package = pkgs.cachix;
}
];
bash.extra = ''
'';
}; };
inherit pkgs;
run-erpnext = pkgs.run-erpnext;
pip2nix = import "${pip2nix}/default.nix" { inherit pkgs; pythonPackages = "python310Packages"; };
erpnext = pkgs.python3-erpnext.pkgs.erpnext;
bench = pkgs.python3-erpnext.pkgs.bench;
pythonPkgs = pkgs.python3-erpnext.pkgs;
}); });
nixosConfigurations = { packages = eachSystem (system:
let
pkgs = nixpkgsFor.${system};
in
{
run-erpnext = pkgs.run-erpnext;
erpnext = pkgs.python3.pkgs.erpnext;
bench = pkgs.python3.pkgs.bench;
});
nixosConfigurations =
let
system = "x86_64-linux";
pkgs = nixpkgsFor.${system};
in
{
test-vm = nixpkgs.lib.nixosSystem { test-vm = nixpkgs.lib.nixosSystem {
inherit pkgs; inherit system pkgs;
system = "x86_64-linux";
modules = [./test-vm/configuration.nix]; modules = [./test-vm/configuration.nix];
}; };
}; };

View file

@ -1,7 +1,7 @@
self: super: { final: prev: {
run-erpnext = self.callPackage ./scripts/run-erpnext.nix {}; run-erpnext = final.callPackage ./scripts/run-erpnext.nix {};
frappe-erpnext-assets = self.callPackage ./node/frappe-erpnext-assets.nix {}; frappe-erpnext-assets = final.callPackage ./node/frappe-erpnext-assets.nix {};
erpnext-app = self.callPackage ./node/erpnext-app.nix {}; erpnext-app = final.callPackage ./node/erpnext-app.nix {};
frappe-app = self.callPackage ./node/frappe-app.nix {}; frappe-app = final.callPackage ./node/frappe-app.nix {};
erpnext-nginx-conf = self.callPackage ./nginx-erpnext-conf.nix {}; erpnext-nginx-conf = final.callPackage ./nginx-erpnext-conf.nix {};
} }

View file

@ -1,111 +1,50 @@
self: super: { final: prev: {
python3-erpnext = super.python3.override { python3 = prev.python3.override {
packageOverrides = pyself: pysuper: { packageOverrides = pyFinal: pyPrev: {
bench = pyself.callPackage ./python/bench.nix {}; bench = pyFinal.callPackage ./python/bench.nix {};
erpnext = pyself.callPackage ./python/erpnext.nix {}; erpnext = pyFinal.callPackage ./python/erpnext.nix {};
frappe = pyself.callPackage ./python/frappe.nix {}; frappe = pyFinal.callPackage ./python/frappe.nix {};
email-reply-parser = pyself.callPackage ./python/email-reply-parser.nix {}; email-reply-parser = pyFinal.callPackage ./python/email-reply-parser.nix {};
git-url-parse = pyself.callPackage ./python/git-url-parse.nix {}; git-url-parse = pyFinal.callPackage ./python/git-url-parse.nix {};
gocardless-pro = pyself.callPackage ./python/gocardless-pro.nix {}; gocardless-pro = pyFinal.callPackage ./python/gocardless-pro.nix {};
honcho = pyself.callPackage ./python/honcho.nix {}; honcho = pyFinal.callPackage ./python/honcho.nix {};
jsonobject = pyself.callPackage ./python/jsonobject.nix {}; jsonobject = pyFinal.callPackage ./python/jsonobject.nix {};
maxminddb-geolite2 = pyself.callPackage ./python/maxminddb-geolite2.nix {}; maxminddb-geolite2 = pyFinal.callPackage ./python/maxminddb-geolite2.nix {};
posthog = pyself.callPackage ./python/posthog.nix {}; posthog = pyFinal.callPackage ./python/posthog.nix {};
psycopg2-binary = pyself.callPackage ./python/psycopg2-binary.nix {}; psycopg2-binary = pyFinal.callPackage ./python/psycopg2-binary.nix {};
pypdf2 = pyself.callPackage ./python/pypdf2.nix {}; pypdf2 = pyFinal.callPackage ./python/pypdf2.nix {};
pypika = pyself.callPackage ./python/pypika.nix {}; pypika = pyFinal.callPackage ./python/pypika.nix {};
python-youtube = pyself.callPackage ./python/python-youtube.nix {}; python-youtube = pyFinal.callPackage ./python/python-youtube.nix {};
rauth = pyself.callPackage ./python/rauth.nix {}; rauth = pyFinal.callPackage ./python/rauth.nix {};
redisearch = pyself.callPackage ./python/redisearch.nix {}; redisearch = pyFinal.callPackage ./python/redisearch.nix {};
rejson = pyself.callPackage ./python/rejson.nix {}; rejson = pyFinal.callPackage ./python/rejson.nix {};
taxjar = pyself.callPackage ./python/taxjar.nix {}; taxjar = pyFinal.callPackage ./python/taxjar.nix {};
traceback-with-variables = pyself.callPackage ./python/traceback-with-variables.nix {}; traceback-with-variables = pyFinal.callPackage ./python/traceback-with-variables.nix {};
#barcodenumber = pysuper.barcodenumber.overridePythonAttrs (oldAttrs: (rec { bleach = pyPrev.bleach.overridePythonAttrs (oldAttrs: (rec {
# version = "0.5.0";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-VZfHLwSF9aDoy5L1x4O2mu8/f2ijYKgyjCrQ1KKY5Ho=";
# };
#}));
bleach = pysuper.bleach.overridePythonAttrs (oldAttrs: (rec {
version = "3.3.1"; version = "3.3.1";
src = pysuper.fetchPypi { src = pyPrev.fetchPypi {
inherit version; inherit version;
inherit (oldAttrs) pname; inherit (oldAttrs) pname;
sha256 = "sha256-MGSDpal5VHQWCtV/zj3dG1BVHpge7Y4VpYLTTO8oqvo="; sha256 = "sha256-MGSDpal5VHQWCtV/zj3dG1BVHpge7Y4VpYLTTO8oqvo=";
}; };
})); }));
#phonenumbers = pysuper.phonenumbers.overridePythonAttrs (oldAttrs: (rec { plaid-python = pyPrev.plaid-python.overridePythonAttrs (oldAttrs: (rec {
# version = "8.12.40";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-APKVWkVrRY+barDSQykEnD5zWMRN/Bl5/kkIztQPHrg=";
# };
#}));
plaid-python = pysuper.plaid-python.overridePythonAttrs (oldAttrs: (rec {
version = "7.2.1"; version = "7.2.1";
src = pysuper.fetchPypi { src = pyPrev.fetchPypi {
inherit version; inherit version;
inherit (oldAttrs) pname; inherit (oldAttrs) pname;
sha256 = "sha256-ryrTJug3fIyG2XGE9gwL5BzXH1B1IB39szMcyF1N5RM="; sha256 = "sha256-ryrTJug3fIyG2XGE9gwL5BzXH1B1IB39szMcyF1N5RM=";
}; };
propagatedBuildInputs = [ pysuper.requests ]; propagatedBuildInputs = [ pyPrev.requests ];
checkInputs = [ pysuper.pytest ]; checkInputs = [ pyPrev.pytest ];
# Integration tests require API keys and internet access # Integration tests require API keys and internet access
checkPhase = "py.test -rxs ./tests/unit"; checkPhase = "pyPrev.test -rxs ./tests/unit";
})); }));
#pycountry = pysuper.pycountry.overridePythonAttrs (oldAttrs: (rec { tweepy = pyPrev.tweepy.overridePythonAttrs (oldAttrs: (rec {
# version = "20.7.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-gQhKU9NFQ0TAKS3uvCD80KFIjBNtSQAxLL1GXPVSy0I=";
# };
#}));
#pymysql = pysuper.pymysql.overridePythonAttrs (oldAttrs: (rec {
# version = "1.0.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-PdqUPvNpQGinXWnQcXVdvsrO4a35ofxbIGgw0rZ9Jeg=";
# };
# format = "pyproject";
# buildInputs = [pysuper.setuptools];
#}));
#pypng = pysuper.pypng.overridePythonAttrs (oldAttrs: (rec {
# version = "0.20220715.0";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-c5xDO6lvB4MV3lTA25da7lN8vD4dCuTtmqsMoeQn4sE=";
# };
#}));
#pytz = pysuper.pytz.overridePythonAttrs (oldAttrs: (rec {
# version = "2022.1";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-HnYOL+aoFjvAs9mhnE+ENCr6Cir/6/qoSwG5eKAuyqc=";
# };
#}));
#redis = pysuper.redis.overridePythonAttrs (oldAttrs: (rec {
# version = "3.5.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-Dn4M/KhmDeqLfVzYxPbF4p4R8xFYwLCukaOX8A5aBaI=";
# };
# pythonImportsCheck = [];
# # tests require a running redis
# doCheck = false;
#}));
tweepy = pysuper.tweepy.overridePythonAttrs (oldAttrs: (rec {
version = "3.10.0"; version = "3.10.0";
src = pysuper.fetchPypi { src = pyPrev.fetchPypi {
inherit version; inherit version;
inherit (oldAttrs) pname; inherit (oldAttrs) pname;
sha256 = "sha256-duaVS4BspHDdqHf1fbh5L/8GoL66DtQ+/DgFdx458Go="; sha256 = "sha256-duaVS4BspHDdqHf1fbh5L/8GoL66DtQ+/DgFdx458Go=";
@ -113,14 +52,6 @@ self: super: {
doCheck = false; doCheck = false;
pythonImportsCheck = []; pythonImportsCheck = [];
})); }));
#unidecode = pysuper.unidecode.overridePythonAttrs (oldAttrs: (rec {
# version = "1.2.0";
# src = pysuper.fetchPypi {
# inherit version;
# pname = "Unidecode";
# sha256 = "sha256-jXOpfTh6lWkiNE9rdCQ8LGdxWUZZd4dEstvarY9rcn0=";
# };
#}));
}; };
}; };
} }

View file

@ -53,10 +53,4 @@ buildPythonPackage rec {
python-stdnum python-stdnum
frappe frappe
]; ];
#nativeCheckInputs = [
# bench
#];
#checkPhase = ''
# bench --site test_site run-tests --app erpnext
#'';
} }

View file

@ -208,17 +208,4 @@ buildPythonPackage rec {
google-auth google-auth
posthog posthog
]; ];
#nativeCheckInputs = [
# bench
# redis
#];
#checkPhase = ''
# tmp=$(mktemp -d)
# cd $tmp
# bench -v init frappe-bench --skip-assets
# cd frappe-bench
# mkdir -p sites/test_site
# bench --site test_site run-tests --app frappe
#'';
} }

View file

@ -128,11 +128,11 @@
systemd.services.erpnext = systemd.services.erpnext =
let let
penv = pkgs.python3-erpnext.buildEnv.override { penv = pkgs.python3.buildEnv.override {
extraLibs = [ extraLibs = [
pkgs.python3-erpnext.pkgs.frappe pkgs.python3.pkgs.frappe
pkgs.python3-erpnext.pkgs.erpnext pkgs.python3.pkgs.erpnext
pkgs.python3-erpnext.pkgs.bench pkgs.python3.pkgs.bench
]; ];
}; };
appsFile = pkgs.writeText "erpnext-apps.txt" '' appsFile = pkgs.writeText "erpnext-apps.txt" ''
@ -166,7 +166,7 @@
packages = [ pkgs.mariadb-client pkgs.nodejs penv ]; packages = [ pkgs.mariadb-client pkgs.nodejs penv ];
}; };
script = '' script = ''
export PYTHON_PATH=${penv}/${pkgs.python3-erpnext.sitePackages} export PYTHON_PATH=${penv}/${pkgs.python3.sitePackages}
export PATH="${pkgs.mariadb-client}/bin:${pkgs.nodejs}/bin:${penv}/bin:$PATH" export PATH="${pkgs.mariadb-client}/bin:${pkgs.nodejs}/bin:${penv}/bin:$PATH"
# Upstream initializes the DB with this command # Upstream initializes the DB with this command