Compare commits

...

17 Commits

Author SHA1 Message Date
David Bomba
ff3b7263f5 Merge pull request #825 from turbo124/master
Force cache:clear on first boot
2025-10-28 06:28:11 +11:00
David Bomba
ba896fcc03 Force cache:clear on first boot 2025-10-28 06:26:49 +11:00
David Bomba
b53ed7c914 Merge pull request #749 from turbo124/master
Add deprecation notice for master branch
2025-04-25 08:23:55 +10:00
David Bomba
e3fd4afb7d Add deprecation notice for master branch 2025-04-25 08:23:28 +10:00
David Bomba
afceccfaf6 Merge pull request #734 from benbrummer/master
github latest url, tar.gz, alpine 3.20
2025-03-19 10:05:22 +11:00
Benjamin Brummer
320cdc961d github latest url, tar.gz, alpine 3.20 2025-03-18 07:25:21 +00:00
David Bomba
7e466b38a3 Merge pull request #715 from invoiceninja/revert-689-master
Revert "Align alpine to debian and octane for maintenance"
2025-01-26 09:47:59 +11:00
David Bomba
c5bb7960c3 Revert "Align alpine to debian and octane for maintenance" 2025-01-26 09:47:24 +11:00
David Bomba
3bf4174cbf Merge pull request #712 from turbo124/master
Fixes for publish-image regression
2025-01-24 15:40:41 +11:00
David Bomba
18550bcf3e Fixes for publish-image regression 2025-01-24 15:40:26 +11:00
David Bomba
83bfb1b22f Fixes for publish-image regression 2025-01-24 15:38:25 +11:00
David Bomba
e4b3e0f0f1 Merge pull request #711 from turbo124/master
Revert and run on ubuntu 22.04
2025-01-24 15:01:20 +11:00
David Bomba
a060c70d3f Revert and run on ubuntu 22.04 2025-01-24 15:01:08 +11:00
David Bomba
d8749fa049 Revert and run on ubuntu 22.04 2025-01-24 14:59:52 +11:00
David Bomba
febb70263c Merge pull request #710 from turbo124/master
align build and publish images
2025-01-24 14:49:21 +11:00
David Bomba
4b6b287906 align build and publish images 2025-01-24 14:48:52 +11:00
David Bomba
e0bb394346 minor changes 2025-01-24 14:32:47 +11:00
18 changed files with 179 additions and 180 deletions

View File

@@ -16,7 +16,7 @@ on:
jobs:
docker:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v2
@@ -53,6 +53,5 @@ jobs:
- name: Move cache
run: |
mkdir -p /tmp/.buildx-cache
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

View File

@@ -11,7 +11,7 @@ on:
jobs:
docker:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v2
@@ -31,9 +31,9 @@ jobs:
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}
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "major=${MAJOR}" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -48,9 +48,9 @@ jobs:
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ steps.prep.outputs.major }}-${{ hashFiles('alpine/${{ steps.prep.outputs.major }}/cache_buster') }}-${{ github.sha }}
key: ${{ runner.os }}-buildx-5-${{ hashFiles('alpine/5/cache_buster') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ steps.prep.outputs.major }}-${{ hashFiles('alpine/${{ steps.prep.outputs.major }}/cache_buster') }}-
${{ runner.os }}-buildx-5-${{ hashFiles('alpine/5/cache_buster') }}-
- name: Login to DockerHub
if: github.event_name != 'pull_request'
@@ -79,4 +79,4 @@ jobs:
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@@ -1,10 +1,15 @@
![Docker images](https://github.com/invoiceninja/dockerfiles/workflows/Docker%20images/badge.svg)
[![Docker image, latest](https://img.shields.io/docker/image-size/invoiceninja/invoiceninja/latest?label=latest)](https://hub.docker.com/r/invoiceninja/invoiceninja)
[![Docker image, alpine](https://img.shields.io/docker/image-size/invoiceninja/invoiceninja/alpine?label=alpine)](https://hub.docker.com/r/invoiceninja/invoiceninja)
[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/invoiceninja)](https://artifacthub.io/packages/search?repo=invoiceninja)
[![Publish Image](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/publish-image.yaml)
[![Cache v5 Image](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-v5.yaml/badge.svg)](https://github.com/invoiceninja/dockerfiles/actions/workflows/build-image-v5.yaml)
# Deprecation Notice
The master branch is not longer receiving active updates. We will continue to tag new releases whilst compatibility with underlying packages remains, however we will not be updating this image going forward.
Instead, please use the debian branch [here](https://github.com/invoiceninja/dockerfiles/tree/debian) this image is a completely fresh start based on the debian image and allows improved package support.
# Docker for [Invoice Ninja](https://www.invoiceninja.com/)
:crown: **Features**

View File

@@ -1,67 +1,63 @@
ARG PHP_VERSION=8.3
ARG ALPINE_VERSION=3.20
ARG PHP_VERSION=8.2
ARG BAK_STORAGE_PATH=/var/www/app/docker-backup-storage/
ARG BAK_PUBLIC_PATH=/var/www/app/docker-backup-public/
# Get Invoice Ninja and install nodejs packages
FROM --platform=$BUILDPLATFORM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS nodebuild
FROM --platform=$BUILDPLATFORM node:lts-alpine${ALPINE_VERSION} as nodebuild
# Download Invoice Ninja
ARG INVOICENINJA_VERSION
ARG REPOSITORY=invoiceninja/invoiceninja
ARG FILENAME=invoiceninja.tar
ARG FILENAME=invoiceninja.tar.gz
RUN mkdir -p /var/www/app
RUN set -eux; apk add curl unzip grep
# Extract Invoice Ninja
RUN apk add --no-cache curl \
&& curl -s "https://api.github.com/repos/invoiceninja/invoiceninja/releases/latest" | \
grep -o '"browser_download_url": "[^"]*invoiceninja.tar.gz"' | \
cut -d '"' -f 4 | \
xargs curl -sL | \
tar -xz --strip-components=1 -C /var/www/app/ \
&& apk --purge del curl
RUN mkdir -p /var/www/app
RUN curl -sL "https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar.gz" | \
tar -xz -C /var/www/app/
RUN mkdir -p /var/www/app/public/logo /var/www/app/storage
WORKDIR /var/www/app
# Prepare php image
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS phpbuild
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} as phpbuild
LABEL maintainer="David Bomba <turbo124@gmail.com>"
ARG php_require="bcmath gd pdo_mysql zip mbstring"
ARG php_suggest="exif imagick intl pcntl soap"
ARG php_extra="opcache"
# Adding caching_sha2_password.so
# With this we get native support for caching_sha2_password
RUN apk add --no-cache mariadb-connector-c
RUN ln -s "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini"
RUN mv /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
# Install PHP extensions
# https://hub.docker.com/r/mlocati/php-extension-installer/tags
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
# Install chromium
RUN set -eux; \
apk add --no-cache \
font-isas-misc \
supervisor \
mariadb-client \
mariadb-connector-c \
mysql-client \
chromium \
# font-noto-cjk-extra \
# font-wqy-zenhei \
ttf-freefont \
ttf-dejavu
COPY --from=ghcr.io/mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
RUN install-php-extensions \
${php_require} \
${php_suggest} \
${php_extra}
# Install PHP extensions
# RUN ( curl -sSLf https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - || echo 'return 1' ) | sh -s \
# ${php_require} \
# ${php_suggest} \
# ${php_extra}
bcmath \
exif \
gd \
gmp \
mysqli \
opcache \
pdo_mysql \
zip \
intl \
@composer \
&& rm /usr/local/bin/install-php-extensions
# Copy files
COPY rootfs /
@@ -89,6 +85,8 @@ ENV BAK_STORAGE_PATH $BAK_STORAGE_PATH
ENV BAK_PUBLIC_PATH $BAK_PUBLIC_PATH
COPY --from=nodebuild --chown=$INVOICENINJA_USER:$INVOICENINJA_USER /var/www/app /var/www/app
RUN rm -rf /var/www/app/ui
USER $UID
WORKDIR /var/www/app
@@ -106,7 +104,7 @@ ARG BAK_PUBLIC_PATH
RUN mv /var/www/app/storage $BAK_STORAGE_PATH \
&& mv /var/www/app/public $BAK_PUBLIC_PATH
FROM phpbuild AS prod
FROM phpbuild as prod
COPY --from=dependencybuild --chown=$INVOICENINJA_USER:$INVOICENINJA_USER /var/www/app /var/www/app

View File

@@ -1,6 +1,7 @@
#!/bin/sh
php artisan db:seed --force
php artisan cache:clear
# Build up array of arguments...
if [[ ! -z "${IN_USER_EMAIL}" ]]; then

View File

@@ -1,36 +1,37 @@
[supervisord]
nodaemon=true
logfile=/dev/null
pidfile=/tmp/supervisord.pid
logfile=/dev/null ; nodaemon will cause logs to go to stdout
logfile_maxbytes=0
[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
loglevel=info
[program:php-fpm]
command=php-fpm
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php-fpm
[program:scheduler]
command=php artisan schedule:work
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php artisan schedule:work
[program:queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php artisan queue:work --sleep=3 --tries=1 --timeout=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=2
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
stopwaitsecs=3600
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
numprocs=2
command=php artisan queue:work --sleep=3 --tries=1 --memory=256 --timeout=3600
[eventlistener:shutdown]
command=shutdown.sh

View File

@@ -30,7 +30,7 @@ php artisan optimize
php artisan package:discover
# Check if DB works, if not crash the app.
DB_READY=$(php -d opcache.preload='' artisan tinker --execute='echo app()->call("App\Utils\SystemHealth@dbCheck")["success"];')
DB_READY=$(php artisan tinker --execute='echo app()->call("App\Utils\SystemHealth@dbCheck")["success"];')
if [ "$DB_READY" != "1" ]; then
php artisan migrate:status # Print verbose error
in_error "Error connecting to DB"
@@ -39,7 +39,7 @@ fi
php artisan migrate --force
# If first IN run, it needs to be initialized
IN_INIT=$(php -d opcache.preload='' artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();')
IN_INIT=$(php artisan tinker --execute='echo Schema::hasTable("accounts") && !App\Models\Account::all()->first();')
if [ "$IN_INIT" == "1" ]; then
docker_process_init_files /docker-entrypoint-init.d/*
fi

View File

@@ -1 +0,0 @@
pm.max_children = 10

View File

@@ -0,0 +1,17 @@
; How often (in seconds) to check file timestamps for changes to the shared
; memory storage allocation. ("1" means validate once per second, but only
; once per request. "0" means always validate)
;opcache.revalidate_freq=2
opcache.revalidate_freq=60
# http://symfony.com/doc/current/performance.html
; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
;realpath_cache_ttl = 120
realpath_cache_ttl = 600
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 8M

View File

@@ -1,22 +0,0 @@
[core]
; https://www.php.net/manual/en/ini.core.php
post_max_size=10M
upload_max_filesize=10M
[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]
; http://symfony.com/doc/current/performance.html
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.preload=/var/www/app/preload.php
opcache.validate_timestamps=0
realpath_cache_size=4096K
realpath_cache_ttl=600

View File

@@ -0,0 +1,34 @@
server {
listen 80 default_server;
server_name _;
server_tokens off;
client_max_body_size 100M;
root /var/www/app/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,14 +0,0 @@
# https://nginx.org/en/docs/http/ngx_http_core_module.html
client_max_body_size 10M;
client_body_buffer_size 10M;
server_tokens off;
# https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
fastcgi_buffers 32 16K;
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
gzip on;
gzip_comp_level 2;
gzip_min_length 1M;
gzip_proxied any;
gzip_types *;

View File

@@ -1,32 +0,0 @@
# https://laravel.com/docs/master/deployment#nginx
server {
listen 80 default_server;
server_name _;
root /var/www/app/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
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; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}

18
config/php/php-cli.ini Normal file
View File

@@ -0,0 +1,18 @@
session.auto_start = Off
short_open_tag = Off
error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED
; opcache.enable_cli=1
; opcache.fast_shutdown=1
; opcache.memory_consumption=256
; opcache.interned_strings_buffer=8
; opcache.max_accelerated_files=4000
; opcache.revalidate_freq=60
; # http://symfony.com/doc/current/performance.html
; realpath_cache_size = 4096K
; realpath_cache_ttl = 600
memory_limit = 2G
post_max_size = 60M
upload_max_filesize = 50M

View File

@@ -1 +0,0 @@
pm.max_children = 10

View File

@@ -1,22 +1,21 @@
[core]
; https://www.php.net/manual/en/ini.core.php
post_max_size=10M
upload_max_filesize=10M
session.auto_start = Off
short_open_tag = Off
[opcache]
; https://www.php.net/manual/en/opcache.installation.php#opcache.installation.recommended
opcache.enable_cli=1
error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED
[jit]
; https://wiki.php.net/rfc/jit_config_defaults
opcache.jit=tracing
opcache.jit_buffer_size=64M
; opcache.enable=1
; opcache.preload=/var/www/app/preload.php
; opcache.preload_user=www-data
[extra]
; http://symfony.com/doc/current/performance.html
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.preload=/var/www/app/preload.php
opcache.validate_timestamps=0
realpath_cache_size=4096K
realpath_cache_ttl=600
; ; 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,12 +1,14 @@
version: '3.7'
services:
nginx:
server:
image: nginx
restart: always
env_file: env
volumes:
# Vhost configuration
#- ./config/caddy/Caddyfile:/etc/caddy/Caddyfiledocker-com
- ./config/nginx:/etc/nginx/conf.d:ro
- ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
- ./docker/app/public:/var/www/app/public:ro
depends_on:
- app
@@ -15,27 +17,28 @@ services:
ports:
- "80:80"
#- "443:443"
# extra_hosts:
# - "in5.localhost:192.168.0.124 " #host and ip
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
app:
build:
context: ./alpine/5
image: invoiceninja/invoiceninja:${TAG:-5}
image: invoiceninja/invoiceninja:5
env_file: env
restart: always
volumes:
# - ./config/hosts:/etc/hosts:ro
- ./config/hosts:/etc/hosts:ro
- ./docker/app/public:/var/www/app/public:rw,delegated
- ./docker/app/storage:/var/www/app/storage:rw,delegated
# - ./config/php/php.ini:/usr/local/etc/php/conf.d/invoiceninja.ini
# - ./config/php/php-fpm.conf:/usr/local/etc/php-fpm.d/invoiceninja.conf
- ./config/php/php.ini:/usr/local/etc/php/php.ini
- ./config/php/php-cli.ini:/usr/local/etc/php/php-cli.ini
depends_on:
- db
- valkey
# extra_hosts:
# - "in5.localhost:192.168.0.124 " #host and ip
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
db:
image: mysql:8
@@ -54,8 +57,10 @@ services:
#- ./config/mysql/backup-script:/etc/cron.daily/daily:ro
#- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro
#- ./config/mysql/backup-script:/etc/cron.monthly/monthly:ro
# extra_hosts:
# - "in5.localhost:192.168.0.124 " #host and ip
networks:
- invoiceninja
extra_hosts:
- "in5.localhost:192.168.0.124 " #host and ip
# THIS IS ONLY A VALID CONFIGURATION FOR IN 4. DO NOT USE FOR IN 5.
# cron:
@@ -77,9 +82,6 @@ services:
# networks:
# - invoiceninja
#
valkey:
image: valkey/valkey:8
restart: unless-stopped
healthcheck:
test: [ "CMD", "valkey-cli", "ping" ]
start_period: 10s
networks:
invoiceninja:

7
env
View File

@@ -7,13 +7,8 @@ PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*'
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
REDIS_HOST=valkey
REDIS_PASSWORD=null
REDIS_PORT=6379
QUEUE_CONNECTION=database
# DB connection
DB_HOST=db