diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d93150c6bf..5fca2d5408 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -230,6 +230,8 @@ To build and run Coolify locally, see: [Development](./DEVELOPMENT.md) ### Testing the Coolify Helper Locally +When you change a tool version in `docker/coolify-helper/Dockerfile`, run `./scripts/helper-checksums` to update the SHA256 checksums of the downloads. + Use `scripts/dev-helper` to build a local helper image and test it with the running development instance. The script requires the standard local Coolify container and the seeded Dockerfile, Docker Compose, and Nixpacks applications. Run the complete workflow: diff --git a/config/constants.php b/config/constants.php index a2e6bf048a..744eaf1b1f 100644 --- a/config/constants.php +++ b/config/constants.php @@ -6,8 +6,8 @@ $sshCommandTimeout = (int) env('SSH_COMMAND_TIMEOUT', 3600); return [ 'coolify' => [ 'version' => env('COOLIFY_VERSION') ?: '4.5.1', - 'helper_version' => '1.0.18', - 'railpack_version' => '0.40.1', + 'helper_version' => '1.0.19', + 'railpack_version' => '0.43.0', 'self_hosted' => env('SELF_HOSTED', true), 'autoupdate' => env('AUTOUPDATE'), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), diff --git a/docker/coolify-helper/Dockerfile b/docker/coolify-helper/Dockerfile index b3c068f437..e3acabdd9a 100644 --- a/docker/coolify-helper/Dockerfile +++ b/docker/coolify-helper/Dockerfile @@ -1,25 +1,28 @@ # Versions # https://hub.docker.com/_/alpine -ARG BASE_IMAGE=alpine:3.21 +ARG BASE_IMAGE=alpine:3.24@sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a +# https://quay.io/repository/minio/aistor/mc?tab=tags +ARG MINIO_CLIENT_IMAGE=quay.io/minio/aistor/mc:RELEASE.2026-09-19T15-24-59Z@sha256:23511e340cbabf07e6a8b53f9c434975708f22f3c047d6beeddc17bf1a5aed88 # https://download.docker.com/linux/static/stable/ -ARG DOCKER_VERSION=29.7.2 +ARG DOCKER_VERSION=29.9.2 # https://github.com/docker/compose/releases -ARG DOCKER_COMPOSE_VERSION=5.5.0 +ARG DOCKER_COMPOSE_VERSION=5.6.1 # https://github.com/docker/buildx/releases -ARG DOCKER_BUILDX_VERSION=0.36.1 +ARG DOCKER_BUILDX_VERSION=0.38.1 # https://github.com/buildpacks/pack/releases -ARG PACK_VERSION=0.38.2 +ARG PACK_VERSION=0.40.10 # https://github.com/railwayapp/nixpacks/releases ARG NIXPACKS_VERSION=1.41.0 # https://github.com/railwayapp/railpack/releases -ARG RAILPACK_VERSION=0.40.1 +ARG RAILPACK_VERSION=0.43.0 # https://github.com/jdx/mise/releases — must match the version pinned at that railpack tag (https://raw.githubusercontent.com/railwayapp/railpack/v${RAILPACK_VERSION}/core/mise/version.txt) -ARG MISE_VERSION=2026.9.15 -FROM quay.io/minio/aistor/mc:RELEASE.2026-09-06T02-44-40Z AS minio-client +ARG MISE_VERSION=2026.10.14 + +FROM ${MINIO_CLIENT_IMAGE} AS minio-client FROM ${BASE_IMAGE} AS base -ARG TARGETPLATFORM +ARG TARGETARCH ARG DOCKER_VERSION ARG DOCKER_COMPOSE_VERSION ARG DOCKER_BUILDX_VERSION @@ -33,41 +36,56 @@ WORKDIR /artifacts ENV RAILPACK_VERSION=${RAILPACK_VERSION} RUN apk upgrade --no-cache && \ apk add --no-cache bash curl git git-lfs openssh-client pigz tar tini -RUN mkdir -p ~/.docker/cli-plugins +SHELL ["/bin/bash", "-euo", "pipefail", "-c"] -# Install mise (musl build) at the path railpack expects (/tmp/railpack/mise/mise-VERSION). -# Railpack skips its own mise download when this file exists. -RUN mkdir -p /tmp/railpack/mise && \ - if [[ ${TARGETPLATFORM} == 'linux/amd64' ]]; then \ - curl -sSL "https://github.com/jdx/mise/releases/download/v${MISE_VERSION}/mise-v${MISE_VERSION}-linux-x64-musl.tar.gz" | tar xz && \ - mv mise/bin/mise "/tmp/railpack/mise/mise-${MISE_VERSION}" && rm -rf mise; \ - elif [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ - curl -sSL "https://github.com/jdx/mise/releases/download/v${MISE_VERSION}/mise-v${MISE_VERSION}-linux-arm64-musl.tar.gz" | tar xz && \ - mv mise/bin/mise "/tmp/railpack/mise/mise-${MISE_VERSION}" && rm -rf mise; \ - fi +# SHA256 of every download, per architecture. After you change a version above, run scripts/helper-checksums to update them. +COPY <<'EOF' /tmp/SHA256SUMS +9ac225999fd5e863f7694c728ef23d480616b1e5639328fa309befd4243d69eb docker-amd64.tgz +873b3e0207857c3b2f28392fb922f3ea6efe37620c16d4d4aaf2fef409c90b73 docker-arm64.tgz +e25d5cd675092bb5d1d03632fdc46cdf3fede7b514dc5f023a105e00d3ce5ad4 docker-buildx-amd64 +3b83b3731916ba433feccaaa689fe5bcdc81c641d92c8e6c2ea865dfa141c97a docker-buildx-arm64 +47737f4236e6d3ccea7291995203f8f018058783b4c3a9469119811a0b5db8c0 docker-compose-amd64 +42cfa75f51ad0ccf290bad37899e0038a8c10a0069e85233ecc1d53e3ff1347d docker-compose-arm64 +b0e388c8014f9ac14a5ddf7a4042b0db28043f7f9ce485ffc2521bff02247f8e mise-amd64 +c71eec4d0015f6ced74ac9d5cd755b56674df04e899d0d1566d533c95511ae6c mise-arm64 +0f55de7874507b9cf7502113120bd96f2ab6979f78d10eaf2eb2ade9207b3af6 nixpacks-amd64.tgz +912bd02dd2bb6f9c3a9ed965fe8a68b4aa318dc7a2546e2eca6f2806a894ba39 nixpacks-arm64.tgz +687c3616e21824a449b56d4f989613ca68c921c6cce670b4de4459b025233806 pack-amd64.tgz +9a294abb0576fd95e19a009b3f9d5f5aa9fecdc2d7da7fa05e7e1e94f5085d77 pack-arm64.tgz +248a8f60f36854aabed6124113631078a802de3461660855fc4de9c26065c1fb railpack-amd64.tgz +732ece14eb4f4676a43ebba19431f954edf7b130acb76159ef0f2ff86ac42ac9 railpack-arm64.tgz +EOF -RUN if [[ ${TARGETPLATFORM} == 'linux/amd64' ]]; then \ - curl -sSL https://github.com/docker/buildx/releases/download/v${DOCKER_BUILDX_VERSION}/buildx-v${DOCKER_BUILDX_VERSION}.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx && \ - curl -sSL https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && \ - (curl -sSL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz | tar -C /usr/bin/ --no-same-owner -xzv --strip-components=1 docker/docker) && \ - (curl -sSL https://github.com/buildpacks/pack/releases/download/v${PACK_VERSION}/pack-v${PACK_VERSION}-linux.tgz | tar -C /usr/local/bin/ --no-same-owner -xzv pack) && \ - curl -sSL https://nixpacks.com/install.sh | bash && \ - curl -sSL https://railpack.com/install.sh | RAILPACK_VERSION=${RAILPACK_VERSION} sh && \ - chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack /root/.docker/cli-plugins/docker-buildx \ - ;fi - -RUN if [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ - curl -sSL https://github.com/docker/buildx/releases/download/v${DOCKER_BUILDX_VERSION}/buildx-v${DOCKER_BUILDX_VERSION}.linux-arm64 -o ~/.docker/cli-plugins/docker-buildx && \ - curl -sSL https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-linux-aarch64 -o ~/.docker/cli-plugins/docker-compose && \ - (curl -sSL https://download.docker.com/linux/static/stable/aarch64/docker-${DOCKER_VERSION}.tgz | tar -C /usr/bin/ --no-same-owner -xzv --strip-components=1 docker/docker) && \ - (curl -sSL https://github.com/buildpacks/pack/releases/download/v${PACK_VERSION}/pack-v${PACK_VERSION}-linux-arm64.tgz | tar -C /usr/local/bin/ --no-same-owner -xzv pack) && \ - curl -sSL https://nixpacks.com/install.sh | bash && \ - curl -sSL https://railpack.com/install.sh | RAILPACK_VERSION=${RAILPACK_VERSION} sh && \ - chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack /root/.docker/cli-plugins/docker-buildx \ - ;fi +RUN case "${TARGETARCH}" in \ + amd64) DOCKER_ARCH=x86_64; PACK_SUFFIX=""; NIXPACKS_ARCH=x86_64; RAILPACK_ARCH=x86_64; MISE_ARCH=x64 ;; \ + arm64) DOCKER_ARCH=aarch64; PACK_SUFFIX="-arm64"; NIXPACKS_ARCH=aarch64; RAILPACK_ARCH=arm64; MISE_ARCH=arm64 ;; \ + *) echo "Unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; \ + esac && \ + mkdir -p /tmp/downloads && cd /tmp/downloads && \ + download() { curl -fsSL --proto '=https' --tlsv1.2 --retry 3 -o "$1" "$2"; } && \ + download "docker-${TARGETARCH}.tgz" "https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz" && \ + download "docker-compose-${TARGETARCH}" "https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-linux-${DOCKER_ARCH}" && \ + download "docker-buildx-${TARGETARCH}" "https://github.com/docker/buildx/releases/download/v${DOCKER_BUILDX_VERSION}/buildx-v${DOCKER_BUILDX_VERSION}.linux-${TARGETARCH}" && \ + download "pack-${TARGETARCH}.tgz" "https://github.com/buildpacks/pack/releases/download/v${PACK_VERSION}/pack-v${PACK_VERSION}-linux${PACK_SUFFIX}.tgz" && \ + download "nixpacks-${TARGETARCH}.tgz" "https://github.com/railwayapp/nixpacks/releases/download/v${NIXPACKS_VERSION}/nixpacks-v${NIXPACKS_VERSION}-${NIXPACKS_ARCH}-unknown-linux-musl.tar.gz" && \ + download "railpack-${TARGETARCH}.tgz" "https://github.com/railwayapp/railpack/releases/download/v${RAILPACK_VERSION}/railpack-v${RAILPACK_VERSION}-${RAILPACK_ARCH}-unknown-linux-musl.tar.gz" && \ + download "mise-${TARGETARCH}" "https://github.com/jdx/mise/releases/download/v${MISE_VERSION}/mise-v${MISE_VERSION}-linux-${MISE_ARCH}-musl" && \ + grep -- "-${TARGETARCH}" /tmp/SHA256SUMS | sha256sum -c - && \ + mkdir -p /root/.docker/cli-plugins /tmp/railpack/mise && \ + tar -xzf "docker-${TARGETARCH}.tgz" -C /usr/bin --no-same-owner --strip-components=1 docker/docker && \ + install -m 0755 "docker-compose-${TARGETARCH}" /root/.docker/cli-plugins/docker-compose && \ + install -m 0755 "docker-buildx-${TARGETARCH}" /root/.docker/cli-plugins/docker-buildx && \ + tar -xzf "pack-${TARGETARCH}.tgz" -C /usr/local/bin --no-same-owner pack && \ + tar -xzf "nixpacks-${TARGETARCH}.tgz" -C /usr/local/bin --no-same-owner nixpacks && \ + tar -xzf "railpack-${TARGETARCH}.tgz" -C /usr/local/bin --no-same-owner railpack && \ + # Railpack skips its own mise download when this file exists. + install -m 0755 "mise-${TARGETARCH}" "/tmp/railpack/mise/mise-${MISE_VERSION}" && \ + cd / && rm -rf /tmp/downloads /tmp/SHA256SUMS && \ + docker --version && docker compose version && docker buildx version && pack --version && \ + nixpacks --version && railpack --version COPY --from=minio-client /usr/bin/mc /usr/bin/mc -RUN chmod +x /usr/bin/mc +RUN chmod +x /usr/bin/mc && mc --version ENTRYPOINT ["/sbin/tini", "--"] CMD ["tail", "-f", "/dev/null"] diff --git a/other/nightly/versions.json b/other/nightly/versions.json index f96c7ef895..d0c384b345 100644 --- a/other/nightly/versions.json +++ b/other/nightly/versions.json @@ -7,7 +7,7 @@ "version": "4.6-rc.1" }, "helper": { - "version": "1.0.18" + "version": "1.0.19" }, "sentinel": { "version": "1.1.2" diff --git a/scripts/helper-checksums b/scripts/helper-checksums new file mode 100755 index 0000000000..afdeff5979 --- /dev/null +++ b/scripts/helper-checksums @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Update the SHA256SUMS block in docker/coolify-helper/Dockerfile. +# Change the ARG versions in the Dockerfile first, then run this script. +# It downloads every file, compares it with the upstream checksum file where one exists, and writes the new block. + +set -euo pipefail + +ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +DOCKERFILE="$ROOT_DIR/docker/coolify-helper/Dockerfile" +GH=https://github.com + +arg() { + sed -n "s/^ARG $1=//p" "$DOCKERFILE" +} + +DOCKER_VERSION=$(arg DOCKER_VERSION) +DOCKER_COMPOSE_VERSION=$(arg DOCKER_COMPOSE_VERSION) +DOCKER_BUILDX_VERSION=$(arg DOCKER_BUILDX_VERSION) +PACK_VERSION=$(arg PACK_VERSION) +NIXPACKS_VERSION=$(arg NIXPACKS_VERSION) +RAILPACK_VERSION=$(arg RAILPACK_VERSION) +MISE_VERSION=$(arg MISE_VERSION) + +railpack_mise=$(curl -fsSL "https://raw.githubusercontent.com/railwayapp/railpack/v${RAILPACK_VERSION}/core/mise/version.txt") +if [[ $railpack_mise != "$MISE_VERSION" ]]; then + echo "MISE_VERSION is $MISE_VERSION, but Railpack $RAILPACK_VERSION pins mise $railpack_mise." >&2 + exit 1 +fi + +WORK_DIR=$(mktemp -d) +trap 'rm -rf "$WORK_DIR"' EXIT + +lines=() + +# add [upstream checksum file URL] +add() { + local name=$1 url=$2 sums_url=${3:-} sum upstream + curl -fsSL --proto '=https' --tlsv1.2 --retry 3 -o "$WORK_DIR/$name" "$url" + sum=$(sha256sum "$WORK_DIR/$name" | cut -d' ' -f1) + + if [[ -n $sums_url ]]; then + upstream=$(curl -fsSL "$sums_url" | grep -F "${url##*/}" | awk '{print $1}' | head -1) + if [[ $upstream != "$sum" ]]; then + echo "Checksum mismatch for $url (upstream: ${upstream:-not found}, downloaded: $sum)." >&2 + exit 1 + fi + echo "verified $name" + else + echo "no upstream checksum $name" + fi + + lines+=("$sum $name") +} + +for arch in amd64 arm64; do + case $arch in + amd64) DOCKER_ARCH=x86_64; PACK_SUFFIX=""; NIXPACKS_ARCH=x86_64; RAILPACK_ARCH=x86_64; MISE_ARCH=x64 ;; + arm64) DOCKER_ARCH=aarch64; PACK_SUFFIX="-arm64"; NIXPACKS_ARCH=aarch64; RAILPACK_ARCH=arm64; MISE_ARCH=arm64 ;; + esac + + add "docker-$arch.tgz" \ + "https://download.docker.com/linux/static/stable/$DOCKER_ARCH/docker-$DOCKER_VERSION.tgz" + add "docker-compose-$arch" \ + "$GH/docker/compose/releases/download/v$DOCKER_COMPOSE_VERSION/docker-compose-linux-$DOCKER_ARCH" \ + "$GH/docker/compose/releases/download/v$DOCKER_COMPOSE_VERSION/checksums.txt" + add "docker-buildx-$arch" \ + "$GH/docker/buildx/releases/download/v$DOCKER_BUILDX_VERSION/buildx-v$DOCKER_BUILDX_VERSION.linux-$arch" \ + "$GH/docker/buildx/releases/download/v$DOCKER_BUILDX_VERSION/checksums.txt" + add "pack-$arch.tgz" \ + "$GH/buildpacks/pack/releases/download/v$PACK_VERSION/pack-v$PACK_VERSION-linux$PACK_SUFFIX.tgz" \ + "$GH/buildpacks/pack/releases/download/v$PACK_VERSION/pack-v$PACK_VERSION-linux$PACK_SUFFIX.tgz.sha256" + add "nixpacks-$arch.tgz" \ + "$GH/railwayapp/nixpacks/releases/download/v$NIXPACKS_VERSION/nixpacks-v$NIXPACKS_VERSION-$NIXPACKS_ARCH-unknown-linux-musl.tar.gz" + add "railpack-$arch.tgz" \ + "$GH/railwayapp/railpack/releases/download/v$RAILPACK_VERSION/railpack-v$RAILPACK_VERSION-$RAILPACK_ARCH-unknown-linux-musl.tar.gz" \ + "$GH/railwayapp/railpack/releases/download/v$RAILPACK_VERSION/checksums.txt" + add "mise-$arch" \ + "$GH/jdx/mise/releases/download/v$MISE_VERSION/mise-v$MISE_VERSION-linux-$MISE_ARCH-musl" \ + "$GH/jdx/mise/releases/download/v$MISE_VERSION/SHASUMS256.txt" +done + +block=$(printf '%s\n' "${lines[@]}" | sort -k2) +BLOCK="$block" perl -0pi -e 's/(COPY <<.EOF. \/tmp\/SHA256SUMS\n).*?(\nEOF\n)/$1$ENV{BLOCK}$2/s' "$DOCKERFILE" + +echo "Updated SHA256SUMS in $DOCKERFILE"