diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3eb9d4e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml new file mode 100644 index 0000000..7bd2591 --- /dev/null +++ b/.github/workflows/build-push.yml @@ -0,0 +1,17 @@ +name: Build and push + +permissions: + contents: read + packages: write + +on: + push: + branches: + - main + schedule: + - cron: '30 2 * * SUN' + +jobs: + build-and-push: + uses: ./.github/workflows/docker.yml + secrets: inherit diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..ac51988 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,12 @@ +name: Checks + +permissions: + contents: read + +on: + pull_request: + +jobs: + build: + uses: ./.github/workflows/docker.yml + secrets: inherit diff --git a/.github/workflows/container-cleanup.yml b/.github/workflows/container-cleanup.yml new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml new file mode 100644 index 0000000..9bed577 --- /dev/null +++ b/.github/workflows/docker-images.yml @@ -0,0 +1,57 @@ +name: Docker + +on: + workflow_call: + inputs: + node_version: + type: string + latest: + type: boolean + lts: + type: boolean + debian_version: + type: string + postgresql_version: + type: string + +jobs: + base: + uses: "tweedegolf/actions-container-helpers/.github/workflows/container-image.yml@main" + with: + push: ${{ github.ref == 'refs/heads/main' }} + platforms: "linux/amd64,linux/arm64" + build-args: | + DEBIAN_VERSION=${{ inputs.debian_version }} + NODE_VERSION=${{ inputs.node_version }} + POSTGRESQL_VERSION=${{ inputs.postgresql_version }} + tags: | + ghcr.io/tweedegolf/node:${{inputs.node_version}} + ${{ inputs.latest && 'ghcr.io/tweedegolf/node:latest' || '' }} + ${{ inputs.lts && 'ghcr.io/tweedegolf/node:lts' || '' }} + extended: + uses: "tweedegolf/actions-container-helpers/.github/workflows/container-image.yml@main" + with: + file: Dockerfile-extended + push: ${{ github.ref == 'refs/heads/main' }} + platforms: "linux/amd64,linux/arm64" + build-args: | + DEBIAN_VERSION=${{ inputs.debian_version }} + NODE_VERSION=${{ inputs.node_version }} + tags: | + ghcr.io/tweedegolf/node:${{inputs.node_version}}-extended + ${{ inputs.latest && 'ghcr.io/tweedegolf/node:latest-extended' || '' }} + ${{ inputs.lts && 'ghcr.io/tweedegolf/node:lts-extended' || '' }} + + full: + uses: "tweedegolf/actions-container-helpers/.github/workflows/container-image.yml@main" + with: + file: Dockerfile-full + push: ${{ github.ref == 'refs/heads/main' }} + platforms: "linux/amd64,linux/arm64" + build-args: | + DEBIAN_VERSION=${{ inputs.debian_version }} + NODE_VERSION=${{ inputs.node_version }} + tags: | + ghcr.io/tweedegolf/node:${{inputs.node_version}}-full + ${{ inputs.latest && 'ghcr.io/tweedegolf/node:latest-full' || '' }} + ${{ inputs.lts && 'ghcr.io/tweedegolf/node:lts-full' || '' }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..ba3f225 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,23 @@ +name: Docker + +on: + workflow_call: + +jobs: + build: + strategy: + matrix: + include: + - node_version: 20 + latest: true + lts: true + - node_version: 18 + latest: false + lts: false + uses: "./.github/workflows/docker-images.yml" + with: + node_version: ${{ matrix.node_version }} + latest: ${{ matrix.latest }} + lts: ${{ matrix.lts }} + debian_version: bookworm + postgresql_version: "16" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..182b992 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +ARG DEBIAN_VERSION +FROM ghcr.io/tweedegolf/debian:${DEBIAN_VERSION} +ARG DEBIAN_VERSION + +# Add additional build tools for node.js (and node-gyp) +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential \ + pkg-config \ + python3 \ + && rm -rf /var/lib/apt/lists/* + +# Install node.js +ARG NODE_VERSION +ENV NODE_VERSION ${NODE_VERSION} +RUN curl -s -L https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource.gpg \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Install yarn +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + yarn \ + && rm -rf /var/lib/apt/lists/* + +# Install postgresql client +ARG POSTGRESQL_VERSION +ENV POSTGRESQL_VERSION ${POSTGRESQL_VERSION} +RUN curl -s -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ + && echo "deb http://apt.postgresql.org/pub/repos/apt/ $DEBIAN_VERSION-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + postgresql-client-$POSTGRESQL_VERSION \ + && rm -rf /var/lib/apt/lists/* diff --git a/Dockerfile-extended b/Dockerfile-extended new file mode 100644 index 0000000..e3d2221 --- /dev/null +++ b/Dockerfile-extended @@ -0,0 +1,51 @@ +ARG NODE_VERSION +FROM ghcr.io/tweedegolf/node:${NODE_VERSION} + +# Install dependencies for extended install +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ghostscript \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv \ + gconf-service \ + libasound2 \ + libatk1.0-0 \ + libc6 \ + libcairo2 \ + libcups2 \ + libdbus-1-3 \ + libexpat1 \ + libfontconfig1 \ + libgbm-dev \ + libgcc1 \ + libgconf-2-4 \ + libgdk-pixbuf2.0-0 \ + libglib2.0-0 \ + libgtk-3-0 \ + libnspr4 \ + libpango-1.0-0 \ + libpangocairo-1.0-0 \ + libstdc++6 \ + libx11-6 \ + libx11-xcb1 \ + libxcb1 \ + libxcomposite1 \ + libxcursor1 \ + libxdamage1 \ + libxext6 \ + libxfixes3 \ + libxi6 \ + libxrandr2 \ + libxrender1 \ + libxshmfence-dev \ + libxss1 \ + libxtst6 \ + fonts-liberation \ + fonts-freefont-ttf \ + libayatana-appindicator1 \ + libnss3 \ + xdg-utils \ + libdrm2 \ + && rm -rf /var/lib/apt/lists/* diff --git a/Dockerfile-full b/Dockerfile-full new file mode 100644 index 0000000..b3d9693 --- /dev/null +++ b/Dockerfile-full @@ -0,0 +1,19 @@ +ARG NODE_VERSION +FROM ghcr.io/tweedegolf/node:${NODE_VERSION}-extended + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + chromium \ + firefox-esr \ + x11-utils \ + xvfb \ + dbus \ + udev \ + fluxbox \ + procps \ + tzdata \ + libosmesa6 \ + libglapi-mesa \ + libgl1-mesa-dri \ + mesa-utils \ + && rm -rf /var/lib/apt/lists/* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..90a987f --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# Node.js Docker images +This image contains Node.js, yarn and a postgresql client and basic build +tools. For yarn we use the 1.0 version distributed from their apt repository. +Currently these tags are available: + +* Node.js 18: `18` +* Node.js 20: `20`, `lts`, `latest` + +All versions contain node.js at the specified version, npm and yarn. They also +include the postgresql client applications (e.g. psql and others) and include +basic build tools allowing you to build C/C++ node.js extensions as well. + +## Extended images +You can also use the extended images (with the postfix `-extended`). These +variants include dependencies for running browsers such as for usage with +puppeteer. + +## Full images +A larger variant still is also available (with the postfix `-full`). These +images include preinstalled firefox and chromium browsers, making them suitable +for end-to-end testing. + +## Usage +For basic usage instructions, also see our [debian image] detailed usage +instructions. Basic usage when using docker compose is shown below: + +```yaml +services: + # ... + app: + image: ghcr.io/tweedegolf/node:lts + user: "$USER_ID:$GROUP_ID" + command: [npm, run, server] + volumes: [".:/app"] + working_dir: /app + # ... +``` + +## Extending for production +When running this image in a production setting, you should set up a few things: + +* Create a user that your application will run under +* Make sure that user will be the default user +* Set the `ROOT_SWITCH_USER` environment variable to your user as well to + prevent the application accidentally running as root +* Copy the full appllication and its dependencies into the image +* Set a command that will run the application + +See for example the Dockerfile below: + +```Dockerfile +FROM ghcr.io/tweedegolf/node:lts +RUN useradd -C Application -m -U app +ENV ROOT_SWITCH_USER app +ENV NODE_ENV production +COPY --chown=app:app ./build /opt/application +WORKDIR /opt/application +CMD ["node", "index.js"] +USER app +``` + +[debian image]: https://github.com/tweedegolf/docker-debian-image