How to Use TypeScript & Docker to Build a REST Service with Debugging

IT Training

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

How to Use TypeScript & Docker to Build a REST Service with Debugging

TypeScript and Docker are a powerful combination for building reliable, maintainable REST services. TypeScript brings static typing and modern JavaScript features to your Node.js backend, while Docker ensures your service runs consistently across development, staging, and production environments. This guide explains how to wire the two together, including setting up remote debugging from IDEs such as WebStorm and Visual Studio Code.

Why Combine TypeScript and Docker for REST Services?

Running a TypeScript REST service inside Docker solves several common DevOps pain points:

  • Reproducible builds: The TypeScript compilation step is baked into the Docker image, so every environment uses exactly the same compiled output.
  • Dependency isolation: Node modules are installed inside the container, eliminating “works on my machine” problems caused by differing local node_modules trees.
  • Type safety at build time: TypeScript catches type errors during the Docker build step, preventing broken images from being deployed.
  • Scalability: Containerised services are straightforward to orchestrate with Docker Compose, Kubernetes, or any container platform.

Project Structure

A typical TypeScript REST service prepared for Docker looks like this:

my-rest-service/
├── src/
│   ├── index.ts          # Entry point
│   └── routes/
│       └── health.ts     # Example route
├── dist/                 # Compiled JS output (generated)
├── tsconfig.json
├── package.json
├── Dockerfile
└── docker-compose.ymlCode language: PHP (php)

TypeScript Configuration

A minimal tsconfig.json suitable for a Node.js REST service:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "sourceMap": true
  },
  "include": ["src"]
}Code language: JSON / JSON with Comments (json)

Setting "sourceMap": true is essential for debugging inside Docker — it allows the debugger to map minified or compiled JavaScript back to the original TypeScript source files.

Writing a Simple REST Entry Point

The following example uses Express, one of the most common Node.js HTTP frameworks:

// src/index.ts
import express, { Request, Response } from 'express';

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

app.use(express.json());

app.get('/health', (_req: Request, res: Response) => {
  res.json({ status: 'ok' });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});Code language: JavaScript (javascript)

Dockerfile

A multi-stage Dockerfile keeps the final image small by discarding the TypeScript compiler and development dependencies before producing the production image:

# Stage 1 – build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src ./src
RUN npm run build

# Stage 2 – production image
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]Code language: PHP (php)

Ensure your package.json includes a build script that invokes the TypeScript compiler:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts"
  }
}Code language: JSON / JSON with Comments (json)

Docker Compose for Local Development

During development you typically want live reloading and a debug port exposed. A docker-compose.yml configured for this looks like:

version: '3.8'
services:
  api:
    build:
      context: .
      target: builder          # Use the build stage so devDeps are available
    volumes:
      - ./src:/app/src         # Mount source for live edits
    ports:
      - "3000:3000"            # HTTP
      - "9229:9229"            # Node.js inspector (debugger)
    command: node --inspect=0.0.0.0:9229 dist/index.js
    environment:
      - NODE_ENV=developmentCode language: PHP (php)

Port 9229 is the standard Node.js V8 inspector port. Exposing it from the container is all that is needed to attach a remote debugger.

Enabling Debugging in WebStorm

To attach WebStorm to a running container:

  1. Go to Run → Edit Configurations and add a new Node.js Remote Debug configuration.
  2. Set Host to localhost and Port to 9229.
  3. In the Path mappings section, map your local src/ directory to /app/src inside the container.
  4. Start the container with docker compose up, then click the debug button in WebStorm.

Enabling Debugging in Visual Studio Code

Add the following configuration to your .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Docker",
      "address": "localhost",
      "port": 9229,
      "localRoot": "${workspaceFolder}/src",
      "remoteRoot": "/app/src",
      "sourceMaps": true,
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}Code language: JSON / JSON with Comments (json)

With the container running, press F5 in VSCode to attach. Breakpoints set in your .ts source files will be hit correctly because source maps are enabled.

Useful Boilerplate

If you want a ready-made starting point, the npm package boilerplate-typescript-rest-docker (source: npmjs.com) provides a pre-configured project scaffold covering TypeScript compilation, Docker setup, and debug configuration for both WebStorm and VSCode. Review its README for version-specific instructions before adopting it in a production project.

Key Takeaways

  • Use a multi-stage Dockerfile to separate build-time and runtime dependencies.
  • Enable sourceMap: true in tsconfig.json so debuggers can map compiled JS back to TypeScript.
  • Expose port 9229 and start Node with --inspect=0.0.0.0:9229 for remote debugging.
  • Configure path mappings in your IDE to point from local source files to the container filesystem.
  • Docker Compose makes it easy to manage the development container lifecycle alongside other services such as databases or caches.
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x