diff --git a/.github/workflows/build-image-debian.yaml b/.github/workflows/build-image-debian.yaml deleted file mode 100644 index f0e7fe1..0000000 --- a/.github/workflows/build-image-debian.yaml +++ /dev/null @@ -1,36 +0,0 @@ -name: Build Debian Octane Container Image - -on: - pull_request: - paths: - - "debian/**" - push: - paths: - - "debian/**" - branches: - - master - -jobs: - docker: - runs-on: ${{ startsWith(matrix.platforms, '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: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - - - name: Build - id: docker_build - uses: docker/build-push-action@v6 - with: - context: debian - load: true - tags: invoiceninja/invoiceninja-octane:test - cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file diff --git a/.github/workflows/build-image-octane.yaml b/.github/workflows/build-image-octane.yaml new file mode 100644 index 0000000..07f9ee5 --- /dev/null +++ b/.github/workflows/build-image-octane.yaml @@ -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 diff --git a/.github/workflows/publish-image-octane.yaml b/.github/workflows/publish-image-octane.yaml new file mode 100644 index 0000000..1c71a02 --- /dev/null +++ b/.github/workflows/publish-image-octane.yaml @@ -0,0 +1,161 @@ +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 }} + steps: + - id: version + run: | + + VERSION=edge + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + fi + MAJOR="$(echo "${VERSION}" | cut -d. -f1)" + MINOR="$(echo "${VERSION}" | cut -d. -f2)" + + # 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 + + 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: INVOICENINJA_VERSION=${{ needs.version.outputs.version }} + 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 }} diff --git a/.github/workflows/publish-image.yaml b/.github/workflows/publish-image.yaml deleted file mode 100644 index bdfecbd..0000000 --- a/.github/workflows/publish-image.yaml +++ /dev/null @@ -1,84 +0,0 @@ -name: Publish Debian Container Images - -on: - push: - tags-ignore: - - "invoiceninja-*" - -jobs: - docker: - runs-on: ${{ startsWith(matrix.platforms, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} - strategy: - fail-fast: false - matrix: - platform: ["linux/amd64", "linux/arm64"] - include: - - image: invoiceninja/invoiceninja-octane - context: debian - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - 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}" - - # 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")" - - TAGS="$TAGS,${DOCKER_IMAGE}:latest" - - echo "tags=${TAGS}" >> $GITHUB_OUTPUT # Updated output syntax - echo "version=${VERSION}" >> $GITHUB_OUTPUT - echo "major=${MAJOR}" >> $GITHUB_OUTPUT - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to DockerHub - if: github.event_name != 'pull_request' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v6 - with: - context: ${{ matrix.context }} - build-args: INVOICENINJA_VERSION=${{ steps.prep.outputs.version }} - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.prep.outputs.tags }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} - - Description: - runs-on: ubuntu-latest - 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: invoiceninja/invoiceninja-octane diff --git a/README.md b/README.md index 4ff66ce..e2534c5 100644 --- a/README.md +++ b/README.md @@ -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** -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/debian +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. @@ -51,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....` @@ -64,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``` @@ -74,8 +74,8 @@ docker-compose up -d To upgrade to a newer release image, update your docker-compose.yml first by running: ```bash -docker-compose pull -docker-compose up -d +docker compose pull +docker compose up -d ``` It is recommended to perform a backup before updating. diff --git a/debian/.env b/octane/.env similarity index 100% rename from debian/.env rename to octane/.env diff --git a/debian/Dockerfile b/octane/Dockerfile similarity index 94% rename from debian/Dockerfile rename to octane/Dockerfile index f95eb63..6fda878 100644 --- a/debian/Dockerfile +++ b/octane/Dockerfile @@ -4,8 +4,9 @@ ARG DEBIAN_VERSION=trixie FROM dunglas/frankenphp:${FRANKENPHP_VERSION}-php${PHP_VERSION}-${DEBIAN_VERSION} AS prepare-app -RUN curl -sL "https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar.gz" | \ - tar -xz \ +ADD https://github.com/invoiceninja/invoiceninja/releases/latest/download/invoiceninja.tar.gz /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 \ diff --git a/debian/docker-compose.yml b/octane/docker-compose.yml similarity index 100% rename from debian/docker-compose.yml rename to octane/docker-compose.yml diff --git a/debian/php/php.ini b/octane/php/php.ini similarity index 100% rename from debian/php/php.ini rename to octane/php/php.ini diff --git a/debian/scripts/init.sh b/octane/scripts/init.sh similarity index 100% rename from debian/scripts/init.sh rename to octane/scripts/init.sh