Category Archives: node.js

A simple web API in various languages and deployable to Kubernetes (Node/Typescript)

Continuing this short series of writing a simple echo service web API along with the docker and k8s requirements, we’re now going to turn our attention to a Node implementation.

Add the file app.ts to the /src folder with the following content

import express, { Request, Response } from 'express';
import bodyParser from 'body-parser';

const app = express();
const PORT = process.env.PORT || 8080;

app.use(bodyParser.json());


app.get('/echo', (req: Request, res: Response) => {
  const queryParams = req.query;
  res.type('text/plain');
  res.send(`Node Echo: ${queryParams.text}`);
});

app.get('/livez', (_req: Request, res: Response) => {
  res.sendStatus(200);
});

app.get('/readyz', async (_req: Request, res: Response) => {
  try {
    res.sendStatus(200);
  } catch (err) {
    res.status(503).send('Service not ready');
  }
});

app.listen(PORT, () => {
  console.log(`Echo service is live at http://localhost:${PORT}`);
});

Dockerfile

Next up we need to create our Dockerfile

FROM node:24-alpine

WORKDIR /app

COPY package.json package-lock.json* tsconfig.json ./

RUN npm install

COPY src ./src

#RUN npx tsc

EXPOSE 8080

CMD ["npx", "ts-node", "src/app.ts"]

Note: In Linux port 80 might be locked down, hence we use port 8080 by default.

To build this, run

docker build -t putridparrot.echo_service:v1 .

Don’t forget to change the name to your preferred name.

and to test this, run

docker run -p 8080:8080 putridparrot.echo_service:v1

Kubernetes

If all wen well we’ve not tested our application and see it working from a docker image, so now we need to create the deployment etc. for Kubernete’s. Let’s assume you’ve pushed you image to Docker or another container registry such as Azure – I’m call my container registry putridparrotreg.

I’m also not going to use helm at this point as I just want a (relatively) simple yaml file to run from kubectl, so create a deployment.yaml file, we’ll store all the configurations, deployment, service and ingress in this one file jus for simplicity.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
  namespace: dev
  labels:
    app: echo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: putridparrotreg/putridparrot.echo_service:v1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "100Mi"
            cpu: "100m"
          limits:
            memory: "200Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /livez
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /readyz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: echo_service
  namespace: dev
  labels:
    app: echo
spec:
  type: ClusterIP
  selector:
    app: echo 
  ports:
  - name: http
    port: 80
    targetPort: 8080
    protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  namespace: dev
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: mydomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: echo_service
            port:
              number: 80

Don’t forget to change the “host” and image to suit, also this assume you created a namespace “dev” for your app. See Creating a local container registry for information on setting up your own container registry.

Cannot GET / in Angular

I was playing with the quick start tutorial from Angular’s setup page on their web site.

Using the file/folder layout on their THE HERO EDITOR I removed all folders/files not listed in their diagram.

For completeness I’ll duplicate the information here

angular-tour-of-heroes
|—src
|—|—app
|—|—|—app.component.ts
|—|—|—app.module.ts
|—|—index.html
|—|—main.ts
|—|—styles.css
|—|—systemjs.config.js
|—|—tsconfig.json
|—node_modules …
|—package.json

I then ran npm start from the command prompt in the root angular-tour-of-heroes and up pops the browser with Cannot GET /, looking at the output from npm I could see index.html was not found by npm.

I also noticed npm couldn’t find a file bs-config.json, so I located that from the quick start and placed it in the root angular-tour-of-heroes folder and all worked correctly, no more 404.

Here’s why, the bs-confog.json gives the baseDir of the “website”, here’s the file context

{
  "server": {
    "baseDir": "src",
    "routes": {
      "/node_modules": "node_modules"
    }
  }
}