Compare commits

...

201 Commits

Author SHA1 Message Date
David Bomba
f79afe3dcf Set default memory limit 2025-12-18 09:06:57 +11:00
David Bomba
720d17aac0 Merge pull request #833 from benbrummer/octane
unicode emoji for dockerhub
2025-11-05 09:46:19 +11:00
Benjamin Brummer
8d53a0d915 unicode emoji 2025-11-04 14:11:16 +01:00
David Bomba
a29e6f3d18 Fixes for release for debian/octane 2025-11-04 10:00:06 +11:00
David Bomba
48fd2fdf9d Merge pull request #830 from benbrummer/octane
url as argument
2025-10-30 06:58:10 +11:00
Benjamin Brummer
97c2a4cf27 url as argument 2025-10-29 13:48:44 +01:00
David Bomba
026d00dea0 Merge pull request #828 from benbrummer/octane
Align octane with debian
2025-10-29 10:52:51 +11:00
Benjamin Brummer
7848cf055a fix typo 2025-10-28 14:58:43 +01:00
Benjamin Brummer
5434c1e6da update badges 2025-10-28 14:55:27 +01:00
Benjamin Brummer
de60faec4d rename paths in workflow 2025-10-28 14:48:44 +01:00
Benjamin Brummer
41c0b26efb fix tar extraction 2025-10-28 14:46:35 +01:00
Benjamin Brummer
670eb2ce33 Set context to octane 2025-10-28 14:35:17 +01:00
Benjamin Brummer
ea35d304df Use ADD instead of RUN 2025-10-28 14:34:59 +01:00
Benjamin Brummer
64382d89ad Rename files and folders to octane 2025-10-28 14:31:07 +01:00
Benjamin Brummer
7dfe1dadc1 rename files to octane 2025-10-28 14:22:14 +01:00
Benjamin Brummer
7d518c24dc align workflows with debian 2025-10-28 14:20:35 +01:00
David Bomba
a4289dffa3 Merge pull request #817 from benbrummer/octane
Compose file refactoring - Octane
2025-10-01 18:12:08 +10:00
Benjamin Brummer
54e5031703 Default timing configuration for healthcheck should be sufficient 2025-10-01 07:49:24 +02:00
Benjamin Brummer
7eee4e770e disable json logs 2025-10-01 07:37:30 +02:00
Benjamin Brummer
cc2cc537b5 Use docker default logging configuration 2025-10-01 07:34:49 +02:00
benbrummer
5361a2dabf Merge branch 'invoiceninja:octane' into octane 2025-09-30 13:40:56 +02:00
Benjamin Brummer
de1a30979d Do not pass all variables into mysql container 2025-09-30 13:40:07 +02:00
Benjamin Brummer
26aa6b45c1 Mounting .env file is redundant with env_file: 2025-09-30 13:39:14 +02:00
David Bomba
4de9066b39 Merge pull request #813 from benbrummer/octane
Push README.md to Dockerhub
2025-09-30 20:49:36 +10:00
Benjamin Brummer
65fbd0bd5d Use default depth for checkout 2025-09-30 12:40:21 +02:00
Benjamin Brummer
eecea97f7c Push README.md to Dockerhub 2025-09-30 12:37:35 +02:00
David Bomba
ad2a8b35dc Merge pull request #809 from benbrummer/octane
Remove artisan package:discover
2025-09-30 07:07:17 +10:00
Benjamin Brummer
6f9de01d3b matrix build with arm runners 2025-09-29 22:27:42 +02:00
Benjamin Brummer
fa5d522a36 Update upgrade instructions 2025-09-29 14:11:58 +02:00
Benjamin Brummer
84a42794d3 remove package discovery command from production setup 2025-09-29 14:08:50 +02:00
David Bomba
9cd585678c Merge pull request #807 from benbrummer/octane
Optimize artisan commands
2025-09-29 08:09:36 +10:00
Benjamin Brummer
8899d3e956 optimize artisan commands 2025-09-28 10:39:29 +02:00
Benjamin Brummer
f22c7b4f59 Increas start-period as first run might take a long time 2025-09-28 10:39:15 +02:00
David Bomba
d728221b0b Merge pull request #796 from benbrummer/octane
Create app/public
2025-09-09 07:31:43 +10:00
benbrummer
be451b454f Create app/public
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2025-09-08 16:42:23 +02:00
David Bomba
184564e022 Merge pull request #795 from benbrummer/octane
Use correct image for octane
2025-09-05 09:04:31 +10:00
Benjamin Brummer
2f31fc0da8 remove .gitignore and .editorconfig 2025-09-04 21:42:46 +02:00
Benjamin Brummer
7a37b9641d remove folders for bind mounts 2025-09-04 21:42:13 +02:00
Benjamin Brummer
1917de0046 align APP_URL with docker-compose.yaml port 2025-09-04 21:35:36 +02:00
Benjamin Brummer
c9f91b4a45 use octane image in compose file 2025-09-04 21:34:52 +02:00
David Bomba
0117fbd93e Merge pull request #791 from turbo124/octane
Rollback to 8.4
2025-09-03 07:27:52 +10:00
David Bomba
fc7b94a223 Rollback to 8.4 2025-09-03 07:27:05 +10:00
David Bomba
281b6a15a4 Roll back to PHP 8.3 2025-09-02 18:54:36 +10:00
David Bomba
5e6d21646c Merge pull request #788 from benbrummer/octane
Workaround: Disable SSL for mariadb-client for compatibility with MySQL
2025-09-02 06:21:46 +10:00
benbrummer
17c1705fe7 Workaround: Disable SSL for mariadb-client for compatibility with MySQL
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2025-09-01 21:34:09 +02:00
David Bomba
9180712245 Merge pull request #785 from benbrummer/octane
Debian Trixie and php 8.4
2025-08-29 22:02:11 +10:00
benbrummer
94582c4658 Debian Trixie and php 8.4
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2025-08-29 12:57:23 +02:00
David Bomba
3e5035478d Merge pull request #774 from stavros-k/patch-1
Fix init.sh for octane
2025-08-20 07:57:03 +10:00
Stavros Kois
4e80bc01d0 correct dir 2025-08-19 15:58:36 +03:00
Stavros Kois
6e73e3af9d Update init.sh
Makes sure the storage directory exists, otherwise it will fail with

```sh
In ServerStateFile.php line 49:
                                       
  Unable to write to process ID file.  
```

Signed-off-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com>
2025-08-11 12:56:27 +03:00
David Bomba
9944d43f0b Merge pull request #765 from stavros-k/patch-1
Update init.sh
2025-07-07 08:42:59 +10:00
Stavros Kois
5eefcecf47 Update init.sh
Signed-off-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com>
2025-07-03 13:57:12 +03:00
David Bomba
f80e7f2ec3 Merge pull request #752 from benbrummer/octane
saxon defaults now to 12.5.0
2025-05-11 09:44:33 +10:00
benbrummer
f5821630fa saxon defaults now to 12.5.0
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2025-05-10 10:58:40 +02:00
David Bomba
1848f11a36 Merge pull request #751 from benbrummer/octane
align octane to debian
2025-05-08 19:41:31 +10:00
Benjamin Brummer
f96d4d4aa0 image versions as ARGs 2025-05-08 06:58:11 +00:00
Benjamin Brummer
5d29d3a052 align init.sh with invoiceninja-debian 2025-05-08 06:43:50 +00:00
Benjamin Brummer
0c607953ec HEALTHCHECK for laravel 2025-05-08 06:43:23 +00:00
Benjamin Brummer
ebc6c3642a remove cache volume and healthcheck configuration 2025-05-08 06:43:03 +00:00
David Bomba
ec35498159 set conditional for chrome / chromium path 2025-03-25 12:04:11 +11:00
David Bomba
4bff59808e Merge pull request #730 from benbrummer/octane
use github latest url, tar.gz without top level repository, mbstring
2025-03-19 10:05:07 +11:00
benbrummer
217c05bd1f use github latest url, tar.gz without top level repository, mbstring
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2025-03-15 07:41:00 +01:00
David Bomba
24d1f9cd2e Merge pull request #714 from turbo124/octane
Fixes for publish image regression - force 22.04
2025-01-24 16:15:58 +11:00
David Bomba
9a3603b709 Fixes for publish image regression - force 22.04 2025-01-24 16:15:09 +11:00
David Bomba
c2bf3ca8d9 Merge pull request #709 from turbo124/octane
Change context dir from ./debian to debian
2025-01-24 14:28:42 +11:00
David Bomba
1c3f96e723 Change context dir from ./debian to debian 2025-01-24 14:28:11 +11:00
David Bomba
2364f53777 Merge pull request #708 from turbo124/octane
Debug php extension installer
2025-01-24 13:57:28 +11:00
David Bomba
7bfbe9ee03 Install each extension individually to identify the root cause 2025-01-24 13:56:44 +11:00
David Bomba
afd597456f Minor fixes for build files 2025-01-24 13:36:58 +11:00
David Bomba
243f46bd23 Merge pull request #707 from turbo124/octane
Fixes for php extension installer
2025-01-24 13:35:26 +11:00
David Bomba
6dfaa3b441 Fixes for php extension installer 2025-01-24 13:34:52 +11:00
David Bomba
6d0e0648e3 Fixes for php extension installer 2025-01-24 12:58:47 +11:00
David Bomba
85979fdcf2 Require mbstring 2025-01-24 09:22:36 +11:00
David Bomba
377c068667 Merge pull request #690 from benbrummer/octane
Octane
2025-01-15 08:18:57 +11:00
benbrummer
da7f8d93b0 Merge branch 'invoiceninja:octane' into octane 2025-01-13 13:40:31 +01:00
Benjamin Brummer
1d475a5218 php.ini with frankenphp/symfony recommendations 2025-01-12 00:57:51 +00:00
Benjamin Brummer
3a8184df73 fix for initialization with opcache.preload enabled 2025-01-12 00:56:21 +00:00
Benjamin Brummer
0c796fee5f use invoiceninja.tar.gz 2025-01-12 00:54:53 +00:00
David Bomba
bc5aa2e844 Merge pull request #686 from benbrummer/frankenphp
healthcheck for scheduler and worker
2025-01-11 16:40:22 +11:00
Benjamin Brummer
295bb6268b remove moiunt for php.ini 2025-01-10 07:32:58 +00:00
Benjamin Brummer
ff636077d4 --help flag for usage instructions 2025-01-10 07:31:35 +00:00
Benjamin Brummer
247f946422 include minimal php settings in the image 2025-01-10 07:31:03 +00:00
Benjamin Brummer
4c50bbad19 H3_GENERAL_PROTOCOL_ERROR only happens on Firefox 2025-01-09 13:23:29 +00:00
Benjamin Brummer
2e22177b20 permissions are already correct in the release artifact tar/tar.gz 2025-01-09 12:43:05 +00:00
Benjamin Brummer
dfc392580e healthcheck for scheduler and worker 2025-01-09 10:15:37 +00:00
David Bomba
260980f2a3 Merge pull request #685 from benbrummer/frankenphp
https for octane
2025-01-08 13:47:46 +11:00
Benjamin Brummer
57724b7d93 Single RUN for first stage to avoid insane build times 2025-01-07 11:51:09 +00:00
Benjamin Brummer
39b6680f0b added example command for https and caddy_data volume for persistent certificates 2025-01-07 10:04:24 +00:00
David Bomba
768df3c1dd Merge pull request #682 from benbrummer/frankenphp
Cleanup
2025-01-07 13:01:02 +11:00
Benjamin Brummer
7870b345ed composer is not needed 2025-01-05 16:57:56 +00:00
Benjamin Brummer
3c6ed5cda1 remove octane installation 2025-01-04 19:41:05 +00:00
Benjamin Brummer
2f43d4b45a php.ini refactoring 2025-01-04 18:52:36 +00:00
David Bomba
a71af868d2 Add build pipe for octane 2025-01-04 19:36:30 +11:00
David Bomba
237abe4aa8 Merge pull request #678 from benbrummer/frankenphp
Frankenphp
2025-01-03 13:47:40 +11:00
Benjamin Brummer
f680c8a59a require laravel/octane 2024-12-31 17:57:54 +01:00
Benjamin Brummer
8f51f3bc51 octane and multistage 2024-12-31 17:52:48 +01:00
Benjamin Brummer
e4c26dde5d Merge branch 'frankenphp' of https://github.com/benbrummer/dockerfiles into frankenphp 2024-12-28 09:25:43 +01:00
Benjamin Brummer
9c96e9d261 make mysql and redis available/default again 2024-12-28 09:25:25 +01:00
benbrummer
e1cde6b6be Merge branch 'invoiceninja:debian' into frankenphp 2024-12-28 08:58:49 +01:00
Benjamin Brummer
068acdd097 remove nginx, php-fpm and supervisord configuration 2024-12-28 08:36:19 +01:00
Benjamin Brummer
95aec27c65 Merge init scripts 2024-12-28 08:35:19 +01:00
Benjamin Brummer
6c6950d298 frankenphp, mariadb and valkey 2024-12-28 08:33:39 +01:00
David Bomba
3394694ffc Merge pull request #676 from benbrummer/debian
arm64 image with chromium
2024-12-24 18:28:05 +11:00
Benjamin Brummer
99f280319c saxon is available for arm64 and amd64 2024-12-21 20:38:44 +01:00
Benjamin Brummer
470a3d036d EXPOSE is already inherited from base image 2024-12-21 20:37:47 +01:00
Benjamin Brummer
514ebb74c6 No need to have arm64 and amd64 for php extensions 2024-12-21 20:37:16 +01:00
Benjamin Brummer
dc3b87140f Install chromium for arm64 2024-12-21 20:36:20 +01:00
Benjamin Brummer
c0afd971e1 mariadb is the default on debian 2024-12-21 20:32:22 +01:00
Benjamin Brummer
677cc44a15 remove gosu 2024-12-21 20:31:42 +01:00
David Bomba
91c7b1ea2a Merge pull request #673 from turbo124/debian
Updates for github actions
2024-12-11 09:55:32 +11:00
David Bomba
a508ccc41e Updates for github actions 2024-12-11 09:53:54 +11:00
David Bomba
d42f66617c Merge pull request #672 from brdns/debian
Remove nginx `[warn]` log when uploading
2024-12-10 06:10:58 +11:00
brdns
8746015041 Removes nginx logs when uploading: [warn] a client request body is buffered to a temporary file
[warn] a client request body is buffered to a temporary file
Was already fixed with commit bfc61fb64e
Then got reverted by commit 66408fccb2
2024-12-09 18:02:44 +01:00
David Bomba
53c38b65f9 Merge pull request #664 from benbrummer/debian-dev
dockerfile cleanup, apt reduction, php module configuration, allow to run custom CMD
2024-12-06 08:49:18 +11:00
Benjamin Brummer
473e38259f Merge remote-tracking branch 'origin/debian' into debian-dev
CMD was not properly handled
2024-12-05 13:57:10 +01:00
Benjamin Brummer
d538666600 final fix for if statement 2024-12-05 13:47:42 +01:00
Benjamin Brummer
0ace427585 - supervisord.conf defines nodaemon already
- Fix if statement
2024-12-05 13:35:32 +01:00
benbrummer
8c1357fc4c Merge branch 'debian' into debian-dev
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2024-12-05 10:52:43 +01:00
Benjamin Brummer
806a340a00 - make it possible to run a custom CMD
- rename volume according to their origin
- Add arguments for required, suggested and extra php-modules
2024-12-05 10:34:45 +01:00
Benjamin Brummer
d437dab72c remove upload folder 2024-12-04 10:24:10 +01:00
Benjamin Brummer
d64ed83abf temporarly install gpg 2024-12-03 23:57:20 +01:00
Benjamin Brummer
337f38e0dc remove default values 2024-12-03 10:53:13 +01:00
David Bomba
5d5c036175 Merge pull request #667 from turbo124/debian
Patches for copying files
2024-12-03 15:01:54 +11:00
David Bomba
d5ed1935f7 set port 80 2024-12-03 15:01:08 +11:00
David Bomba
5e40e34943 run local init.sh file 2024-12-03 14:59:41 +11:00
David Bomba
c4e1d0e3a5 Updates for copy files 2024-12-03 14:49:58 +11:00
David Bomba
84dcb8caab Merge pull request #665 from turbo124/debian
Update dockerfile
2024-12-03 12:40:39 +11:00
Benjamin Brummer
733e72d5dd curl is already installed 2024-12-02 12:56:24 +01:00
Benjamin Brummer
7eaf6968d2 - fonts-noto-cjk-extra depends on fonts-noto-cjk
- *-dev packages are not required
- fonts depends on libpng16-16 (no dev)
2024-12-02 12:30:17 +01:00
Benjamin Brummer
66408fccb2 align php settings with recommendations opcache/jit from php.net (aligned for php 8.3 and 8.4), increased buffernumber to allow parallel requests without writing to file 2024-12-02 11:53:27 +01:00
Benjamin Brummer
79647d4f8c Fix do not delete public folder on container restart 2024-12-02 11:29:40 +01:00
Benjamin Brummer
067b5eb194 remove value, which matches default 2024-12-01 14:53:48 +01:00
Benjamin Brummer
eed358c32b extended gzip configuration 2024-12-01 14:38:48 +01:00
Benjamin Brummer
71909c73e0 configure chrome during installation 2024-12-01 13:46:58 +01:00
Benjamin Brummer
fab57c9db3 Ensure permissions on volumes are correct
mv public directory inside a single RUN to not increase the image
2024-12-01 12:11:57 +01:00
Benjamin Brummer
e7bc565745 Set correct owner, file and directory permissions. 2024-12-01 10:39:40 +01:00
Benjamin Brummer
87092bb8bd All directories apart of "uploads" exist already 2024-12-01 10:27:06 +01:00
Benjamin Brummer
5abd297c7f switch to user www-data before running tar. tar -o will set correct ownership afterwards. 2024-12-01 09:48:12 +01:00
Benjamin Brummer
8be252781f google-chrome only needs to have ownership for /var/www, which is by default owned by root 2024-12-01 09:42:29 +01:00
David Bomba
f281b33ea1 Update dockerfile 2024-11-30 22:05:28 +11:00
Benjamin Brummer
22d170a4e5 shrink directory configuration 2024-11-29 13:40:46 +01:00
Benjamin Brummer
f722c91d21 Merge chrome related configuration into one RUN 2024-11-29 11:04:11 +01:00
Benjamin Brummer
641b527702 fix if else 2024-11-29 10:48:14 +01:00
Benjamin Brummer
d139a48303 move google-chrome-stable related apt packages to arm64 2024-11-29 10:26:46 +01:00
benbrummer
a75b6f0a00 Merge branch 'invoiceninja:debian' into debian 2024-11-29 09:45:20 +01:00
David Bomba
113c700754 Merge pull request #663 from turbo124/debian
Corrective fixes for new dockerfile
2024-11-29 13:57:39 +11:00
David Bomba
b6be06c977 Corrective fixes for new dockerfile 2024-11-29 13:56:46 +11:00
benbrummer
8c53895c97 Merge branch 'invoiceninja:debian' into debian 2024-11-28 21:52:35 +01:00
Benjamin Brummer
8204465048 cleanup 2024-11-28 21:35:05 +01:00
David Bomba
baad65c737 Merge pull request #661 from benbrummer/debian
php 8.3 and apt package optimization
2024-11-29 07:17:52 +11:00
benbrummer
9fd35b874d second try for nginx
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2024-11-28 16:18:05 +01:00
benbrummer
fe4993f8a3 set correct mount destination for nginx
Signed-off-by: benbrummer <info@benjamin-brummer.de>
2024-11-28 15:50:38 +01:00
Benjamin Brummer
b83fb831b9 - Use default laravel nginx and extend it with invoiceninja -specific settings
- Overwrite php.ini/php-fpm.ini settings with customized settings
2024-11-28 14:04:11 +01:00
Benjamin Brummer
687e74c983 Fix: app-1 for supervisor warning redirect_stderr 2024-11-28 10:55:29 +01:00
Benjamin Brummer
7644151370 memory limits are not aligned with php/opcache and cause error 500 2024-11-28 10:26:23 +01:00
Benjamin Brummer
c84f80f9a9 add build context to docker-compose.yml 2024-11-28 10:23:25 +01:00
Benjamin Brummer
6cfdca078f - Update to php 8.3
- Minimal system packages
  - additional packages will be handled as dependencies of google-chrome-stable (amd64
  - arm64 will still install all apt packages
- "--no-install-recommends" for apt-get
2024-11-28 10:22:05 +01:00
David Bomba
74ed1b2432 Merge pull request #659 from benbrummer/debian
install saxon 12.5.0 with install-php-extensions
2024-11-28 11:28:26 +11:00
Benjamin Brummer
b3b7f7b9f0 - install saxon with install-php-extensions
- replace deprecated apt-key
- artisan optimize will handle caches
2024-11-27 13:01:46 +01:00
David Bomba
a6d8f663ae Merge pull request #656 from benbrummer/debian
Use php.ini-production
2024-11-27 19:27:34 +11:00
David Bomba
3024f11a31 Merge pull request #658 from brdns/debian-dev
move client_max_body_size from default.conf to nginx.conf
2024-11-27 19:19:14 +11:00
Benjamin Brummer
6274c432d9 Fix access for nginx to storage/public 2024-11-26 17:16:09 +01:00
Brandon
f5afd3f527 Revert "Prevents swapping on pdf generation with Chrome"
This reverts commit 3ce5983131.
2024-11-26 16:28:04 +01:00
Brandon
3ce5983131 Prevents swapping on pdf generation with Chrome
Increase allowed memory usage of main container from 512M to 1G

This is useful particularly if the server uses a hard drive, which can drastically slow down pdf generation during swap
2024-11-26 16:22:38 +01:00
Brandon
bfc61fb64e client_max_body_size is a parameter of nginx.conf and not of default.conf (https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size )
add client_body_buffer_size

prevents the following logs: [warn] a client request body is buffered to a temporary file
2024-11-26 16:07:27 +01:00
Benjamin Brummer
535d6d4c06 Refactoring docker-compose.yml 2024-11-26 12:50:59 +01:00
Benjamin Brummer
24d49a4374 refactoring dockerfile 2024-11-26 12:49:12 +01:00
Benjamin Brummer
30ad63f306 Use php.ini-production 2024-11-26 09:46:36 +01:00
David Bomba
60fd0aa79e Merge pull request #655 from turbo124/debian
Set home path for PHP when supervisor boots
2024-11-26 08:31:54 +11:00
David Bomba
d1786100ca Set home path for PHP when supervisor boots 2024-11-26 08:31:18 +11:00
David Bomba
f58ca724c9 Merge pull request #653 from turbo124/debian
Expose storage/ for nginx
2024-11-25 21:38:53 +11:00
David Bomba
53cadbf750 Expose storage/ for nginx 2024-11-25 21:38:26 +11:00
David Bomba
3fca330958 Merge pull request #651 from turbo124/debian
Updates for volume mounts
2024-11-25 11:39:13 +11:00
David Bomba
7d79b39bc2 Updates for volume mounts 2024-11-25 11:38:39 +11:00
David Bomba
aa271a1488 Merge pull request #650 from turbo124/debian
Add index.html to public/
2024-11-25 09:14:58 +11:00
David Bomba
451c1b872f Add index.html to public/ 2024-11-25 09:14:34 +11:00
David Bomba
5c74753da2 Merge pull request #648 from turbo124/debian
Updates for resolving filessystem
2024-11-24 19:58:47 +11:00
David Bomba
83f17aa669 Updates for resolving filessystem 2024-11-24 19:56:02 +11:00
David Bomba
394c4c8b5e Merge pull request #647 from turbo124/debian
Add storage link
2024-11-24 16:17:53 +11:00
David Bomba
9ed63a6762 add storage link 2024-11-24 15:48:15 +11:00
David Bomba
cb6d6d46c2 Merge pull request #646 from turbo124/debian
Adjustments for permissions
2024-11-24 11:51:49 +11:00
David Bomba
3b0e475de6 Adjustments for permissions 2024-11-24 11:50:13 +11:00
David Bomba
d5bb90fa04 Merge pull request #644 from turbo124/debian
Fixes for permissions on container init
2024-11-24 08:44:10 +11:00
David Bomba
1b62d86659 Fixes for permissions on container init 2024-11-24 08:43:50 +11:00
David Bomba
4431abcb88 Merge pull request #643 from turbo124/debian
Updates for permission handling in the container
2024-11-23 21:00:01 +11:00
David Bomba
d05e55a24e Updates for permission handling in the container 2024-11-23 20:58:56 +11:00
David Bomba
34e5043317 Merge pull request #642 from turbo124/debian
Fixes for tar command flags
2024-11-23 19:14:23 +11:00
David Bomba
6f92d1c155 Fixes for tar command flags 2024-11-23 19:13:59 +11:00
David Bomba
11330003a2 Merge pull request #641 from turbo124/debian
Updates for tar extraction
2024-11-23 19:01:32 +11:00
David Bomba
47b015af7c More explicity unpacking of .tar file 2024-11-23 19:00:45 +11:00
David Bomba
c6648a8511 Updates for tar extraction 2024-11-23 18:48:09 +11:00
David Bomba
de2036adff Merge pull request #640 from turbo124/debian
Fixes for tar command flags
2024-11-23 17:07:22 +11:00
David Bomba
ea8c5fed8e Fixes for tar command flags 2024-11-23 17:07:00 +11:00
David Bomba
c2f8cedc4a Merge pull request #639 from turbo124/debian
Enforce latest tags during build
2024-11-23 17:02:05 +11:00
David Bomba
7ddfe8a793 Enforce latest tags 2024-11-23 17:01:28 +11:00
David Bomba
196e66e06d updates for container 2024-11-23 16:57:44 +11:00
David Bomba
7498a94bd1 Merge pull request #638 from turbo124/debian
Update readme
2024-11-23 16:33:49 +11:00
David Bomba
8289c6c65e Update readme 2024-11-23 16:23:14 +11:00
David Bomba
b75ac4fd87 Update directory 2024-11-23 16:09:11 +11:00
David Bomba
94d3f6212e Merge pull request #636 from turbo124/debian
Update github action versions
2024-11-23 16:07:46 +11:00
David Bomba
a940bf2ed2 Update github action versions 2024-11-23 16:07:18 +11:00
25 changed files with 600 additions and 711 deletions

View File

@@ -1,24 +0,0 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.*]
charset = utf-8
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Matches the files *.yml
[*.yml]
indent_style = space
indent_size = 2

View File

@@ -1,38 +0,0 @@
name: Build Debian Container Image
on:
pull_request:
paths:
- "debian/**"
push:
paths:
- "debian/**"
branches:
- master
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Build
id: docker_build
uses: docker/build-push-action@v5
with:
context: debian
file: debian/Dockerfile
load: true
tags: invoiceninja/invoiceninja-debian:test
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -0,0 +1,48 @@
name: Build Octane Container Image
on:
pull_request:
paths:
- ".github/**"
- "octane/**"
push:
paths:
- ".github/**"
- "octane/**"
env:
REGISTRY_IMAGE: invoiceninja/invoiceninja-octane
jobs:
build:
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Build
id: build
uses: docker/build-push-action@v6
with:
context: octane
platforms: ${{ matrix.platform }}
tags: ${{ env.REGISTRY_IMAGE }}
outputs: type=image,push-by-digest=true,name-canonical=true
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -0,0 +1,166 @@
name: Publish Octane Container Images
on:
push:
tags-ignore:
- "invoiceninja-*"
env:
REGISTRY_IMAGE: invoiceninja/invoiceninja-octane
jobs:
version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
major: ${{ steps.version.outputs.major }}
minor: ${{ steps.version.outputs.minor }}
url: ${{ steps.version.outputs.url }}
steps:
- id: version
run: |
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
# Remove -o or -d suffix if present
VERSION=${VERSION%-*}
fi
MAJOR="$(echo "${VERSION}" | cut -d. -f1)"
MINOR="$(echo "${VERSION}" | cut -d. -f2)"
URL=https://github.com/invoiceninja/invoiceninja/releases/download/v${VERSION}/invoiceninja.tar.gz
# Debug output
echo "Current version: ${VERSION}"
echo "Version pattern check: $([[ $VERSION =~ ^5\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && echo "matches" || echo "doesn't match")"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "major=${MAJOR}" >> $GITHUB_OUTPUT
echo "minor=${MINOR}" >> $GITHUB_OUTPUT
echo "url=${URL}" >> $GITHUB_OUTPUT
build:
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
needs:
- version
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Prepare
id: prep
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: octane
build-args: URL=${{ needs.version.outputs.url }}
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ env.REGISTRY_IMAGE }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs:
- version
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
tags: |
${{ needs.version.outputs.version }}
${{ needs.version.outputs.major }}
${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}
latest
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
if: ${{ github.event_name != 'pull_request' }}
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
if: ${{ github.event_name != 'pull_request' }}
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
Description:
if: ${{ github.event_name != 'pull_request' }}
runs-on: ubuntu-latest
needs:
- merge
steps:
- name: Checkout
uses: actions/checkout@v5
with:
sparse-checkout: "README.md"
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: ${{ env.REGISTRY_IMAGE }}

View File

@@ -1,83 +0,0 @@
name: Publish Debian Container Images
on:
push:
tags-ignore:
- "invoiceninja-*"
jobs:
docker:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- image: invoiceninja/invoiceninja-debian
context: ./debian
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=${{ matrix.image }}
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
MAJOR="$(echo "${VERSION}" | cut -d. -f1)"
MINOR="$(echo "${VERSION}" | cut -d. -f2)"
TAGS="$TAGS,${DOCKER_IMAGE}:${MAJOR},${DOCKER_IMAGE}:${MAJOR}.${MINOR}"
if [[ $VERSION =~ ^5\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
TAGS="$TAGS,${DOCKER_IMAGE}:latest"
fi
echo ::set-output name=tags::${TAGS}
echo ::set-output name=version::${VERSION}
echo ::set-output name=major::${MAJOR}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-${{ matrix.image }}-buildx-${{ steps.prep.outputs.major }}-${{ hashFiles('**/cache_buster') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.image }}-buildx-${{ steps.prep.outputs.major }}-${{ hashFiles('**/cache_buster') }}-
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: ${{ matrix.context }}
build-args: INVOICENINJA_VERSION=${{ steps.prep.outputs.version }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0

View File

@@ -12,7 +12,7 @@ jobs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -55,7 +55,7 @@ jobs:
- "1.23.15"
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0

14
.gitignore vendored
View File

@@ -1,14 +0,0 @@
# OS files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Helm
charts/**/charts/
# Compose filesystem
/docker

View File

@@ -1,13 +1,13 @@
[![Docker Image Size](https://img.shields.io/docker/image-size/invoiceninja/invoiceninja-debian?label=debian)](https://hub.docker.com/r/invoiceninja/invoiceninja-debian)
[![Docker Pulls](https://img.shields.io/docker/pulls/invoiceninja/invoiceninja-debian)](https://hub.docker.com/r/invoiceninja/invoiceninja-debian)
[![Publish Status](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image.yaml)
[![Build Status](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-v5.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-v5.yaml)
[![Docker Image Size](https://img.shields.io/docker/image-size/invoiceninja/invoiceninja-octane?label=octane)](https://hub.docker.com/r/invoiceninja/invoiceninja-octane)
[![Docker Pulls](https://img.shields.io/docker/pulls/invoiceninja/invoiceninja-octane)](https://hub.docker.com/r/invoiceninja/invoiceninja-octane)
[![Publish Status](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image-octane.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image-octane.yaml)
[![Build Status](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-octane.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-octane.yaml)
# Debian Docker for [Invoice Ninja](https://www.invoiceninja.com/)
# Octane Docker for [Invoice Ninja](https://www.invoiceninja.com/)
:crown: **Features**
👑 **Features**
NGINX webserver support [NGINX](https://nginx.org/)
[FRANKENPHP](https://frankenphp.dev/)
Built-in Chrome for PDF generation and other features
Saxon XLST 2 engine
OPcache
@@ -18,8 +18,8 @@ Multi language support
This Debian-based image includes Chrome for enhanced PDF generation and other features. To get started:
```bash
git clone https://github.com/invoiceninja/dockerfiles.git -b debian
cd dockerfiles
git clone https://github.com/invoiceninja/dockerfiles.git -b octane
cd dockerfiles/octane
```
Instead of defining our environment variables inside our docker-compose.yml file we now define this in the `.env` file, open this file up and insert your `APP_URL`, `APP_KEY` and update the rest of the variables as required.
@@ -41,7 +41,9 @@ Prior to starting the container for the first time, open the .env file and updat
This will take care of the initial account setup. You can later remove these .env variables.
> ⚠️ **Warning**
> If `IN_USER_EMAIL` and `IN_PASSWORD` is not set the default user email and password is "admin@example.com" and "changeme!" respectively. You will use this for the initial login, thereafter, you can delete these two environment variables.
> If `IN_USER_EMAIL` and `IN_PASSWORD` are not set the default user email and password is "admin@example.com" and "changeme!" respectively.
After the container has completed the first startup you can delete these two environment variables.
### Generate a APP_KEY
@@ -49,10 +51,10 @@ The `APP_KEY` can be generated by running:
```bash
# If you haven't started the containers yet:
docker run --rm -it invoiceninja/invoiceninja-debian php artisan key:generate --show
docker run --rm -it invoiceninja/invoiceninja-octane frankenphp php-cli artisan key:generate --show
# Or if your containers are already running:
docker-compose exec app php artisan key:generate --show
docker compose exec app frankenphp php-cli artisan key:generate --show
```
Copy the entire string and insert in the .env file at `APP_KEY=base64....`
@@ -62,7 +64,7 @@ Copy the entire string and insert in the .env file at `APP_KEY=base64....`
Start the container with:
```bash
docker-compose up -d
docker compose up -d
```
**Note: When performing the setup, the Database host is ```mysql```
@@ -72,9 +74,8 @@ docker-compose up -d
To upgrade to a newer release image, update your docker-compose.yml first by running:
```bash
docker-compose down
docker-compose pull
docker-compose up
docker compose pull
docker compose up -d
```
It is recommended to perform a backup before updating.

179
debian/Dockerfile vendored
View File

@@ -1,179 +0,0 @@
FROM php:8.2-fpm AS base
ARG saxon=12.5.0
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
gosu \
default-mysql-client \
supervisor \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libatspi2.0-0 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libwayland-client0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
xdg-utils \
fonts-noto-cjk \
fonts-noto-cjk-extra \
fonts-wqy-microhei \
fonts-wqy-zenhei \
xfonts-wqy \
wget \
gnupg2 \
&& if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update \
&& apt-get install -y google-chrome-stable; \
fi \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set permissions for www-data to execute
RUN mkdir -p /var/www/.chrome/chrome-profile \
&& chown -R www-data:www-data /var/www/.chrome \
&& chmod -R 755 /var/www/.chrome \
&& if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
chown root:root /usr/bin/google-chrome \
&& chmod 4755 /usr/bin/google-chrome \
&& chown -R root:root /opt/google/chrome \
&& chmod -R 755 /opt/google/chrome; \
fi \
&& chown -R www-data:www-data /var/www
# Create required directories with proper permissions
RUN mkdir -p /tmp/chrome \
&& if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
chown -R www-data:www-data /tmp/chrome \
&& chmod -R 755 /tmp/chrome; \
fi
# Copy Install PHP extensions installer
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
# Install Required PHP extensions.
RUN install-php-extensions \
pdo_mysql \
mysqli \
mbstring \
exif \
pcntl \
bcmath \
gd \
opcache \
redis \
soap \
imagick \
curl \
gmp \
zip \
@composer
# Configure PHP
COPY php/php.ini /usr/local/etc/php/conf.d/app.ini
COPY php/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf
# Configure Saxon
WORKDIR /opt
RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
curl https://downloads.saxonica.com/SaxonC/HE/12/libsaxon-HEC-linux-x86_64-v${saxon}.zip --output saxon.zip \
&& unzip saxon.zip -d saxon \
&& cp saxon/libsaxon-HEC-linux-amd64-v${saxon}/libs/nix/libsaxon-hec-${saxon}.so /usr/lib/ \
&& cd /opt/saxon/libsaxon-HEC-linux-amd64-v${saxon}/Saxon.C.API \
&& phpize \
&& ./configure --enable-saxon \
&& make \
&& make install \
&& echo 'extension=saxon.so' > "/usr/local/etc/php/conf.d/app.ini"; \
fi
# Copy scripts
COPY rootfs /
# Set working directory
WORKDIR /var/www/html
# Download and extract application
RUN set -eux; \
DOWNLOAD_URL=$(curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | \
grep -o '"browser_download_url": "[^"]*invoiceninja.tar"' | cut -d '"' -f 4) && \
curl -L "$DOWNLOAD_URL" | tar -xvz -C /var/www/html && \
rm -rf /var/www/html/ui && \
chown -R www-data:www-data /var/www/html
# Install dependencies
RUN composer install --no-dev --no-scripts --no-autoloader
# Generate optimized autoloader and clear cache
RUN composer dump-autoload --optimize \
&& php artisan optimize \
&& php artisan view:cache \
&& php artisan config:cache \
&& php artisan route:cache
# Setup supervisor
COPY supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Add initialization script
COPY scripts/init.sh /usr/local/bin/init.sh
# Make executable
RUN chmod +x /usr/local/bin/init.sh
# Configure PHP-FPM
RUN sed -i "s/user = www-data/user = www-data/g" /usr/local/etc/php-fpm.d/www.conf \
&& sed -i "s/group = www-data/group = www-data/g" /usr/local/etc/php-fpm.d/www.conf
# Create volume directories
RUN mkdir -p \
/var/www/html/storage/app/public \
/var/www/html/storage/framework/cache \
/var/www/html/storage/framework/sessions \
/var/www/html/storage/framework/views \
/var/www/html/storage/logs \
/var/www/html/public/uploads \
/var/run \
/var/log/supervisor
# Set permissions
RUN chown -R www-data:www-data \
/var/www/html/storage \
/var/www/html/bootstrap/cache \
/var/www/html/public/uploads \
/var/run \
/var/log/supervisor \
&& chmod -R 775 \
/var/www/html/public/uploads \
/var/www/html/storage \
/var/www/html/bootstrap/cache \
/var/run \
/var/log/supervisor
# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD php -v || exit 1
EXPOSE 9000
ENTRYPOINT ["/usr/local/bin/init.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

View File

@@ -1,115 +0,0 @@
version: '3.8'
x-logging: &default-logging
options:
max-size: "10m"
max-file: "3"
driver: json-file
services:
app:
image: invoiceninja/invoiceninja-debian:5
restart: unless-stopped
env_file:
- ./.env
volumes:
- ./.env:/var/www/html/.env
- app_storage:/var/www/html/storage
- app_cache:/var/www/html/bootstrap/cache
- public_files:/var/www/html/public
networks:
- app-network
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
deploy:
resources:
limits:
memory: 512M
logging: *default-logging
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- type: volume
source: public_files
target: /var/www/html/public
read_only: true
networks:
- app-network
depends_on:
- app
deploy:
resources:
limits:
memory: 128M
logging: *default-logging
mysql:
image: mysql:8.0
restart: unless-stopped
env_file:
- ./.env
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
networks:
- app-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 1G
logging: *default-logging
redis:
image: redis:alpine
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- app-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 256M
logging: *default-logging
networks:
app-network:
driver: bridge
volumes:
app_storage:
driver: local
app_public:
driver: local
app_cache:
driver: local
mysql_data:
driver: local
redis_data:
driver: local
public_files:
driver: local

View File

@@ -1,38 +0,0 @@
server {
error_log /var/log/nginx/error.log debug;
access_log /var/log/nginx/access.log;
listen 80 default_server;
server_name _;
server_tokens off;
client_max_body_size 100M;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~* /storage/.*\.php$ {
return 503;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
}

View File

@@ -1,26 +0,0 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
sendfile on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf;
}

View File

@@ -1,9 +0,0 @@
[www]
user = www-data
group = www-data
listen = 0.0.0.0:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

21
debian/php/php.ini vendored
View File

@@ -1,21 +0,0 @@
session.auto_start = Off
short_open_tag = Off
error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED
opcache.enable=1
opcache.preload=/var/www/html/preload.php
opcache.preload_user=www-data
; ; The OPcache shared memory storage size.
opcache.max_accelerated_files=300000
opcache.validate_timestamps=1
opcache.revalidate_freq=30
opcache.jit_buffer_size=256M
opcache.jit=1205
opcache.memory_consumption=1024M
post_max_size = 60M
upload_max_filesize = 50M
memory_limit=512M

View File

@@ -1,14 +0,0 @@
#!/bin/sh
php artisan db:seed --force
# Build up array of arguments...
if [[ ! -z "${IN_USER_EMAIL}" ]]; then
email="--email ${IN_USER_EMAIL}"
fi
if [[ ! -z "${IN_PASSWORD}" ]]; then
password="--password ${IN_PASSWORD}"
fi
php artisan ninja:create-account $email $password

View File

@@ -1,73 +0,0 @@
#!/bin/sh
set -e
in_log() {
local type="$1"; shift
printf '%s [%s] [Entrypoint]: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$type" "$*"
}
docker_process_init_files() {
echo
local f
for f; do
case "$f" in
*.sh)
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
# https://github.com/docker-library/postgres/pull/452
if [ -x "$f" ]; then
in_log INFO "$0: running $f"
"$f"
else
in_log INFO "$0: sourcing $f"
. "$f"
fi
;;
*) in_log INFO "$0: ignoring $f" ;;
esac
echo
done
}
# Create directories if they don't exist
mkdir -p \
/var/www/html/storage/app/public \
/var/www/html/storage/framework/cache \
/var/www/html/storage/framework/sessions \
/var/www/html/storage/framework/views \
/var/www/html/storage/logs \
/var/www/html/public/uploads
# Set directory permissions without changing ownership
chmod -R 775 \
/var/www/html/storage \
/var/www/html/bootstrap/cache \
/var/www/html/public/uploads
# Clear and cache config in production
if [ "$APP_ENV" = "production" ]; then
php artisan config:cache
php artisan optimize
php artisan package:discover
php artisan migrate --force
echo "Checking initialization status..."
# If first IN run, it needs to be initialized
echo "Checking initialization status..."
IN_INIT=$(php artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();')
echo "IN_INIT value: $IN_INIT"
if [ "$IN_INIT" = "1" ]; then
echo "Running initialization scripts..."
docker_process_init_files /docker-entrypoint-init.d/*
fi
echo "Production setup completed"
echo "IN_INIT value: $IN_INIT"
fi
echo "Starting supervisord..."
# Start supervisord in the foreground
exec /usr/bin/supervisord -n -c /etc/supervisor/conf.d/supervisord.conf

View File

@@ -1,52 +0,0 @@
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[program:php-fpm]
command=/usr/local/sbin/php-fpm -F
autostart=true
autorestart=true
priority=5
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopwaitsecs=3600
[program:scheduler]
command=/bin/sh -c "while [ true ]; do (php /var/www/html/artisan schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1,5 +1,5 @@
# IN application vars
APP_URL=http://localhost:8012
APP_URL=http://localhost
APP_KEY=base64:RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno=
APP_ENV=production
APP_DEBUG=true
@@ -8,7 +8,16 @@ PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*'
QUEUE_CONNECTION=database
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
FILESYSTEM_DISK=debian_docker
# DB connection
DB_HOST=mysql
@@ -48,5 +57,6 @@ NORDIGEN_SECRET_KEY=
IS_DOCKER=true
SCOUT_DRIVER=null
SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome-stable
#SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome
#SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome-stable

102
octane/Dockerfile Normal file
View File

@@ -0,0 +1,102 @@
ARG PHP_VERSION=8.4
ARG FRANKENPHP_VERSION=1
ARG DEBIAN_VERSION=trixie
FROM dunglas/frankenphp:${FRANKENPHP_VERSION}-php${PHP_VERSION}-${DEBIAN_VERSION} AS prepare-app
ARG URL=https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar.gz
ADD ${URL} /tmp/invoiceninja.tar.gz
RUN tar -xf /tmp/invoiceninja.tar.gz \
&& ln -s ./resources/views/react/index.blade.php ./public/index.html \
# Symlink
&& php artisan storage:link \
# Octane
&& php artisan octane:install --server=frankenphp
# ==================
# InvoiceNinja image
# ==================
FROM dunglas/frankenphp:${FRANKENPHP_VERSION}-php${PHP_VERSION}-${DEBIAN_VERSION}
ARG user=ninja
# PHP modules
ARG php_require="bcmath gd mbstring pdo_mysql zip"
ARG php_suggest="exif imagick intl pcntl saxon soap"
ARG php_extra="opcache"
# Create a system user UID/GID=999
RUN useradd -r ${user}
# Allow to bind to privileged ports
RUN setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
mariadb-client \
gpg \
# Unicode support for PDF
fonts-noto-cjk-extra \
fonts-wqy-microhei \
fonts-wqy-zenhei \
xfonts-wqy \
# Install google-chrome-stable(amd64)/chromium(arm64)
&& if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | \
gpg --dearmor -o /etc/apt/keyrings/google.gpg \
&& echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google.gpg] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends google-chrome-stable \
&& mkdir /config/google-chrome \
&& chown ${user}: /config/google-chrome; \
elif [ "$(dpkg --print-architecture)" = "arm64" ]; then \
apt-get install -y --no-install-recommends \
chromium \
&& mkdir /config/chromium \
&& chown ${user}: /config/chromium; \
fi \
# Cleanup
&& apt-get purge -y gpg \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN install-php-extensions \
${php_require} \
${php_suggest} \
${php_extra}
# Configure PHP
RUN ln -s "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini"
COPY php/php.ini /usr/local/etc/php/conf.d/invoiceninja.ini
# Workaround: Disable SSL for mariadb-client for compatibility with MySQL
RUN echo "skip-ssl = true" >> /etc/mysql/mariadb.conf.d/50-client.cnf
# Create directory for artisan tinker (init.sh)
RUN mkdir /config/psysh \
&& chown ${user}: /config/psysh
# Change owner for caddy directories
RUN chown -R ${user}: \
/data/caddy \
/config/caddy
# InvoiceNinja
COPY --from=prepare-app --chown=${user}:${user} /app /app
# Add initialization script
COPY --chmod=0755 scripts/init.sh /usr/local/bin/init.sh
USER ${user}
HEALTHCHECK --start-period=100s CMD curl -f http://localhost/health
ENTRYPOINT ["/usr/local/bin/init.sh"]
CMD ["frankenphp", "php-cli", "artisan", "octane:frankenphp"]

129
octane/docker-compose.yml Normal file
View File

@@ -0,0 +1,129 @@
# name: invoiceninja
x-app-volumes: &volumes
volumes:
- app_storage:/app/storage
- caddy_data:/data
services:
app:
build:
context: .
image: invoiceninja/invoiceninja-octane:${TAG:-latest}
restart: unless-stopped
# php artisan help octane:frankenphp
command: --port=80 --workers=2
# command: --host=example.com --port=443 --workers=2 --https --http-redirect --log-level=info
ports:
- "80:80" # HTTP
# - "443:443" # HTTPS
# - "443:443/udp" # HTTP/3, Works for chromium based browser, but causes H3_GENERAL_PROTOCOL_ERROR for pdf previews in Firefox
env_file:
- ./.env
environment:
LARAVEL_ROLE: app
<<: *volumes
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
# mariadb:
# condition: service_healthy
# valkey:
# condition: service_healthy
app-worker:
image: invoiceninja/invoiceninja-octane:${TAG:-latest}
restart: unless-stopped
# php artisan help queue:work
command: --verbose --sleep=3 --tries=3 --max-time=3600
deploy:
mode: replicated
replicas: 2
env_file:
- ./.env
environment:
LARAVEL_ROLE: worker
<<: *volumes
healthcheck:
test: ["CMD", "pgrep", "-f", "queue:work"]
depends_on:
app:
condition: service_healthy
app-scheduler:
image: invoiceninja/invoiceninja-octane:${TAG:-latest}
restart: unless-stopped
# php artisan help schedule:work
command: --verbose
env_file:
- ./.env
environment:
LARAVEL_ROLE: scheduler
<<: *volumes
healthcheck:
test: ["CMD", "pgrep", "-f", "schedule:work"]
depends_on:
app:
condition: service_healthy
mysql:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"localhost",
"-u${MYSQL_USER}",
"-p${MYSQL_PASSWORD}",
]
redis:
image: redis:alpine
restart: unless-stopped
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
# mariadb:
# image: mariadb:11.8
# restart: unless-stopped
# environment:
# MARIADB_DATABASE: ${DB_DATABASE}
# MARIADB_USER: ${DB_USERNAME}
# MARIADB_PASSWORD: ${DB_PASSWORD}
# MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
# volumes:
# - mariadb:/var/lib/mysql
# healthcheck:
# test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
# valkey:
# image: valkey/valkey:8
# restart: unless-stopped
# volumes:
# - valkey:/data
# healthcheck:
# test: [ "CMD", "valkey-cli", "ping" ]
volumes:
app_storage:
caddy_data:
mysql_data:
redis_data:
# mariadb:
# valkey:

24
octane/php/php.ini Normal file
View File

@@ -0,0 +1,24 @@
[core]
; https://www.php.net/manual/en/ini.core.php
post_max_size=10M
upload_max_filesize=10M
memory_limit=512M
[opcache]
; https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended
opcache.enable_cli=1
[jit]
; https://wiki.php.net/rfc/jit_config_defaults
opcache.jit=tracing
opcache.jit_buffer_size=64M
[extra]
; https://frankenphp.dev/docs/performance/#php-performance
; http://symfony.com/doc/current/performance.html
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.preload=/app/preload.php
opcache.validate_timestamps=0
realpath_cache_size = 4096K
realpath_cache_ttl = 600

97
octane/scripts/init.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/bin/sh -eu
# Fallback to app
role=${LARAVEL_ROLE:-app}
# Set PDF generation browser path based on architecture
export SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome-stable
if [ "$(dpkg --print-architecture)" = "arm64" ]; then
export SNAPPDF_CHROMIUM_PATH=/usr/bin/chromium
fi
# Check for default CMD, flag(s) or empty CMD
if [ "$*" = 'frankenphp php-cli artisan octane:frankenphp' ] || [ "${1#-}" != "$1" ] || [ "$#" -eq "0" ]; then
if [ "--help" = "$1" ]; then
echo [CMD]
echo "This image will execute specific CMDs based on the environment variable LARAVEL_ROLE"
echo
echo "LARAVEL_ROLE=app: frankenphp php-cli artisan octane:frankenphp (default)"
echo "LARAVEL_ROLE=worker: frankenphp php-cli artisan queue:work"
echo "LARAVEL_ROLE=scheduler: frankenphp php-cli artisan schedule:work"
echo
echo [FLAGS]
echo To the CMD defined by LARAVEL_ROLE can be extended with flags for artisan commands
echo
echo Available flags can be displaced:
echo docker run --rm invoiceninja/invoiceninja-debian frankenphp php-cli artisan help octane:frankenphp
echo docker run --rm invoiceninja/invoiceninja-debian frankenphp php-cli artisan queue:work
echo docker run --rm invoiceninja/invoiceninja-debian frankenphp php-cli artisan schedule:work
echo
echo Example:
echo docker run -e LARAVEL_ROLE=worker invoiceninja/invoiceninja-debian --verbose --sleep=3 --tries=3 --max-time=3600
echo
echo [Deployment]
echo Docker compose is recommended
echo
echo Example:
echo https://github.com/invoiceninja/dockerfiles/blob/octane/debian/docker-compose.yml
echo
exit 0
fi
# Run app
if [ "${role}" = "app" ]; then
cmd="frankenphp php-cli artisan octane:frankenphp"
# Check for required folders and create if needed, relevant for bind mounts
# It is not possible to chown, as we are not executing this script as root
[ -d /var/www/html/storage/app/public ] || mkdir -p /var/www/html/storage/app/public
[ -d /app/storage/framework/sessions ] || mkdir -p /app/storage/framework/sessions
[ -d /app/storage/framework/views ] || mkdir -p /app/storage/framework/views
[ -d /app/storage/framework/cache ] || mkdir -p /app/storage/framework/cache
[ -d /app/storage/logs ] || mkdir -p /app/storage/logs
if [ "$APP_ENV" = "production" ]; then
frankenphp php-cli artisan migrate --force
frankenphp php-cli artisan cache:clear # Clear after the migration
frankenphp php-cli artisan ninja:design-update
frankenphp php-cli artisan optimize
# If first IN run, it needs to be initialized
if [ "$(frankenphp php-cli artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();')" = "1" ]; then
echo "Running initialization..."
frankenphp php-cli artisan db:seed --force
if [ -n "${IN_USER_EMAIL}" ] && [ -n "${IN_PASSWORD}" ]; then
frankenphp php-cli artisan ninja:create-account --email "${IN_USER_EMAIL}" --password "${IN_PASSWORD}"
else
echo "Initialization failed - Set IN_USER_EMAIL and IN_PASSWORD in .env"
exit 1
fi
fi
fi
echo "Production setup completed"
# Run worker
elif [ "${role}" = "worker" ]; then
cmd="frankenphp php-cli artisan queue:work"
# Run scheduler
elif [ "${role}" = "scheduler" ]; then
cmd="frankenphp php-cli artisan schedule:work"
# Invalid role
else
echo "Invalid role: ${role}"
exit 1
fi
# Append flag(s) to role cmd
if [ "${1#-}" != "$1" ]; then
set -- ${cmd} "$@"
else
set -- ${cmd}
fi
fi
exec "$@"