Skip to content

Commit

Permalink
feat: added node
Browse files Browse the repository at this point in the history
  • Loading branch information
bhunter234 authored and divyam234 committed Sep 1, 2024
1 parent 48cc174 commit 1092285
Show file tree
Hide file tree
Showing 12 changed files with 576 additions and 17 deletions.
189 changes: 189 additions & 0 deletions .github/workflows/node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
name: node

on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:

env:
DOCKER_CLI_EXPERIMENTAL: enabled
REPOSITORY: tgdrive/${{ github.workflow }}

permissions:
packages: write

jobs:
fetch-versions:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.versions.outputs.latest }}
lts: ${{ steps.versions.outputs.lts }}
steps:
- name: Fetch Node.js versions
id: versions
run: |
LATEST=$(curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.lts == false)][0].version')
LTS=$(curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.lts != false)][0].version')
echo "latest=${LATEST#v}" >> $GITHUB_OUTPUT
echo "lts=${LTS#v}" >> $GITHUB_OUTPUT
check-existing-images:
needs: fetch-versions
runs-on: ubuntu-latest
outputs:
build_latest: ${{ steps.check.outputs.build_latest }}
build_lts: ${{ steps.check.outputs.build_lts }}
steps:
- name: Check existing images
id: check
run: |
LATEST_VERSION=${{ needs.fetch-versions.outputs.latest }}
LTS_VERSION=${{ needs.fetch-versions.outputs.lts }}
check_image() {
REPO="ghcr.io/${{ env.REPOSITORY }}"
TAG="$1"
curl -s -f -L -I -o /dev/null -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://ghcr.io/v2/${REPO#ghcr.io/}/manifests/${TAG}" && echo "exists" || echo "not_exists"
}
LATEST_EXISTS=$(check_image $LATEST_VERSION)
LTS_EXISTS=$(check_image $LTS_VERSION)
echo "build_latest=$([[ $LATEST_EXISTS == "not_exists" ]] && echo "true" || echo "false")" >> $GITHUB_OUTPUT
echo "build_lts=$([[ $LTS_EXISTS == "not_exists" ]] && echo "true" || echo "false")" >> $GITHUB_OUTPUT
build-and-push:
needs: [fetch-versions, check-existing-images]
runs-on: ubuntu-latest
strategy:
matrix:
arch: [amd64]
version_type: [latest, lts]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Prepare tags and cache keys
id: prep
run: |
if [[ "${{ matrix.version_type }}" == "latest" ]]; then
VERSION=${{ needs.fetch-versions.outputs.latest }}
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_latest }}
else
VERSION=${{ needs.fetch-versions.outputs.lts }}
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_lts }}
fi
MAJOR_VERSION=$(echo $VERSION | cut -d. -f1)
TAGS="ghcr.io/${{ env.REPOSITORY }}:${VERSION}-${{ matrix.arch }}"
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:${MAJOR_VERSION}-${{ matrix.arch }}"
if [[ "${{ matrix.version_type }}" == "lts" ]]; then
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:lts-${{ matrix.arch }}"
fi
if [[ "${{ matrix.version_type }}" == "latest" ]]; then
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:latest-${{ matrix.arch }}"
fi
CACHE_FROM="type=gha,scope=${{ github.workflow }}-${{ matrix.version_type }}-${{ matrix.arch }}"
CACHE_TO="type=gha,scope=${{ github.workflow }}-${{ matrix.version_type }}-${{ matrix.arch }}"
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "major_version=${MAJOR_VERSION}" >> $GITHUB_OUTPUT
echo "build_condition=${BUILD_CONDITION}" >> $GITHUB_OUTPUT
echo "cache_from=${CACHE_FROM}" >> $GITHUB_OUTPUT
echo "cache_to=${CACHE_TO}" >> $GITHUB_OUTPUT
- name: Set Docker metadata
id: docker_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REPOSITORY }}
labels: |
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.title=${{ env.REPOSITORY }}
org.opencontainers.image.description="Node.js Distroless image"
- name: Build and push image
uses: docker/build-push-action@v6
if: steps.prep.outputs.build_condition == 'true'
with:
context: ./node
push: true
provenance: false
labels: ${{ steps.docker_meta.outputs.labels }}
build-args: |
version=${{ steps.prep.outputs.version }}
arch=${{ matrix.arch == 'arm64' && 'arm64v8' || matrix.arch }}
cache-from: ${{ steps.prep.outputs.cache_from }}
cache-to: ${{ steps.prep.outputs.cache_to }}
tags: ${{ steps.prep.outputs.tags }}


create-and-push-manifest:
needs: [fetch-versions, check-existing-images, build-and-push]
runs-on: ubuntu-latest
strategy:
matrix:
version_type: [latest, lts]
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Create and push manifests
run: |
if [[ "${{ matrix.version_type }}" == "latest" ]]; then
VERSION=${{ needs.fetch-versions.outputs.latest }}
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_latest }}
else
VERSION=${{ needs.fetch-versions.outputs.lts }}
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_lts }}
fi
if [[ "${BUILD_CONDITION}" != "true" ]]; then
echo "Skipping manifest creation for ${{ matrix.version_type }} as it was not built"
exit 0
fi
MAJOR_VERSION=$(echo $VERSION | cut -d. -f1)
create_and_push_manifest() {
local TAG=$1
docker manifest create --amend ghcr.io/${{ env.REPOSITORY }}:${TAG} \
ghcr.io/${{ env.REPOSITORY }}:${VERSION}-amd64
docker manifest annotate --os linux --arch amd64 ghcr.io/${{ env.REPOSITORY }}:${TAG} ghcr.io/${{ env.REPOSITORY }}:${VERSION}-amd64
#docker manifest annotate --os linux --arch arm64 ghcr.io/${{ env.REPOSITORY }}:${TAG} ghcr.io/${{ env.REPOSITORY }}:${VERSION}-arm64
docker manifest push --purge ghcr.io/${{ env.REPOSITORY }}:${TAG}
}
create_and_push_manifest ${VERSION}
create_and_push_manifest ${MAJOR_VERSION}
if [[ "${{ matrix.version_type }}" == "latest" ]]; then
create_and_push_manifest latest
else
create_and_push_manifest lts
fi
44 changes: 29 additions & 15 deletions .github/workflows/postgres.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
name: Build Postgres
name: postgres

on:
schedule:
- cron: '0 0 1 * *'

workflow_dispatch:

env:
BUILD_VERSION: "16-alpine"
DOCKER_CLI_EXPERIMENTAL: enabled
REPOSITORY: tgdrive/${{ github.workflow }}

jobs:
build-postgres:
build:
runs-on: ubuntu-latest
permissions:
packages: write
Expand All @@ -15,10 +21,10 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

Expand All @@ -28,22 +34,30 @@ jobs:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta

- name: Set Docker metadata
id: docker_meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/tgdrive/postgres
tags: |
latest
16-alpine
images: ${{ env.REPOSITORY }}
labels: |
org.opencontainers.image.version=${{ env.BUILD_VERSION }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.title=${{ env.REPOSITORY }}
- name: Build Image
uses: docker/build-push-action@v6
with:
context: ./postgres
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILD_VERSION
labels: ${{ steps.docker_meta.outputs.labels }}
sbom: true
provenance: true
cache-from: type=gha, scope=${{ github.workflow }}
cache-to: type=gha, scope=${{ github.workflow }}
tags: |
ghcr.io/${{ env.REPOSITORY }}:${{ env.BUILD_VERSION }}
ghcr.io/${{ env.REPOSITORY }}:latest
4 changes: 4 additions & 0 deletions node/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*
!build.sh
!patch.sh
!patches
82 changes: 82 additions & 0 deletions node/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
FROM alpine:3.16.2 as builder

RUN apk update
RUN apk add make g++ python3 gnupg curl file flex patch rsync texinfo

ARG arch=
ENV BUILD_ARCH=$arch

COPY build.sh /

RUN curl -Lsq -o musl-cross-make.zip https://git.zv.io/toolchains/musl-cross-make/-/archive/ed72f5171e3d4a9e92026823cbfe93e795105763/musl-cross-make-ed72f5171e3d4a9e92026823cbfe93e795105763.zip \
&& unzip -q musl-cross-make.zip \
&& mv musl-cross-make-ed72f5171e3d4a9e92026823cbfe93e795105763 musl-cross-make \
&& $(/build.sh config_mak ${BUILD_ARCH:-""} /musl-cross-make/config.mak) \
&& cd /musl-cross-make \
&& make install -j$(getconf _NPROCESSORS_ONLN) V= \
&& rm -rf /musl-cross-make

ARG version=0.0.0
ENV NODE_VERSION=$version

# gpg keys listed at https://github.com/nodejs/node#release-keys
RUN for key in \
4ED778F539E3634C779C87C6D7062848A1AB005C \
141F07595B7B3FFE74309A937405533BE57C7D57 \
74F12602B6F1C4E913FAA37AD3A89613643B6201 \
DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \
CC68F5A3106FF448322E48ED27F5E38D5B0A215F \
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \
C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
108F52B48DB57BB0CC439B2997B01419BD92F80A \
A363A499291CBBC940DD62E41F10027AF002F8B0 \
; do \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \
done \
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz" \
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION.tar.xz\$" SHASUMS256.txt | sha256sum -c -

ADD patch.sh /
ADD patches /patches

RUN tar -xf "node-v$NODE_VERSION.tar.xz" \
&& cd "node-v$NODE_VERSION" \
&& /patch.sh ${BUILD_ARCH} ${NODE_VERSION} \
&& export TARGET=$(/build.sh target ${BUILD_ARCH:-""}) \
&& export CC=$TARGET-gcc \
&& export CXX=$TARGET-g++ \
&& export AR=$TARGET-ar \
&& export NM=$TARGET-nm \
&& export RANLIB=$TARGET-ranlib \
&& export LINK=$TARGET-g++ \
&& export CXXFLAGS="-O3 -ffunction-sections -fdata-sections" \
&& export LDFLAGS="-Wl,--gc-sections,--strip-all $(/build.sh ld_flags ${BUILD_ARCH:-""})" \
&& ln -snf libc.so /usr/local/$TARGET/lib/ld-musl-*.so.1 \
&& ln -snf /usr/local/$TARGET/lib/ld-musl-*.so.1 /lib \
&& ./configure \
--partly-static \
--with-intl=small-icu \
--without-inspector \
$(/build.sh node_config ${BUILD_ARCH:-""}) \
&& make -j$(getconf _NPROCESSORS_ONLN) V=

RUN echo 'node:x:1000:1000:Linux User,,,:/home/node:/bin/sh' > /tmp/passwd

FROM scratch

ARG version=0.0.0

LABEL org.opencontainers.image.source="https://github.com/astefanutti/scratch-node"

COPY --from=builder node-v$version/out/Release/node /bin/node
COPY --from=builder /lib/ld-musl-*.so.1 /lib/
COPY --from=builder /tmp/passwd /etc/passwd

USER node

ENTRYPOINT ["node"]
32 changes: 32 additions & 0 deletions node/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
PREFIX?=tgdrive
REPOSITORIES?= ghcr.io/$(PREFIX)
VERSION?=22.5.1

ARCHITECTURES=amd64 arm64v8

tag-images:
@for arch in $(ARCHITECTURES); do docker tag $(PREFIX)/scratch-node:${VERSION}-$${arch} $(PREFIX)/scratch-node:${TAG}-$${arch}; done

move-images:
@for repo in $(REPOSITORIES); do \
for arch in $(ARCHITECTURES); do \
docker tag $(PREFIX)/scratch-node:${VERSION}-$${arch} $${repo}/scratch-node:${VERSION}-$${arch}; \
done \
done

build-images:
@for arch in $(ARCHITECTURES); do docker build --progress=auto --build-arg version=${VERSION} --build-arg arch=$${arch} -t $(PREFIX)/scratch-node:${VERSION}-$${arch} .; done

push-images:
@for arch in $(ARCHITECTURES); do docker push $(PREFIX)/scratch-node:${VERSION}-$${arch}; done

create-manifest: push-images
docker manifest create --amend $(PREFIX)/scratch-node:$(VERSION) $(shell echo $(ARCHITECTURES) | sed -e "s~[^ ]*~$(PREFIX)/scratch-node:$(VERSION)\-&~g")
docker manifest annotate --os linux --arch amd64 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-amd64
# TODO: set the CPU features as soon as the CLI exposes a --features option
docker manifest annotate --os linux --arch arm --variant v6 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm32v6
docker manifest annotate --os linux --arch arm --variant v7 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm32v7
docker manifest annotate --os linux --arch arm64 --variant v8 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm64v8

push-manifest: create-manifest
docker manifest push --purge $(PREFIX)/scratch-node:${VERSION}
Loading

0 comments on commit 1092285

Please sign in to comment.