Commit Graph
67 Commits
Author SHA1 Message Date
awkawbandClaude Sonnet 5 2c9915699d nixos-module: run db migrations on every activation, not just once
The .initial-migration marker file prevented `migrate --force` from ever
running again after the first activation, so migrations shipped by a later
invoiceninja version upgrade would never apply to an already-deployed
instance. `migrate` is idempotent (Laravel tracks applied migrations in the
DB), so just run it unconditionally on every activation instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-02 13:15:00 -04:00
awkawbandClaude Sonnet 5 bd112541e5 nixos-module: use playwright's chromium-headless-shell instead of pkgs.chromium for PDF generation
snappdf only ever shells out to `$SNAPPDF_CHROMIUM_PATH --headless --print-to-pdf=...`,
so the full browser UI/GPU stack pkgs.chromium ships is unnecessary. Google's official
"Chrome for Testing" headless-only build (packaged by nixpkgs' playwright-driver,
selected via `browsers.override` with every other browser/ffmpeg disabled) does the
same job for a ~1.45GB smaller closure (431MB vs 1.88GB), needs no allowUnfree, and
PDF generation is noticeably faster in the VM test (~2.5s vs ~10s per request).

Drops the now-unnecessary allowUnfree wiring from the interactive VM and automated
test configs, which existed solely to build pkgs.chromium.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 18:19:38 -04:00
awkawbandClaude Sonnet 5 b883e04303 package: strip composer-repository store path from runtime closure
composer.lock and vendor/composer/installed.json record each package's
"dist.url" as the store path of the build-time composer-repository
mirror, which drags that whole ~570MB fixed-output derivation into the
runtime closure even though it's just install provenance -- neither
Laravel's package manifest (name/extra only) nor Composer's runtime
InstalledVersions (reads installed.php, not this file) consult it.
Cuts the package closure from ~1.75GB to ~1.18GB.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 17:39:14 -04:00
awkawbandClaude Sonnet 5 8216a723f0 tests: add client/invoice/payment end-to-end check
Extracts small api_get/api_post helpers to cut the repeated curl/header/
json.loads boilerplate, then uses them for a new subtest that creates a
client, invoices it, marks the invoice sent, and pays it in full - checking
the invoice comes back paid with a zero balance. Runs after the PDF preview
check, since PreviewController::blankEntity only builds its mock PDF when
the company has no invoices/invitations yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 17:15:26 -04:00
awkawbandClaude Sonnet 5 ef08e0d7fc package: update invoiceninja to v5.13.43, ui to 28.09.2026.1
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 20:28:11 -04:00
awkawbandClaude Sonnet 5 330ec8c503 tests: fix APP_URL port mismatch in the interactive VM
`just boot-vm` forwards the guest's port 80 to host port 8080
(QEMU_NET_OPTS in the justfile), but the backend builds absolute URLs
(e.g. the stored company logo path returned by the upload API) from
APP_URL, which defaults to plain "http://localhost" with no port. The
SPA's own relative URLs are fine - they inherit whatever port the
browser is already on - but any backend-generated absolute URL then
points at host port 80, where nothing is listening, instead of the
forwarded 8080. That gave a silent net::ERR_CONNECTION_REFUSED for the
logo image specifically, even though the upload itself succeeded.

Verified directly: with APP_URL overridden to "http://localhost:8080",
a freshly uploaded logo's URL is
"http://localhost:8080/storage/.../....png" instead of missing the
port. Automated test checks are unaffected (checks derivation hash
unchanged) since they curl the guest's own localhost directly, with no
host-side port remap involved.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 16:47:23 -04:00
awkawbandClaude Sonnet 5 b1fe86e9d5 tests: give the interactive VM enough RAM to not OOM under real use
Root-caused a "logo upload hangs, connection refused in browser
console" report: the qemu-vm module's defaults (1 core, 1024MB) are
too tight for this stack (MySQL + Redis + PHP-FPM + chromium for PDF
generation, each PDF request spawning a full multi-process browser
instance) under real concurrent load, and this VM boots with
panic_on_oom - so exhausting memory doesn't degrade gracefully, the
whole VM goes down and every connection starts refusing.

Reproduced directly: at the 1024MB default, even 2 concurrent PDF
generation requests triggered `redis-server invoked oom-killer` and a
kernel panic. Bumped to 2 cores / 2560MB, which comfortably survives
that same load (~1.4GB still free afterward) - verified via the exact
concurrent-request scenario that crashed the 1024MB config, not just
absence of errors.

virtualisation.cores/memorySize aren't options on a plain nixosSystem
in this nixpkgs (only nixosTest nodes get the qemu-vm module
automatically), so this also adds an explicit import of it.

Documented the underlying resource cost (chromium is a full browser
per PDF request, pm.max_children=8 means up to 8 can run concurrently)
in CLAUDE.md as an operational note for real deployments, not just
this test VM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 16:36:22 -04:00
awkawbandClaude Sonnet 5 ccf4d01a34 tests: add end-to-end PDF generation check
Exercises the chromium/snappdf pipeline via POST /api/v1/preview with
no entity, which falls back to PdfMock's self-contained mock PDF -
verified this needs no client/invoice test data, since a fresh account
has neither. Asserts the response starts with the %PDF magic bytes.

This was previously the biggest untested path in the module: an actual
binary runtime dependency (chromium) rather than just config, and the
kind of thing that silently breaks in a minimal NixOS closure.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 15:50:24 -04:00
awkawbandClaude Sonnet 5 fd055f0cf9 nixos-module: remove nginx recommendedProxySettings, keep recommendedOptimisation
recommendedProxySettings only adds proxy_* directives (proxy_redirect,
proxy_connect_timeout, proxy_set_header Connection, etc.), which only
take effect on locations using proxy_pass. This vhost only ever uses
fastcgi_pass for PHP, so the setting was inert here.

recommendedOptimisation (sendfile/tcp_nopush/tcp_nodelay/keepalive)
does apply regardless of proxy_pass vs fastcgi_pass, so it's kept.
Verified via the full automated test suite (both proxy backends).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 15:33:43 -04:00
awkawbandClaude Sonnet 5 7d7d717745 nixos-module: work around upstream language-list caching bug
Migration 2025_08_31_224356_additional_languages_af_ca_id.php runs
during `migrate`, before db:seed's LanguageSeeder has populated the
other 42 rows of the languages table, and does
Cache::forever('languages', Language::all()) - permanently caching
just the 3 languages (Afrikaans, Catalan, Indonesian) it sees at that
moment. StaticServiceProvider checks this cache key before ever
querying the DB again, so every fresh install's language dropdown
(e.g. the "Welcome to Invoice Ninja" company setup wizard) was stuck
showing only those 3 entries, in their own native-language spelling
(ctrans() translates each name using the active locale).

Adds an unconditional `invoiceninja-manage cache:forget languages` to
invoiceninja-data-setup.service, and a regression test asserting
/api/v1/statics returns more than 40 languages. Verified directly:
before the fix, a fresh account's statics call returned exactly 3
languages; after, it returns all 45.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 15:17:22 -04:00
awkawbandClaude Sonnet 5 d7fea37e25 nixos-module: fix caddy Host-header matching for 127.0.0.1/[::1]
Caddy strictly matches vhosts on the exact Host header, unlike nginx
where a single vhost acts as the default regardless of Host. With
hostname = "localhost" (the local-dev default), visiting the VM via
http://127.0.0.1:PORT instead of http://localhost:PORT sent a Host
header matching no vhost, and Caddy silently returned an empty 200 OK
- a genuine white screen with no error anywhere (not in the console,
not in the network tab).

Adds serverAliases for 127.0.0.1:80 and [::1]:80 to the caddy vhost
when hostname is "localhost", so all three ways of reaching the local
VM resolve to the same site block. Verified directly: before this
fix, curl with `Host: 127.0.0.1` got an empty response while `Host:
localhost` got the full app shell; after, all three (localhost,
127.0.0.1, [::1]) return the same 200 response.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 14:37:12 -04:00
awkawbandClaude Sonnet 5 a71ccc87bb nixos-module: remove proxy-level CORS headers
Laravel's own CORS middleware already sends a complete, correct set of
Access-Control-* headers on every response. The nginx and caddy vhost
configs were additionally setting a second, static set of the same
headers, producing duplicates with conflicting values (e.g. two
Access-Control-Allow-Methods headers, one "*" and one the app's real
list). Browsers reject responses with duplicate/conflicting CORS
headers - curl-based checks never noticed since only browsers enforce
CORS header validation, but it broke real browser usage (login/API
calls failing silently).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 14:35:53 -04:00
awkawbandClaude Sonnet 5 4c97391a33 tests: exercise both nginx and caddy proxy backends
Parameterizes tests/common.nix and tests/default.nix on proxyServer
(default "nginx"), giving flake.nix two nixosConfigurations
(test-nginx/test-caddy) and `just build-vm [proxy]` a way to pick
between them for interactive testing.

The automated nixosTest now boots one node per proxy backend and runs
the full assertion suite (factored into check_invoiceninja()) against
each, so a regression in either nginx or caddy's config gets caught.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 14:33:50 -04:00
awkawbandClaude Sonnet 5 fef9406b63 nixos-module: add scheduler timer for artisan schedule:run
Invoice Ninja relies on Laravel's scheduler for recurring invoices,
scheduled reports, and other internal cron-driven jobs. Without a
systemd unit invoking `artisan schedule:run` periodically, the app's
dashboard reports "cron jobs are not enabled" after login.

Adds invoiceninja-scheduler.timer (every minute, matching upstream's
documented cron cadence) and its oneshot service, and extends the
automated test to assert the timer is active and schedule:run succeeds.

Note: the app's own is_scheduler_running flag only flips on a 5-minute
wall-clock boundary (app/Console/Kernel.php's everyFiveMinutes() job),
so the dashboard warning can take a few minutes to clear after boot -
confirmed working via the "Refresh Data" button in that same modal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 13:06:00 -04:00
awkawbandClaude Sonnet 5 2c0a48b899 Add automated NixOS VM test and CLAUDE.md
Adds a pkgs.testers.nixosTest (checks.<system>.invoiceninja) that boots
the module end-to-end and checks that mysql/redis/phpfpm/queue-worker/
nginx come up, the one-time migrate/seed/admin-create setup completed,
the app shell and /login page are served, invoiceninja-manage works,
and the seeded admin can log in via the API.

Factors the shared services.invoiceninja config used by both the
interactive VM and the new test into tests/common.nix, and satisfies
NixOS's fileSystems/bootloader assertions in the interactive VM config
so `nix flake check` evaluates nixosConfigurations.test cleanly (the
qemu-vm module already overrides both when actually building
config.system.build.vm, so this only affects the toplevel-eval path).

Also adds a `just test` recipe, a CLAUDE.md codebase overview, and a
.gitignore for the result/nixos.qcow2 build artifacts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 12:10:41 -04:00
awkawb d7633e66ce flake.lock: updated nixpkgs input 2026-08-14 16:18:30 -04:00
awkawb f6e5c15afd flake.nix: updated nixpkgs input to latest NixOS release 2026-08-14 16:18:03 -04:00
awkawb df90f25778 tests/default.nix: removed user test, added password declaration for root user
This makes testing/debugging easier by allowing to login as root
directly. The previous test system configuration added a step to this
process by forcing devs to login as test and use sudo to escalate to
root.
2026-08-14 16:15:55 -04:00
awkawb 554f73d477 tests/default.nix: removed system.stateVersion declaration
Having the declaration of system.stateVersion just adds more
maintainance for devs. For example, changing the nixpkgs value in
flake.nix requires a change of system.stateVersion in tests/default.nix.
2026-08-14 16:15:55 -04:00
awkawb 5de2563c0f flake.lock: updated flake inputs 2026-05-25 19:12:41 -04:00
awkawb b37f121f06 flake.nix: updated nixpkgs input to version 25.11 2026-05-25 19:11:06 -04:00
awkawb 878134dd4b nixos-module/invoiceninja.nix: update nginx to work with Invoice Ninja 2026-05-25 19:09:49 -04:00
awkawb 808b9a7fe9 Replaced Makefile with justfile 2026-05-25 19:02:53 -04:00
awkawb 6b0f38d59e tests/default.nix: updated system.stateVersion 2026-05-25 19:02:21 -04:00
awkawb fd776bb9b7 package.nix: updated to build Invoice Ninja with React frontend 2026-05-25 19:01:26 -04:00
awkawb a42d01edd3 package.nix: bumped version to 5.12.13 2025-08-13 18:34:59 -04:00
awkawb 1df11adbde Merge branch 'master' of gitea.awkawb.cloud:awkawb/invoiceninja-nixos 2025-03-01 11:11:58 -05:00
awkawb e8b208accb flake.lock: updated flake inputs 2025-02-24 17:32:32 -05:00
awkawb 295b299fdd package.nix: bumped version to 5.11.41 2025-02-24 17:29:51 -05:00
awkawb d898e26cb1 package.nix: bumped version to 5.11.24 2025-01-14 16:54:51 -05:00
awkawb 7b2072e5b0 package.nix: remove unneeded move and link statements 2025-01-02 16:55:02 -05:00
awkawb 611709cb62 nixos-module/invoiceninja.nix: changed nixos module definition for nginx to allow local development, removed unneeded link in data setup service 2025-01-02 16:53:58 -05:00
awkawb 730715014e tests/default.nix: modified to reflect package name change 2025-01-02 16:22:09 -05:00
awkawb 4bddba21da flake.nix: fixed attribute name 2025-01-01 16:15:10 -05:00
awkawb 8549d2f23d Makefile: build-vm now reflects the repo being a flake 2025-01-01 12:19:25 -05:00
awkawb 91d8d8a908 flake.nix: modified to reflect package name change, add nixos config for development 2025-01-01 12:17:55 -05:00
awkawb 2b98375f9b tests/default.nix: added stateVersion, added import of nixos module, fixed typo 2025-01-01 12:12:59 -05:00
awkawb 4cb4a1c05d Package is now 'invoiceninja', modified code to reflect name change, changed nixos module definition for caddy to allow local development 2025-01-01 12:11:18 -05:00
awkawb 14976fdae9 Added tests directory for testing in vm 2024-12-30 10:19:29 -05:00
awkawb 1e48f190da Removed unused files and directories 2024-12-28 16:19:55 -05:00
awkawb 85de24655f packages.nix: bumped version to 5.11.7 2024-12-28 16:11:25 -05:00
awkawb 9bb2d8f352 package.nix: bumped version to 5.11.6 2024-12-28 16:09:49 -05:00
awkawb e043ebbaea package.nix: bumped version to 5.11.5 2024-12-28 15:40:58 -05:00
awkawb 5178b6b7cb package.nix: bumped version to 5.11.4 2024-12-28 14:30:08 -05:00
awkawb 79b5fa07eb nixos-module/invoice-ninja.nix: fixed typo 2024-12-28 11:51:42 -05:00
awkawb 4f71751bfb nixos-module/invoice-ninja.nix: proxys are now imported using modulesPath 2024-12-28 11:50:00 -05:00
awkawb e49ffa479b nixos-module/default.nix: fixed typo 2024-12-28 11:28:32 -05:00
awkawb 86c794f84b nixos-module/default.nix: fixed typo 2024-12-27 17:20:08 -05:00
awkawb 209f5d3454 Updated repo to make it a Nix Flake 2024-12-27 16:18:59 -05:00
awkawb 038d6fb3bf Merge branch 'master' of gitea.awkawb.cloud:awkawb/invoice-ninja-nixos 2024-12-27 16:00:24 -05:00
awkawb 1b5a64e29a invoice-ninja.nix: a bunch of updates and changes 2024-12-27 15:51:15 -05:00
awkawb f866421659 default.nix: updated Invoice Ninja version, added patch to disable react 2024-12-27 15:50:00 -05:00
awkawb 25b54cd352 Refactored NixOS module
* Admin account configuration
* Proxy server configuration
2024-10-16 09:30:39 -04:00
awkawb 6b016669ec Merge pull request 'working merges with master' (#2) from working into master
Reviewed-on: awkawb/invoice-ninja-nixos#2
2024-10-14 16:30:45 -04:00
awkawb 449c52239a Updated test-config to use modules sendmail feature 2024-10-14 16:26:43 -04:00
awkawb 3a5c532992 Updated NixOS module to support sending emails with msmtp 2024-10-14 16:26:08 -04:00
awkawb 91a0d4e71a Work on sendmail to send emails 2024-10-13 13:08:04 -04:00
awkawb 048ca07f4b Work on Laravel queue 2024-10-11 14:41:42 -04:00
awkawb e6f752704f Updated Invoice Ninja derivation to v5.10.34 2024-10-11 14:41:19 -04:00
awkawb eb0326f1d4 Changes to nixos module
* removed package call
* changed systemd queue worker name
* changed interval option name
* changed assertions
* changed app environment file defaults
* changed app data setup systemd job to only run database seeder on
initial setup
2024-10-10 18:10:22 -04:00
awkawb d7ee5fa774 Changed phpfpm setting refactoring
* moved listen.owner from config to implemetation
* moved listen.group from config to implementation
* moved catch_workers_output from config to implementation
2024-10-06 22:33:57 -04:00
awkawb 5f862fe8d3 Updated Invoice Ninja to v5.10.31
* Changed php environment packages
* Added patch to switch back to Flutter
* Added patch to fix storage permissions
2024-10-06 21:48:09 -04:00
awkawb 1abeb7dc5a Added Nginx as a proxy server option
* Nginx is the default proxy server
2024-10-06 13:30:32 -04:00
awkawb 60640a5023 Work on Invoice Ninja v5.10.29
* Module now uses caddy instead of nginx
* Module now has adminEmail and adminPassword options
2024-10-04 09:56:33 -04:00
awkawb e8461e398c Changed Makefile
* build-vm target is more reproducible
* boot-vm target now forward host port 8080 to vm port 80
2024-09-27 08:53:01 -04:00
awkawb 553674743b Changed test-config.nix
* Cleaned up function args
* Removed create-invoice-ninja-user script
* test-user is now test
2024-09-27 08:49:29 -04:00
awkawb 2dd1579547 Initial commit 2024-07-04 13:56:50 -04:00