InvoiceNinja v5 on Raspberry Pi 4 (ARMv7)
There have been other mentions about IN on RPi, for example: #108 I am still unable to get it to work. When I change the mysql image as mentioned in #108 I get the following error:
standard_init_linux.go:211: exec user process caused "exec format error"
And when I try to build the Dockerfile_5 I get:
URL: https://download.cypress.io/desktop/4.6.0?platform=linux&arch=ia32
Error: Failed downloading the Cypress binary.
Response code: 404
Response message: Not Found
----------
Platform: linux (Alpine Linux - 3.11.6)
Cypress Version: 4.6.0
[...]
The command '/bin/sh -c npm install' returned a non-zero code: 1
Anyone able to run IN v5 on a RPi 4? If so, please provide some instructions on how to make it work.
Any progress with this? Currently I am getting
standard_init_linux.go:219: exec user process caused: exec format error
"Error: Failed downloading the Cypress binary." cypress doesn't run on a raspberry pi because it is not available for arm
Any progress on getting Invoice Ninja to run in docker on Raspberry Pi 4?
I would also be interested in running Invoice Ninja in docker on RPi4.
Anyone interested in testing an ARM64 image? Build passed but Iβm not even sure whether it will work.
Hello,
It is very possible to have invoiceninja running on a Raspberry Pi 4, as I currently have π
ARM64, ARMv8, aarch64
First it is perhaps important to specify that the Raspberry Pi 4 has an ARM v8 based Cortex-A72 processor as is stated on the official raspberrypi.org page, this is also the case for the Raspberry Pi 3 Model B, B+ and in later models of the Raspberry Pi 2 which are Cortex-A53 based (see here). Consequently, all of those models should be usable for what is described hereunder, although I personally only tested this on a Raspberry Pi 4 B. The terms ARM 64, ARM v8 and aarch64 are used interchangeably to describe this processor architecture.
Re-building the docker image
It is necessary to re-build the invoiceninja (app) docker image on the Raspberry Pi itself because, during the build process, alpine will collect and compile packages for aarch64. Here is an extract of the build logs that explicitly shows that:
Step 8/38 : RUN set -eux; apk add --no-cache curl
---> Running in 4014925938eb
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/aarch64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/aarch64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20191127-r2)
(2/4) Installing nghttp2-libs (1.40.0-r1)
(3/4) Installing libcurl (7.67.0-r3)
(4/4) Installing curl (7.67.0-r3)
...
Also the PHP extensions install process will extract and compile for the targeted architecture:
### INSTALLING BUNDLED MODULE bcmath ###
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/aarch64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/aarch64/APKINDEX.tar.gz
(1/1) Installing .phpize-deps (20210325.115001)
OK: 335 MiB in 115 packages
...
checking build system type... aarch64-unknown-linux-musl
checking host system type... aarch64-unknown-linux-musl
checking target system type... aarch64-unknown-linux-musl
...
checking for ld used by cc... /usr/aarch64-alpine-linux-musl/bin/ld
checking if the linker (/usr/aarch64-alpine-linux-musl/bin/ld) is GNU ld... yes
checking for /usr/aarch64-alpine-linux-musl/bin/ld option to reload object files... -r
...
checking whether the cc linker (/usr/aarch64-alpine-linux-musl/bin/ld) supports shared libraries... yes
...
Re-building the docker image is quite easy, simply clone the invoiceninja/dockerfiles repo to your RasPi and docker build from the repo's root directory.
docker build command
$ sudo apt update
$ sudo apt install git
$ cd ~/home/pi/docker
$ git clone [email protected]:invoiceninja/dockerfiles
$ cd dockerfiles
$ docker build \
-f alpine/Dockerfile_v5 \
--build-arg INVOICENINJA_VERSION=5.1.31 \
-t ininja-aarch64:5.1.31 . \
2>&1 | tee dockerbuild.log
The last line 2>&1 | tee dockerbuild.log stores the install logs to a file while still displaying the output to stdout and is not mandatory of course.
On my Raspberry Pi 4 (8G), the build process took about 32 minutes (YMMV)...
Modifying docker-compose.yml
The included docker-compose.yml file uses the mysql:5 docker image for the db container, although it is not reported as AMD 64 compatible on hub.docker.com and thus it won't run on a RasPi (I tried that π ).
Nevertheless, as MariaDB is the official mysql compatible open-source alternative, and its image is reported as ARM 64 compatible on hub.docker.com, we can substitute it to the mysql:5 image used by default.
mysql:5 is indeed v5.7.33, and as stated in the MariaDB compatibility page, MariaDB 10.4 function as limited drop-in replacements for MySQL 5.7, as far as InnoDB is concerned. Thus we will use the mariadb:10.4 image.
Substitute images used in the docker-compose.yml file
Since we have our locally built ininja-aarch64:5.1.31 docker image, we only have to substitute the images used for the app and db containers:
$ cd ~/home/pi/docker/dockerfiles
$ nano -l docker-compose.yml
...
app:
image: ininja-aarch64:5.1.31
...
db:
image: mariadb:10.4
Running invoiceninja using docker on the Raspberry Pi
Set suitable values in your env file, based on the example given in the invoiceninja/invoiceninja project.
Possibly adapt the values for MYSQL_USER, MYSQL_PASSWORD and MYSQL_DATABASE in the docker-compose.yml file and launch the containers from the cloned repo's root with the docker-compose up -d command...
You should now be able to access your InvoiceNinja installation running on docker ππ½
Hope this will allow people owning a Raspberry 4 to easily run their own instance of this great software on this very nice (and cheap) little computer π
@tacticz
Thank you so much for this detailed post!!!
My pleasure!
@tacticz the next docker release to invoiceninja/invoiceninja:5.1.x would feature an ARM64 build, would you like to help test it out?
@lwj5 certainly, I'll be glad to help!
Any plans to develop a version for ARMv7? Most Raspberries run on 32bit Raspberry Pi OS.
@vsisl not possible unless alpine packages chromium for ARMv7, which they havenβt done since 3.11.
https://pkgs.alpinelinux.org/packages?name=chromium&branch=v3.13
You can rebuild the image using an older php image based on alpine 3.11.
This belongs in #108
I'm no expert coder, and I've only hired a coder once, so please bear with me lol. I'd be willing to hire someone to help fix this if needed. #https://github.com/invoiceninja/invoiceninja/issues/5386 was is my first attempt at hiring help for my Feature Requests. I'm not trying to rush anything thru, just trying to get a few new features to the point it can be reviewed and merged at earliest convenience, to help myself and in turn help others by making some things more useful. We're restructuring some of our business tools currently and getting this running on Pi 4 ARMv7 would be extremely helpful as we're trying to go with running as much open source as possible. Ideally running in a docker container to stack on a already running Pi 4, but even getting it running on a dedicated Pi 4 would be fine with me. Just let me know if I should look for one outside here, or even one of you are interested I would just need a platform to fund and pay you thru, like Fiverr Pro or whatever.
@lwj5
Is chromium the only blocking issue? If so we can adjust so that snappdf downloads its binary?
@turbo124 yes it is. The issue is there's no binary for it, which means snappdf cannot download it as well.
See this for the snappdf supported platforms.
https://github.com/beganovich/snappdf/blob/e3657deb39810a82ae9e192cab76b55562539ee1/src/Command/DownloadChromiumCommand.php#L120
Someone can build it from the source and contribute to the alpine packages.
Otherwise, I think Debian buster contains it, which means in addition to alpine, build this docker image on Debian as well. Ref: https://packages.debian.org/buster/chromium
@beganovich thoughts on compiling for ARMv7 ?
@lwj5 I really like how slim the Alpine builds are, not sure what size the image would look like with Debian, but I know that the Ubuntu image is huge by comparison.
Alpine 6MB (3MB) vs Debian-slim 70MB (25MB) (compressed). But the layers can be shared if there are other Debian images on that machine thus I feel it's not something to worry about. MySQL is built on Debian-slim, so if you are running IN on the same machine it does not take up extra space :)
Anyway, it's possible to build both. I do not have the bandwidth to do this so someone needs to help contribute.
Snappdf is able to use any binary thru any architecture you provide it. The file that @lwj5 sent is only for downloader.
So if I follow correctly, we want Chromium for armv7 @ alpine? Does this help? Can we somehow get a building recipe for this? https://pkgs.alpinelinux.org/package/v3.11/community/armv7/chromium
Otherwise, we can all save ourselves troubles and just ship the slim version of Debian, which already has chromium in its repos, right?
@beganovich correct, so the least friction here would be to get a debian slim build running also.
To make our lives easier, I vote for Debian Slim.
cypress runs the tests through chromium, right? so basically invoiceninja itself should run just fine on armv7. conclusion: if you don't need E2E testing capabilities on raspberry platform i 'd suggest to disable cypress
any updates on getting InvoiceNinja on Armv7 Raspberry ?
@KevoM we really need help for this one, we don't have the internal knowledge for this.
Well... see above.
i set up invoice ninja on docker and there were no issues in the logs. The only issue i have is how to access it. I have set up nginx manually before and left that part out in my docker-compose.yml file. Though i used the given in the git repo example and cloned the repository. (then i copied my docker-compose.yml file into the dockerfiles folder) i changed the env file too. The APP_URL is my omv local domain. I thought when i add a port at the end of the url or add a port in the docker-compose.yml like: port: ...:80 i will reach my self hosted invoice ninja app via: http://local.domain:...
this isn't the case. Any help on this? Sorry for my probably stupid question.
Best Regards
`docker-compose.yml:
version: '3.7'
services: app: image: invoiceninja/invoiceninja:5 env_file: env ports: - 8003:80 restart: always volumes: - ./config/hosts:/etc/hosts:ro - ./docker/app/public:/var/www/app/public:rw,delegated - ./docker/app/storage:/var/www/app/storage:rw,delegated depends_on: - db networks: - invoiceninja extra_hosts: - "in5.test:192.168.178.64" #host and ip
db: image: mariadb:10.4
For auto DB backups comment out image and use the build block below
build:
context: ./config/mysql
ports:
- "3305:3306"
restart: always
env_file: env
volumes:
- ./docker/mysql/data:/var/lib/mysql:rw,delegated
networks:
- invoiceninja
extra_hosts:
- "in5.test:192.168.178.64" #host and ip
networks: invoiceninja:
the pwd are only for testing purposes
env file:
IN application vars
APP_URL=http://omv.local APP_KEY=base64:fhs3aA3JIzB+A1RMXaoYheSwxle2pdDLH1271I/AOCY= APP_DEBUG=true REQUIRE_HTTPS=false PHANTOMJS_PDF_GENERATION=false PDF_GENERATOR=snappdf
QUEUE_CONNECTION=database
DB connection
DB_HOST=db DB_PORT=3306 DB_DATABASE=ninja DB_USERNAME=ninja DB_PASSWORD=ninja
Create initial user
Default to these values if empty
[email protected]
IN_PASSWORD=changeme!
[email protected] IN_PASSWORD=sth
Mail options
MAIL_MAILER=log MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS='[email protected]' MAIL_FROM_NAME='Self Hosted User'
MySQL
MYSQL_ROOT_PASSWORD=ninjaAdm1nPassword MYSQL_USER=ninja MYSQL_PASSWORD=ninja MYSQL_DATABASE=ninja