diff --git a/.github/workflows/call_issue_pr_tracker.yml b/.github/workflows/call_issue_pr_tracker.yml index 2c30784..d07cf12 100644 --- a/.github/workflows/call_issue_pr_tracker.yml +++ b/.github/workflows/call_issue_pr_tracker.yml @@ -8,6 +8,9 @@ on: pull_request_review: types: [submitted,edited,dismissed] +permissions: + contents: read + jobs: manage-project: permissions: diff --git a/.github/workflows/call_issues_cron.yml b/.github/workflows/call_issues_cron.yml index 62c79fd..54a20a4 100644 --- a/.github/workflows/call_issues_cron.yml +++ b/.github/workflows/call_issues_cron.yml @@ -4,6 +4,9 @@ on: - cron: '14 1 * * *' workflow_dispatch: +permissions: + contents: read + jobs: stale: permissions: diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index ca6cd64..1e792d0 100644 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -3,6 +3,9 @@ name: External Trigger Main on: workflow_dispatch: +permissions: + contents: read + jobs: external-trigger-main: runs-on: ubuntu-latest @@ -43,8 +46,8 @@ jobs: "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} exit 1 fi - EXT_RELEASE=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g') - echo "External version: \`${EXT_RELEASE}\`" >> $GITHUB_STEP_SUMMARY + EXT_RELEASE_SANITIZED=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g') + echo "Sanitized external version: \`${EXT_RELEASE_SANITIZED}\`" >> $GITHUB_STEP_SUMMARY echo "Retrieving last pushed version" >> $GITHUB_STEP_SUMMARY image="linuxserver/planka" tag="latest" @@ -100,8 +103,8 @@ jobs: exit 1 fi echo "Last pushed version: \`${IMAGE_VERSION}\`" >> $GITHUB_STEP_SUMMARY - if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then - echo "Version \`${EXT_RELEASE}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY + if [ "${EXT_RELEASE_SANITIZED}" == "${IMAGE_VERSION}" ]; then + echo "Sanitized version \`${EXT_RELEASE_SANITIZED}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY exit 0 elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-planka/job/main/lastBuild/api/json | jq -r '.building') == "true" ]; then echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY @@ -116,7 +119,7 @@ jobs: "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} else printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY - echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY + echo "New sanitized version \`${EXT_RELEASE_SANITIZED}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY if [[ "${artifacts_found}" == "true" ]]; then echo "All artifacts seem to be uploaded." >> $GITHUB_STEP_SUMMARY fi @@ -136,7 +139,7 @@ jobs: --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ --data-urlencode "Submit=Submit" echo "**** Notifying Discord ****" - TRIGGER_REASON="A version change was detected for planka tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" + TRIGGER_REASON="A version change was detected for planka tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE_SANITIZED}" curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} diff --git a/.github/workflows/external_trigger_scheduler.yml b/.github/workflows/external_trigger_scheduler.yml index 05811a5..9e67bb0 100644 --- a/.github/workflows/external_trigger_scheduler.yml +++ b/.github/workflows/external_trigger_scheduler.yml @@ -5,6 +5,9 @@ on: - cron: '51 * * * *' workflow_dispatch: +permissions: + contents: read + jobs: external-trigger-scheduler: runs-on: ubuntu-latest diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index 9cc3224..4dfe0b0 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -2,8 +2,14 @@ name: Greetings on: [pull_request_target, issues] +permissions: + contents: read + jobs: greeting: + permissions: + issues: write + pull-requests: write runs-on: ubuntu-latest steps: - uses: actions/first-interaction@v1 diff --git a/.github/workflows/package_trigger_scheduler.yml b/.github/workflows/package_trigger_scheduler.yml index c3f8ec1..073bd51 100644 --- a/.github/workflows/package_trigger_scheduler.yml +++ b/.github/workflows/package_trigger_scheduler.yml @@ -5,6 +5,9 @@ on: - cron: '28 15 * * 4' workflow_dispatch: +permissions: + contents: read + jobs: package-trigger-scheduler: runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index 209fca4..f488425 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,21 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/linuxserver/baseimage-alpine:3.21 AS buildstage +FROM ghcr.io/linuxserver/baseimage-alpine:3.22 AS buildstage # set version label ARG PLANKA_RELEASE RUN \ echo "**** install packages ****" && \ - apk add --no-cache \ + apk add --no-cache --virtual=build-dependencies \ + build-base \ giflib \ libgsf \ nodejs \ - vips && \ - apk add --no-cache --virtual=build-dependencies \ - build-base \ npm \ py3-setuptools \ - python3-dev && \ + python3-dev \ + vips && \ echo "**** install planka ****" && \ if [ -z ${PLANKA_RELEASE+x} ]; then \ PLANKA_RELEASE=$(curl -s https://api.github.com/repos/plankanban/planka/releases/latest \ @@ -30,12 +29,9 @@ RUN \ /tmp/planka.tar.gz -C \ /build --strip-components=1 && \ cd /build/server && \ - npm install pnpm@9 --global && \ - pnpm import && \ - pnpm install --prod && \ + npm install --omit=dev && \ cd /build/client && \ - pnpm import && \ - pnpm install --prod && \ + npm install --omit=dev && \ DISABLE_ESLINT_PLUGIN=true npm run build && \ echo "**** cleanup ****" && \ apk del --purge \ @@ -46,7 +42,7 @@ RUN \ $HOME/.npm \ /tmp/* -FROM ghcr.io/linuxserver/baseimage-alpine:3.21 +FROM ghcr.io/linuxserver/baseimage-alpine:3.22 ARG BUILD_DATE ARG VERSION @@ -56,18 +52,19 @@ LABEL maintainer="thespad" COPY --from=buildstage /build/server/ /app COPY --from=buildstage /build/server/.env.sample /app/.env -COPY --from=buildstage /build/client/build /app/public/ -COPY --from=buildstage /build/client/build/index.html /app/views/index.ejs +COPY --from=buildstage /build/client/dist /app/public/ +COPY --from=buildstage /build/client/dist/index.html /app/views RUN \ apk add --no-cache \ nodejs \ + npm \ postgresql16-client && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** create symlinks ****" && \ /bin/bash -c \ - 'dst=(user-avatars project-background-images attachments logs); \ - src=(public/user-avatars public/project-background-images private/attachments logs); \ + 'dst=(favicons user-avatars background-images attachments logs); \ + src=(public/favicons public/user-avatars public/background-images private/attachments logs); \ for i in "${!src[@]}"; do rm -rf /app/"${src[i]}" && ln -s /config/"${dst[i]}" /app/"${src[i]}"; done' # copy local files diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 9738d4b..1c6e9eb 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -1,22 +1,21 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.21 AS buildstage +FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.22 AS buildstage # set version label ARG PLANKA_RELEASE RUN \ echo "**** install packages ****" && \ - apk add --no-cache \ + apk add --no-cache --virtual=build-dependencies \ + build-base \ giflib \ libgsf \ nodejs \ - vips && \ - apk add --no-cache --virtual=build-dependencies \ - build-base \ npm \ py3-setuptools \ - python3-dev && \ + python3-dev \ + vips && \ echo "**** install planka ****" && \ if [ -z ${PLANKA_RELEASE+x} ]; then \ PLANKA_RELEASE=$(curl -s https://api.github.com/repos/plankanban/planka/releases/latest \ @@ -30,12 +29,9 @@ RUN \ /tmp/planka.tar.gz -C \ /build --strip-components=1 && \ cd /build/server && \ - npm install pnpm@9 --global && \ - pnpm import && \ - pnpm install --prod && \ + npm install --omit=dev && \ cd /build/client && \ - pnpm import && \ - pnpm install --prod && \ + npm install --omit=dev && \ DISABLE_ESLINT_PLUGIN=true npm run build && \ echo "**** cleanup ****" && \ apk del --purge \ @@ -46,7 +42,7 @@ RUN \ $HOME/.npm \ /tmp/* -FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.21 +FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.22 ARG BUILD_DATE ARG VERSION @@ -56,19 +52,20 @@ LABEL maintainer="thespad" COPY --from=buildstage /build/server/ /app COPY --from=buildstage /build/server/.env.sample /app/.env -COPY --from=buildstage /build/client/build /app/public/ -COPY --from=buildstage /build/client/build/index.html /app/views/index.ejs +COPY --from=buildstage /build/client/dist /app/public/ +COPY --from=buildstage /build/client/dist/index.html /app/views RUN \ apk add --no-cache \ nodejs \ + npm \ postgresql16-client && \ - printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ - echo "**** create symlinks ****" && \ - /bin/bash -c \ - 'dst=(user-avatars project-background-images attachments logs); \ - src=(public/user-avatars public/project-background-images private/attachments logs); \ - for i in "${!src[@]}"; do rm -rf /app/"${src[i]}" && ln -s /config/"${dst[i]}" /app/"${src[i]}"; done' + printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ + echo "**** create symlinks ****" && \ + /bin/bash -c \ + 'dst=(favicons user-avatars background-images attachments logs); \ + src=(public/favicons public/user-avatars public/background-images private/attachments logs); \ + for i in "${!src[@]}"; do rm -rf /app/"${src[i]}" && ln -s /config/"${dst[i]}" /app/"${src[i]}"; done' # copy local files COPY root/ / diff --git a/Jenkinsfile b/Jenkinsfile index efb72a7..b686284 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -97,7 +97,11 @@ pipeline { env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/' env.PULL_REQUEST = env.CHANGE_ID env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml ./root/donate.txt' + if ( env.SYFT_IMAGE_TAG == null ) { + env.SYFT_IMAGE_TAG = 'latest' + } } + echo "Using syft image tag ${SYFT_IMAGE_TAG}" sh '''#! /bin/bash echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" ''' script{ @@ -790,7 +794,7 @@ pipeline { docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v ${TEMPDIR}:/tmp \ - ghcr.io/anchore/syft:latest \ + ghcr.io/anchore/syft:${SYFT_IMAGE_TAG} \ ${LOCAL_CONTAINER} -o table=/tmp/package_versions.txt NEW_PACKAGE_TAG=$(md5sum ${TEMPDIR}/package_versions.txt | cut -c1-8 ) echo "Package tag sha from current packages in buit container is ${NEW_PACKAGE_TAG} comparing to old ${PACKAGE_TAG} from github" @@ -900,6 +904,7 @@ pipeline { -e WEB_AUTH=\"${CI_AUTH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \ -e NODE_NAME=\"${NODE_NAME}\" \ + -e SYFT_IMAGE_TAG=\"${CI_SYFT_IMAGE_TAG:-${SYFT_IMAGE_TAG}}\" \ -t ghcr.io/linuxserver/ci:latest \ python3 test_build.py''' } diff --git a/README.md b/README.md index f88fda7..21ce8ec 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![Blog](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Blog)](https://blog.linuxserver.io "all the things you can do with our containers including How-To guides, opinions and much more!") [![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://linuxserver.io/discord "realtime support / chat with the community and the team.") [![Discourse](https://img.shields.io/discourse/https/discourse.linuxserver.io/topics.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=discourse)](https://discourse.linuxserver.io "post on our community forum.") -[![Fleet](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Fleet)](https://fleet.linuxserver.io "an online web interface which displays all of our maintained images.") [![GitHub](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub&logo=github)](https://github.com/linuxserver "view the source for all of our repositories.") [![Open Collective](https://img.shields.io/opencollective/all/linuxserver.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Supporters&logo=open%20collective)](https://opencollective.com/linuxserver "please consider helping us by either donating or contributing to our budget") @@ -22,7 +21,6 @@ Find us at: * [Blog](https://blog.linuxserver.io) - all the things you can do with our containers including How-To guides, opinions and much more! * [Discord](https://linuxserver.io/discord) - realtime support / chat with the community and the team. * [Discourse](https://discourse.linuxserver.io) - post on our community forum. -* [Fleet](https://fleet.linuxserver.io) - an online web interface which displays all of our maintained images. * [GitHub](https://github.com/linuxserver) - view the source for all of our repositories. * [Open Collective](https://opencollective.com/linuxserver) - please consider helping us by either donating or contributing to our budget @@ -54,7 +52,6 @@ The architectures supported by this image are: | :----: | :----: | ---- | | x86-64 | ✅ | amd64-\ | | arm64 | ✅ | arm64v8-\ | -| armhf | ❌ | | ## Application Setup @@ -107,7 +104,8 @@ services: - DEFAULT_ADMIN_PASSWORD=demo - "DEFAULT_ADMIN_NAME=Demo User" - SECRET_KEY=notasecretkey - - TRUST_PROXY=0 + - TRUST_PROXY=false + - DEFAULT_LANGUAGE=en-US #optional volumes: - /path/to/planka/data:/config ports: @@ -130,7 +128,8 @@ docker run -d \ -e DEFAULT_ADMIN_PASSWORD=demo \ -e DEFAULT_ADMIN_NAME="Demo User" \ -e SECRET_KEY=notasecretkey \ - -e TRUST_PROXY=0 \ + -e TRUST_PROXY=false \ + -e DEFAULT_LANGUAGE=en-US `#optional` \ -p 1337:1337 \ -v /path/to/planka/data:/config \ --restart unless-stopped \ @@ -154,7 +153,8 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e DEFAULT_ADMIN_PASSWORD=demo` | Password for default user. | | `-e DEFAULT_ADMIN_NAME=Demo User` | Display name for default user. | | `-e SECRET_KEY=notasecretkey` | Session encryption key, recommended 32-64 character alphanumeric. | -| `-e TRUST_PROXY=0` | Set to `1` to trust upstream proxies if reverse proxying. | +| `-e TRUST_PROXY=false` | Set to `true` to trust upstream proxies if reverse proxying. | +| `-e DEFAULT_LANGUAGE=en-US` | This sets the default language for sending notifications per user (if a user hasn't selected a language) and per board. | | `-v /config` | Local path for planka config files. | | `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). | | `--user=1000:1000` | Run container with a non-root user. Please [read the docs](https://docs.linuxserver.io/misc/non-root/). | @@ -321,6 +321,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **05.07.25:** - Rebase to Alpine 3.22. Updates for v2. Users should update `TRUST_PROXY` to use `true`/`false` instead of `1`/`0`. * **12.01.25:** - Rebase to Alpine 3.21. * **18.09.24:** - Update default user docs. * **12.09.24:** - Initial Release. diff --git a/readme-vars.yml b/readme-vars.yml index 5e2de54..9176189 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -23,7 +23,10 @@ param_env_vars: - {env_var: "DEFAULT_ADMIN_PASSWORD", env_value: "demo", desc: "Password for default user."} - {env_var: "DEFAULT_ADMIN_NAME", env_value: "Demo User", desc: "Display name for default user."} - {env_var: "SECRET_KEY", env_value: "notasecretkey", desc: "Session encryption key, recommended 32-64 character alphanumeric."} - - {env_var: "TRUST_PROXY", env_value: "0", desc: "Set to `1` to trust upstream proxies if reverse proxying."} + - {env_var: "TRUST_PROXY", env_value: "false", desc: "Set to `true` to trust upstream proxies if reverse proxying."} +opt_param_usage_include_env: true +opt_param_env_vars: + - {env_var: "DEFAULT_LANGUAGE", env_value: "en-US", desc: "This sets the default language for sending notifications per user (if a user hasn't selected a language) and per board."} param_usage_include_vols: true param_volumes: - {vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/data", desc: "Local path for planka config files."} @@ -90,6 +93,7 @@ init_diagram: | "planka:latest" <- Base Images # changelog changelogs: + - {date: "05.07.25:", desc: "Rebase to Alpine 3.22. Updates for v2. Users should update `TRUST_PROXY` to use `true`/`false` instead of `1`/`0`."} - {date: "12.01.25:", desc: "Rebase to Alpine 3.21."} - {date: "18.09.24:", desc: "Update default user docs."} - {date: "12.09.24:", desc: "Initial Release."} diff --git a/root/etc/s6-overlay/s6-rc.d/init-planka-config/run b/root/etc/s6-overlay/s6-rc.d/init-planka-config/run index 76a798d..eb5478b 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-planka-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-planka-config/run @@ -3,7 +3,7 @@ cd /app || exit 1 -mkdir -p /config/logs +mkdir -p /config/{favicons,user-avatars,background-images,attachments,logs} if [[ -n ${DATABASE_URL} ]]; then DB_HOST=$(awk -F '@|:|/' '{print $6}' <<<"${DATABASE_URL}") @@ -28,6 +28,14 @@ else sleep infinity fi +# v2 migration nonsense +if [[ ! -f "/config/v2" ]] && [[ -f "/config/logs/planka.log" ]]; then + cp -a /config/project-background-images/. /config/background-images + TZ=UTC s6-setuidgid abc npm run db:upgrade + rm -rf /config/project-background-images + touch "/config/v2" +fi + echo "Migrating database..." if [[ -z ${LSIO_NON_ROOT_USER} ]]; then TZ=UTC s6-setuidgid abc node db/init.js