Standard Node deployments copy devDependencies (like TypeScript compilers) directly into production containers, leading to bloated, insecure images. The diagram below details a multi-stage Docker build pipeline. Stage 1 (Builder) installs all modules and compiles the TypeScript code into vanilla JavaScript. Stage 2 (Runner) copies only the compiled JS and installs production dependencies, minimizing the final image size and reducing security risks.
2. Part 1: Step-by-Step Backend Project Initialization & Commands
Follow these detailed steps to build the TypeScript backend scaffold, configure your tsconfig file, write the server code, and containerize the environment.
STEP 1
Launch VM Terminal and Create Backend Workspace
Boot up your VirtualBox Ubuntu machine. Open the terminal (Ctrl+Alt+T) and create a directory to organize your backend files.
ubuntu@iot-vm:~$ mkdir -p ~/workspace/backend_scaffold && cd ~/workspace/backend_scaffold
We run `mkdir -p` and `cd` to generate and enter a dedicated workspace directory named `~/workspace/backend_scaffold` to isolate our backend scaffold configuration files.
STEP 2
Initialize Node.js Project
Create a package configuration file using default settings.
We install the runtime dependency `express` along with the development dependencies `typescript`, `ts-node`, and type definition files to compile and run the backend.
STEP 4
Generate TypeScript Compiler Configuration File
Initialize the default tsconfig file, which defines the compiler settings.
We run `tsc --init` to generate a default TypeScript compiler configuration file (`tsconfig.json`), which we will configure to output build artifacts to a dedicated directory.
STEP 5
Configure Compiler Directories in tsconfig.json
Open `tsconfig.json` and configure the output and source root directories.
Settings to update (gedit tsconfig.json):
1. Locate line '"target": "es2016"'. Verify it is active.
2. Locate and uncomment '"outDir": "./dist"'. This defines the target directory for compiled JS code.
3. Locate and uncomment '"rootDir": "./src"'. This defines the directory containing your source code.
4. Save and exit the editor.
We configure output and root directories in `tsconfig.json` to instruct the compiler to output compiled JS files to `/dist` and compile source files from `/src`.
STEP 6
Create the Server Entry File
Open the graphical text editor in a background thread to write the Express server code.
We create `docker-compose.yml` to define port forwarding rules and environment variables for the service.
STEP 9
Build and Launch the Containerized Service
Build and start the containerized service using Docker Compose. The terminal will output compilation logs as the container starts.
ubuntu@iot-vm:~/workspace/backend_scaffold$ sudo docker-compose up --build
We run `docker-compose up --build` as root to build the container images and launch the services defined in the compose file.
3. Web Service Port Forwarding Model
The diagram below illustrates the port forwarding paths, mapping incoming requests from the host OS browser to the containerized Express backend.
4. Part 2: Complete Codebases & Container Configurations
Below is the complete C++ firmware code showing how abstract inheritance interfaces work, followed by the complete Python script to listen to the serial port and print the data.
Asset 1: TypeScript Express Server File (`src/index.ts`)
Line-by-Line Code Breakdown
import express, { Request, Response } from 'express';: Imports express alongside standard TS type interfaces.
const app = express();: Instantiates the Express application.
app.get('/health', ...): Configures a health-check endpoint on the route `/health`.
res.json({ status: 'online' }): Returns a JSON status payload to confirm the server is running.
app.listen(port, ...): Starts the server, listening on the configured port.