Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changesets

This repo is a starter template (not published to npm). [Changesets](https://github.com/changesets/changesets) versions the template, updates `CHANGELOG.md`, and creates GitHub Releases.

## Workflow

1. On a feature branch, record a changeset:

```sh
pnpm changeset
```

2. Open a PR. Merge as usual.

3. On `main`, the Release workflow opens or updates a **Version Packages** PR that bumps `package.json` and the changelog.

4. Merge **Version Packages**. The workflow tags the release and creates a GitHub Release (no npm publish).

## Scripts

| Script | Purpose |
| --- | --- |
| `pnpm changeset` | Create a changeset |
| `pnpm version-packages` | Apply changesets locally (`changeset version`) |
| `pnpm release` | Tag the current version for GitHub Releases |
15 changes: 15 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": {
"version": true,
"tag": true
}
}
5 changes: 5 additions & 0 deletions .changeset/security-upgrade-pnpm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"template-node-fastify": minor
---

Upgrade to Fastify 5, modern OpenTelemetry, and pnpm; clear dependency security advisories.
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on:
pull_request:
push:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
name: Build and test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build
run: pnpm build

- name: Test
run: pnpm test

- name: Audit
run: pnpm audit
43 changes: 43 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Release

on:
push:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
contents: write
pull-requests: write

jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Create release PR or GitHub release
id: changesets
uses: changesets/action@v1
with:
title: Version Packages
commit: Version Packages
publish: pnpm release
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node-linker=hoisted
29 changes: 17 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
FROM node as builder
FROM node:22 AS builder

WORKDIR /usr/src/app

COPY package.json yarn.lock ./
RUN corepack enable

RUN yarn install --frozen-lockfile
COPY package.json pnpm-lock.yaml .npmrc ./

COPY . .
RUN pnpm install --frozen-lockfile

RUN yarn build
COPY . .

FROM node:slim
RUN pnpm build

ENV NODE_ENV production
USER node
FROM node:22-slim

WORKDIR /usr/src/app

COPY package.json yarn.lock ./
RUN corepack enable

RUN yarn install --production --frozen-lockfile
COPY package.json pnpm-lock.yaml .npmrc ./

COPY --from=builder /usr/src/app/dist ./dist
RUN pnpm install --prod --frozen-lockfile \
&& chown -R node:node /usr/src/app

COPY --from=builder --chown=node:node /usr/src/app/dist ./dist

USER node

ENV PORT 3000
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE $PORT

CMD [ "node", "dist/index.js" ]
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ git clone https://github.com/dillonstreator/template-node-fastify

cd template-node-fastify

yarn install
pnpm install

yarn dev
pnpm dev
```

## Configuration
Expand All @@ -39,4 +39,8 @@ Open Telemetry is disabled by default but can be enabled by setting the `OTEL_EN

By default, the trace exporter is set to standard output. This can be overridden by setting `OTEL_EXPORTER_OTLP_ENDPOINT`.

Start the `jaegertracing/all-in-one` container with `docker-compose up` and set `OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318` to collect logs in jaeger. Docker compose will expose jaeger at http://localhost:16686
Start the `jaegertracing/all-in-one` container with `docker-compose up` and set `OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318` to collect logs in jaeger. Docker compose will expose jaeger at http://localhost:16686

## Releasing

This template is versioned with [Changesets](https://github.com/changesets/changesets) (GitHub Releases only — not published to npm). See [`.changeset/README.md`](./.changeset/README.md).
120 changes: 76 additions & 44 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,76 @@
{
"name": "template-node-fastify",
"version": "1.0.0",
"main": "dist/index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"test": "tap --reporter=list",
"test:help": "tap --help"
},
"devDependencies": {
"@babel/core": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"@babel/preset-typescript": "^7.23.3",
"@types/jest": "^29.5.8",
"@types/node": "^20.9.2",
"@types/supertest": "^2.0.16",
"nodemon": "^3.0.1",
"tap": "^18.7.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"undici": "^6.21.1"
},
"dependencies": {
"@fastify/compress": "^7.0.0",
"@fastify/helmet": "^11.1.1",
"@fastify/swagger": "^8.14.0",
"@fastify/swagger-ui": "^2.1.0",
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/auto-instrumentations-node": "^0.40.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.45.1",
"@opentelemetry/resources": "^1.18.1",
"@opentelemetry/sdk-node": "^0.45.1",
"@opentelemetry/sdk-trace-base": "^1.18.1",
"@opentelemetry/semantic-conventions": "^1.18.1",
"fastify": "^4.26.0",
"fastify-type-provider-zod": "^1.1.9",
"http-graceful-shutdown": "^3.1.13",
"pino": "^8.16.2",
"zod": "^3.22.4"
}
}
{
"name": "template-node-fastify",
"version": "1.0.0",
"private": true,
"main": "dist/index.js",
"license": "MIT",
"packageManager": "pnpm@10.12.4",
"engines": {
"node": ">=20"
},
"scripts": {
"dev": "nodemon src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"test": "tap --reporter=base --allow-incomplete-coverage",
"test:help": "tap --help",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "changeset publish"
},
"devDependencies": {
"@babel/core": "^7.29.6",
"@babel/preset-env": "^7.29.6",
"@babel/preset-typescript": "^7.28.5",
"@changesets/cli": "^2.31.1",
"@types/node": "^22.15.30",
"nodemon": "^3.1.10",
"tap": "^21.1.0",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"undici": "^6.27.0"
},
"dependencies": {
"@fastify/compress": "^8.0.1",
"@fastify/helmet": "^13.0.1",
"@fastify/swagger": "^9.5.1",
"@fastify/swagger-ui": "^5.2.2",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.78.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.220.0",
"@opentelemetry/resources": "^2.9.0",
"@opentelemetry/sdk-node": "^0.220.0",
"@opentelemetry/sdk-trace-base": "^2.9.0",
"@opentelemetry/semantic-conventions": "^1.43.0",
"fastify": "^5.8.3",
"fastify-type-provider-zod": "^4.0.2",
"http-graceful-shutdown": "^3.1.16",
"pino": "^9.7.0",
"zod": "^3.25.76"
},
"pnpm": {
"overrides": {
"protobufjs": "^7.6.3",
"@grpc/grpc-js": "^1.13.4",
"fast-uri": "^3.1.2",
"lodash": "^4.18.1",
"minimatch@<3.1.3": "3.1.3",
"minimatch@>=5.0.0 <5.1.8": "5.1.8",
"minimatch@>=9.0.0 <9.0.7": "9.0.7",
"tar": "^7.5.16",
"brace-expansion@>=2.0.0 <2.0.3": "2.0.3",
"picomatch@^2": "2.3.2",
"yaml": "^2.8.3",
"ajv@>=8": "8.18.0",
"cookie": "^0.7.2",
"prismjs": "^1.30.0",
"glob@>=10 <10.5.0": "10.5.0",
"uuid@<11.1.1": "11.1.1",
"joi": "^17.13.3",
"sigstore": "^4.1.1",
"@sigstore/core": "^3.2.1",
"@opentelemetry/core": "^2.8.0",
"ws": "^8.21.0"
}
}
}
Loading
Loading