Skip to main content

Create a Node.js Service

This guide walks you through creating a production-ready Node.js microservice from zero using the Golden Path template โ€” from an empty repository to a fully cataloged, CI-enabled service in under 5 minutes.

Prerequisitesโ€‹

  • ForgePortal is running (local or deployed) โ€” see Quick Start
  • A GitHub (or GitLab) token is configured with repo scope โ€” see SCM Providers
  • Your ForgePortal role is developer or higher โ€” see Role Guide

Step 1 โ€” Open the Templateโ€‹

  1. Click Templates in the top navigation bar.
  2. Find the Node.js Service card (it has tags: nodejs, typescript).
  3. Click "Create โ†’".

You are taken to the template form.


Step 2 โ€” Fill the Wizardโ€‹

Fill in each field:

FieldExampleNotes
Service namepayment-serviceLowercase, hyphen-separated. Becomes the repo name and catalog entity name.
DescriptionHandles payments and invoicingShown in the catalog.
Ownerteam-platformUsed in entity.yaml.
LifecycleexperimentalPromote to production when ready.
GitHub Orgmy-github-orgThe org (or user) where the repo will be created.
VisibilityprivateUse public for open-source projects.
tip

All fields with a * are required. Optional fields show a lighter label. You can leave them blank and update the entity.yaml later.

Click "Create Service" to start the run.


Step 3 โ€” Watch the Runโ€‹

You are redirected to the run progress page (/templates/runs/:id). You see each step execute in order:

StepWhat happens
scm.createRepoNew repo payment-service is created in your org
scm.pushFilesScaffolded files are committed to a feat/scaffold branch
scm.openPullRequestPR opened: "chore: initial scaffold"
catalog.registerEntityentity.yaml committed ยท entity visible in the catalog

Each step shows a status indicator (โณ queued โ†’ ๐Ÿ”„ running โ†’ โœ… success). If a step fails, you see the error message and a hint.

When the run completes, you see links to:

  • Repository URL โ€” the new repo on GitHub/GitLab
  • Pull Request URL โ€” the scaffold PR ready for review
Run takes 10โ€“30 seconds

The SCM API calls are synchronous. If your token doesn't have repo write scope, step 1 fails with a 403 error. See SCM Providers to fix the token.


Step 4 โ€” Review and Merge the PRโ€‹

Open the PR URL from the run outputs. You see:

feat/scaffold โ†’ main

Files added:
package.json
tsconfig.json
src/index.ts
Dockerfile
.github/workflows/ci.yml
README.md
entity.yaml

Review the files. When satisfied, merge the PR.

Look at entity.yaml first

The entity.yaml file is the most important โ€” it defines how the service appears in the catalog. Check the owner, lifecycle, and description match your expectations.


Step 5 โ€” See the Entity in the Catalogโ€‹

  1. Click Catalog in the top navigation.
  2. Search for payment-service or filter by kind service.
  3. Click the entity to open its detail page.

You see:

  • Overview tab โ€” description, owner, lifecycle, tags, links
  • Scorecards tab โ€” initial evaluation (Bronze should pass immediately with owner set)
  • Docs tab โ€” content of the README.md rendered as documentation

Step 6 โ€” Check the Scorecardโ€‹

On the entity detail page, click Scorecards.

The default scorecard evaluates:

RuleLevelExpected
Owner is setBronzeโœ… pass (you set it in the form)
README existsBronzeโœ… pass (generated by template)
CI workflow existsSilverโœ… pass (generated by template)
Dockerfile existsSilverโœ… pass (generated by template)
Security scanning configuredGoldโณ pending โ€” needs Snyk/SonarCloud

Your service starts at Bronze / Silver. To reach Gold, configure Snyk or SonarCloud and add their annotations to entity.yaml.


What Was Generatedโ€‹

src/index.tsโ€‹

import Fastify from 'fastify';

const app = Fastify({ logger: true });

app.get('/health', async () => ({ status: 'ok' }));

app.listen({ port: 3000, host: '0.0.0.0' }, (err) => {
if (err) { app.log.error(err); process.exit(1); }
});

Dockerfileโ€‹

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

entity.yamlโ€‹

apiVersion: forgeportal/v1
kind: service
metadata:
name: payment-service
namespace: default
description: Handles payments and invoicing
tags:
- nodejs
- typescript
spec:
owner: team-platform
lifecycle: experimental

Next Stepsโ€‹

Now that your service is in the catalog, you can:

  • Add a database โ€” Run the Create Database template and reference it in your entity.yaml with spec.dependsOn: ["resource:orders-db"]
  • Enable the Kubernetes plugin โ€” Add the annotation forgeportal.dev/kubernetes-label-selector: app=payment-service to your entity.yaml
  • Enable GitHub Insights โ€” Automatic โ€” the plugin reads commits/PRs from your repo via the GitHub token
  • Push to Gold โ€” Add Snyk (forgeportal.dev/snyk-org: my-org) and re-evaluate the scorecard

For a full end-to-end walkthrough of all three golden paths in sequence, see Golden Paths Overview.