diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 95c66b1..e6ceb7f 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -7,6 +7,7 @@ on: push env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} + VOLUMING_IMAGE_NAME: ${{ github.repository }}-voluming # There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. jobs: @@ -16,7 +17,7 @@ jobs: permissions: contents: read packages: write - # + # steps: - name: Checkout repository uses: actions/checkout@v4 @@ -44,3 +45,16 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + - name: Extract metadata (tags, labels) for Docker (Voluming Image) + id: meta-voluming + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.VOLUMING_IMAGE_NAME }} + - name: Build and push Docker image (Voluming Image) + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: voluming.Dockerfile + push: true + tags: ${{ steps.meta-voluming.outputs.tags }} + labels: ${{ steps.meta-voluming.outputs.labels }} diff --git a/.gitignore b/.gitignore index c25c660..81ba957 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules fly.toml +dist diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..165c038 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +services: + voluming-example: + build: + context: . + dockerfile: voluming.Dockerfile + volumes: + - ./src:/app/src + - ./package.json:/app/package.json + - ./package-lock.json:/app/package-lock.json + - ./tsconfig.json:/app/tsconfig.json + - cache-volume:/cache + +volumes: + cache-volume: {} diff --git a/src/index.ts b/src/index.ts index 79bef20..98988c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,11 @@ process.on('SIGINT', () => { process.exit(0); }); +process.on('SIGTERM', () => { + server.log.info("terminated"); + process.exit(0); +}); + const start = async () => { try { await server.listen({port: port, host: "0.0.0.0"}); diff --git a/voluming-start.sh b/voluming-start.sh new file mode 100755 index 0000000..17b89db --- /dev/null +++ b/voluming-start.sh @@ -0,0 +1,58 @@ +#!/bin/sh +set -eu -o pipefail + +cd /app + +create_cache_symlink () { + local SOURCE="$1" + local CACHE_BASE_DIR="$2" + local CACHE_DEST="$2/$(basename $1)" + + # If the cache already exists, discard whatever's already + # there are use the cache + if [ -d "$CACHE_DEST" ] + then + rm -rf "$SOURCE" + echo "Cache exists in $CACHE_DEST, replacing $SOURCE" + fi + + # If there's something already there (and the cache does not exist) + # move it into the cache + if [ -d "$SOURCE" ] + then + mv -f "$SOURCE" "$CACHE_BASE_DIR" + echo "Prepopulating cache $CACHE_DEST from $SOURCE" + fi + + if [ ! -d "$CACHE_DEST" ] + then + mkdir -p "$CACHE_DEST" + fi + + ln -s "$CACHE_DEST" "$SOURCE" + echo "Linked $SOURCE to cache $CACHE_DEST" +} + +if [ -d "/cache" ] # If a caching volume has been mounted, use the cache +then + create_cache_symlink "/root/.npm" "/cache" + + # npm deletes any node_modules symlink (see https://github.com/npm/arborist/security/advisories/GHSA-gmw6-94gg-2rc2) + # so we will detect if the cache has already been populated, and if + # not we will install packages, then create the cache afterwards. + # If the cache has been populated, we will just use it, and not run npm + # so that it will not erase our symlink + if [ ! -d "/cache/node_modules" ] + then + npm ci + fi + create_cache_symlink "/app/node_modules" "/cache" +else + npm ci +fi + +# Can't use npm scripts here because npm doesn't handle SIGTERM properly. +# Using exec, becaus it replaces the shell process with the node process +# so that it receives the SIGTERM signal properly. Otherwise the shell just +# eats the signal. +exec ./node_modules/.bin/ts-node --transpileOnly ./src/index.ts diff --git a/voluming.Dockerfile b/voluming.Dockerfile new file mode 100644 index 0000000..38543d3 --- /dev/null +++ b/voluming.Dockerfile @@ -0,0 +1,10 @@ +FROM node:18-alpine AS base + +WORKDIR /app + +RUN rm -rf /root/.npm + +EXPOSE 8100 + +COPY ./voluming-start.sh /voluming-start.sh +CMD [ "sh", "/voluming-start.sh" ]