diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e87acb7..f718c90c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,7 @@ jobs: base_build: strategy: matrix: - dockerfile: [Dockerfile-bullseye] + dockerfile: [-bullseye, -threaded-bullseye] platform: [arm/v7, amd64, arm64, 386] runs-on: ubuntu-latest steps: @@ -100,7 +100,7 @@ jobs: with: context: . load: true - file: ./${{ matrix.dockerfile }} + file: ./Dockerfile${{ matrix.dockerfile }} platforms: linux/${{ matrix.platform }} push: false target: base @@ -115,8 +115,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dockerfile: [Dockerfile-bullseye] + dockerfile: [-bullseye, -threaded-bullseye] # Steps represent a sequence of tasks that will be executed as part of the job + env: + TAG_LATEST: ${{ (contains(matrix.dockerfile,'threaded') && github.event.release.prerelease == 1) && 'false' || 'auto' }} steps: - name: Checkout this repository uses: actions/checkout@v4 @@ -163,12 +165,12 @@ jobs: ghcr.io/${{ github.repository_owner }}/fhem-docker fhem/fhem flavor: | - latest= ${{ fromJSON('["auto", "false"]')[github.event.release.prerelease == 1 || endsWith(matrix.dockerfile, 'Dockerfile')] }} + latest= ${{ env.TAG_LATEST }} tags: | - type=semver,pattern={{version}},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=ref,event=branch,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=ref,event=pr,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} + type=semver,pattern={{version}},suffix=${{ matrix.dockerfile }} + type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ matrix.dockerfile }} + type=ref,event=branch,suffix=${{ matrix.dockerfile }} + type=ref,event=pr,suffix=${{ matrix.dockerfile }} - name: Build for bats with fhem base layer uses: docker/build-push-action@v5 @@ -176,7 +178,7 @@ jobs: with: context: . load: true - file: ./${{ matrix.dockerfile }} + file: ./Dockerfile${{ matrix.dockerfile }} platforms: linux/amd64 push: false target: with-fhem-bats @@ -204,7 +206,7 @@ jobs: with: context: . load: true - file: ./${{ matrix.dockerfile }} + file: ./Dockerfile${{ matrix.dockerfile }} platforms: linux/amd64 push: false target: with-fhem-python-nodejs @@ -244,8 +246,9 @@ jobs: needs: test_build strategy: matrix: - dockerfile: [Dockerfile-bullseye] - + dockerfile: [-bullseye, -threaded-bullseye] + env: + TAG_LATEST: ${{ (contains(matrix.dockerfile,'threaded') && github.event.release.prerelease == 1) && 'false' || 'auto' }} # Steps represent a sequence of tasks that will be executed as part of the job steps: - name: Checkout this repository @@ -289,13 +292,13 @@ jobs: ghcr.io/${{ github.repository_owner }}/fhem-docker fhem/fhem flavor: | - latest= ${{ fromJSON('["auto", "false"]')[github.event.release.prerelease == 1] }} + latest= ${{ env.TAG_LATEST }} tags: | - type=semver,pattern={{version}},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=ref,event=branch,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }},enable=${{ github.event.release.prerelease == 0 && env.GITHUB_REF_SLUG != 'master' }} - type=ref,event=pr,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=raw,enable=${{ env.GITHUB_REF_SLUG == 'master' }},priority=200,prefix=,suffix=${{ fromJSON('["bullseye", "buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }},value= + type=semver,pattern={{version}},suffix=${{ matrix.dockerfile }} + type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ matrix.dockerfile }} + type=ref,event=branch,suffix=${{ matrix.dockerfile }},enable=${{ github.event.release.prerelease == 0 && env.GITHUB_REF_SLUG != 'master' }} + type=ref,event=pr,suffix=${{ matrix.dockerfile }} + type=raw,enable=${{ env.GITHUB_REF_SLUG == 'master' }},priority=200,prefix=,suffix=${{ matrix.dockerfile }},value= - name: Build and push cross compiled fhem, python and nodejs layer on supported platforms uses: docker/build-push-action@v5 @@ -303,7 +306,7 @@ jobs: with: context: . load: false - file: ./${{ matrix.dockerfile }} + file: ./Dockerfile${{ matrix.dockerfile }} platforms: linux/amd64,linux/arm/v7,linux/arm64 push: ${{ github.event_name != 'pull_request' }} target: with-fhem-python-nodejs @@ -323,7 +326,7 @@ jobs: L_USAGE=${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/README.md L_VCS_URL=${{ github.server_url }}/${{ github.repository }}/ L_AUTHORS=${{ github.server_url }}/${{ github.repository }}/graphs/contributors - L_DESCR=A full blown Docker image for FHEM house automation system, based on Debian ${{ fromJSON('["bullseye", "buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }}. + L_DESCR=A full blown Docker image for FHEM house automation system, based on Debian Perl ${{ matrix.dockerfile }}. - name: Docker meta id: meta_base @@ -333,13 +336,13 @@ jobs: ghcr.io/${{ github.repository_owner }}/fhem-minimal-docker fhem/fhem-minimal flavor: | - latest= ${{ fromJSON('["auto", "false"]')[github.event.release.prerelease == 1] }} + latest= ${{ env.TAG_LATEST }} tags: | - type=semver,pattern={{version}},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=ref,event=branch,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }},enable=${{ github.event.release.prerelease == 0 && env.GITHUB_REF_SLUG != 'master' }} - type=ref,event=pr,suffix=${{ fromJSON('["-bullseye", "-buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }} - type=raw,enable=${{ env.GITHUB_REF_SLUG == 'master' }},priority=200,prefix=,suffix=${{ fromJSON('["bullseye", "buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }},value= + type=semver,pattern={{version}},suffix=${{ matrix.dockerfile }} + type=semver,pattern={{major}},enable=${{ github.event.release.prerelease == 0 }},suffix=${{ matrix.dockerfile }} + type=ref,event=branch,suffix=${{ matrix.dockerfile }},enable=${{ github.event.release.prerelease == 0 && env.GITHUB_REF_SLUG != 'master' }} + type=ref,event=pr,suffix=${{ matrix.dockerfile }} + type=raw,enable=${{ env.GITHUB_REF_SLUG == 'master' }},priority=200,prefix=,suffix=${{ matrix.dockerfile }},value= - name: Build and push cross compiled base image on supported platforms uses: docker/build-push-action@v5 @@ -347,7 +350,7 @@ jobs: with: context: . load: false - file: ./${{ matrix.dockerfile }} + file: ./Dockerfile${{ matrix.dockerfile }} platforms: linux/386,linux/amd64,linux/arm/v7,linux/arm64 push: ${{ github.event_name != 'pull_request' }} target: with-fhem @@ -368,4 +371,4 @@ jobs: L_USAGE=${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/README.md L_VCS_URL=${{ github.server_url }}/${{ github.repository }}/ L_AUTHORS=${{ github.server_url }}/${{ github.repository }}/graphs/contributors - L_DESCR=A minimal (perl) Docker image for FHEM house automation system, based on Debian ${{ fromJSON('["bullseye", "buster"]')[endsWith(matrix.dockerfile, 'Dockerfile')] }}. + L_DESCR=A minimal (perl) Docker image for FHEM house automation system, based on Debian Perl ${{ matrix.dockerfile }}. diff --git a/Dockerfile-threaded-bullseye b/Dockerfile-threaded-bullseye new file mode 100644 index 00000000..a2497848 --- /dev/null +++ b/Dockerfile-threaded-bullseye @@ -0,0 +1,308 @@ +# syntax=docker/dockerfile:1 +# +# base layer with perl and some general preparations +# +FROM perl:5.36.3-threaded-bullseye as base + +ARG TARGETPLATFORM + +ENV LANG=en_US.UTF-8 \ + LANGUAGE=en_US:en \ + LC_ADDRESS=de_DE.UTF-8 \ + LC_MEASUREMENT=de_DE.UTF-8 \ + LC_MESSAGES=en_DK.UTF-8 \ + LC_MONETARY=de_DE.UTF-8 \ + LC_NAME=de_DE.UTF-8 \ + LC_NUMERIC=de_DE.UTF-8 \ + LC_PAPER=de_DE.UTF-8 \ + LC_TELEPHONE=de_DE.UTF-8 \ + LC_TIME=de_DE.UTF-8 \ + TERM=xterm \ + TZ=Europe/Berlin + +RUN </etc/locale.gen + LC_ALL=C locale-gen + ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime + echo "Europe/Berlin" > /etc/timezone + LC_ALL=C DEBIAN_FRONTEND=noninteractive dpkg-reconfigure tzdata + LC_ALL=C apt-get autoremove -qqy && LC_ALL=C apt-get clean + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* ~/.[^.] ~/.??* ~/* +EOF + +RUN < /root/cpanfile + sed -i '/Device::Firmata::Constants/d' root/cpanfile >/root/cpanfile + fi + cpanm --notest --cpanfile /root/cpanfile --installdeps . + rm -rf /root/.cpanm +EOF + +RUN < /root/cpanfile_3rdparty + sed -i '/Device::Firmata::Constants/d' /root/cpanfile_3rdparty > /root/cpanfile_3rdparty + fi + + cpanm --notest --cpanfile /root/cpanfile_3rdparty --installdeps --with-suggests . + rm -rf /root/.cpanm +EOF + + + +# +# Standard FHEM Layer +# +FROM base-cpan as with-fhem + +# Install base environment, cache is invalidated here, because we set a BUILD_DATE Variable which changes every run. +COPY src/entry.sh src/health-check.sh src/ssh_known_hosts.txt / +COPY src/find-* /usr/local/bin/ + +# Add FHEM app layer +# Note: Manual checkout is required if build is not run by Github Actions workflow: +# svn co https://svn.fhem.de/fhem/trunk ./src/fhem/trunk +#COPY src/fhem/trunk/fhem/ /fhem/ +#COPY src/FHEM/trunk/fhem/* /fhem/ + +COPY src/FHEM/99_DockerImageInfo.pm /fhem/FHEM/ + +# FHEM specific ENVs +ENV LOGFILE=./log/fhem-%Y-%m-%d.log \ + TELNETPORT=7072 \ + FHEM_UID=6061 \ + FHEM_GID=6061 \ + FHEM_PERM_DIR=0750 \ + FHEM_PERM_FILE=0640 \ + UMASK=0037 \ + BLUETOOTH_GID=6001 \ + GPIO_GID=6002 \ + I2C_GID=6003 \ + TIMEOUT=10 \ + CONFIGTYPE=fhem.cfg + +# Moved AGS to the end, because it changes every run and invalidates the cache for all following steps https://github.com/moby/moby/issues/20136 +# Arguments to instantiate as variables +ARG PLATFORM="linux" +ARG TAG="" +ARG IMAGE_VCS_REF="" +ARG IMAGE_VERSION="" +ARG BUILD_DATE="" + +# Re-usable variables during build +ARG L_AUTHORS="" +ARG L_URL="https://hub.docker.com/r/fhem/fhem-${TARGETPLATFORM}" +ARG L_USAGE="https://github.com/fhem/fhem-docker/blob/${IMAGE_VCS_REF}/README.md" +ARG L_VCS_URL="https://github.com/fhem/fhem-docker/" +ARG L_VENDOR="FHEM" +ARG L_LICENSES="MIT" +ARG L_TITLE="fhem-${TARGETPLATFORM}" +ARG L_DESCR="A basic Docker image for FHEM house automation system, based on Debian Bullseye Perl image." + +ARG L_AUTHORS_FHEM="https://fhem.de/MAINTAINER.txt" +ARG L_URL_FHEM="https://fhem.de/" +ARG L_USAGE_FHEM="https://fhem.de/#Documentation" +ARG L_VCS_URL_FHEM="https://svn.fhem.de/" +ARG L_VENDOR_FHEM="FHEM e.V." +ARG L_LICENSES_FHEM="GPL-2.0" +ARG L_DESCR_FHEM="FHEM (TM) is a GPL'd perl server for house automation. It is used to automate some common tasks in the household like switching lamps / shutters / heating / etc. and to log events like temperature / humidity / power consumption." + + +# non-standard labels +LABEL org.fhem.authors=${L_AUTHORS_FHEM} \ + org.fhem.url=${L_URL_FHEM} \ + org.fhem.documentation=${L_USAGE_FHEM} \ + org.fhem.source=${L_VCS_URL_FHEM} \ + org.fhem.vendor=${L_VENDOR_FHEM} \ + org.fhem.licenses=${L_LICENSES_FHEM} \ + org.fhem.description=${L_DESCR_FHEM} + +# annotation labels according to +# https://github.com/opencontainers/image-spec/blob/v1.0.1/annotations.md#pre-defined-annotation-keys +LABEL org.opencontainers.image.created=${BUILD_DATE} \ + org.opencontainers.image.authors=${L_AUTHORS} \ + org.opencontainers.image.url=${L_URL} \ + org.opencontainers.image.documentation=${L_USAGE} \ + org.opencontainers.image.source=${L_VCS_URL} \ + org.opencontainers.image.version=${IMAGE_VERSION} \ + org.opencontainers.image.revision=${IMAGE_VCS_REF} \ + org.opencontainers.image.vendor=${L_VENDOR} \ + org.opencontainers.image.licenses=${L_LICENSES} \ + org.opencontainers.image.title=${L_TITLE} \ + org.opencontainers.image.description=${L_DESCR} + +RUN chmod 755 /*.sh /usr/local/bin/* \ + && echo "org.opencontainers.image.created=${BUILD_DATE}\norg.opencontainers.image.authors=${L_AUTHORS}\norg.opencontainers.image.url=${L_URL}\norg.opencontainers.image.documentation=${L_USAGE}\norg.opencontainers.image.source=${L_VCS_URL}\norg.opencontainers.image.version=${IMAGE_VERSION}\norg.opencontainers.image.revision=${IMAGE_VCS_REF}\norg.opencontainers.image.vendor=${L_VENDOR}\norg.opencontainers.image.licenses=${L_LICENSES}\norg.opencontainers.image.title=${L_TITLE}\norg.opencontainers.image.description=${L_DESCR}\norg.fhem.authors=${L_AUTHORS_FHEM}\norg.fhem.url=${L_URL_FHEM}\norg.fhem.documentation=${L_USAGE_FHEM}\norg.fhem.source=${L_VCS_URL_FHEM}\norg.fhem.version=${FHEM_VERSION}\norg.fhem.vendor=${L_VENDOR_FHEM}\norg.fhem.licenses=${L_LICENSES_FHEM}\norg.fhem.description=${L_DESCR_FHEM}" > /image_info + +VOLUME [ "/opt/fhem" ] + +EXPOSE 8083 + +HEALTHCHECK --interval=20s --timeout=10s --start-period=60s --retries=5 CMD /health-check.sh + +WORKDIR "/opt/fhem" +ENTRYPOINT [ "/entry.sh" ] +CMD [ "start" ] + +# +# Add additional Python layer +# + +FROM with-fhem as with-fhem-python + +RUN <