The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included

A Comprehensive Overview of a Node.js TypeScript Project with DevOps: Structure, Code, and Configuration

Explore the essential components of building a robust Node.js TypeScript project integrated with DevOps practices. This guide provides a detailed…


This content originally appeared on DEV Community and was authored by Omor Faruk

Image description
A Comprehensive Overview of a Node.js TypeScript Project with DevOps: Structure, Code, and Configuration

Explore the essential components of building a robust Node.js TypeScript project integrated with DevOps practices. This guide provides a detailed breakdown of the project structure, complete with code snippets and configurations for each file and directory, empowering you to streamline development, testing, and deployment processes effectively. Whether you're a beginner or an experienced developer, this comprehensive overview will enhance your understanding of creating scalable applications in a modern development environment.

Project Structure

πŸ“ node-typescript-project-with-devops/
β”œβ”€β”€ πŸ“ node_modules           # Node.js modules
β”œβ”€β”€ πŸ“„ .gitignore             # Specifies files and directories to be ignored by Git
β”œβ”€β”€ πŸ“„ .dockerignore          # Specifies files and directories to be ignored by Docker
β”œβ”€β”€ πŸ“„ .env                   # Environment variables file
β”œβ”€β”€ πŸ“„ example.env            # Example environment variables file
β”œβ”€β”€ πŸ“ uploads                # Folder for uploaded files
β”‚   └── ...
β”œβ”€β”€ πŸ“ src
β”‚   β”œβ”€β”€ πŸ“„ server.ts          # Main entry point for the application
β”‚   β”œβ”€β”€ πŸ“ bin                # Contains binaries or executable files
β”‚   β”‚   └── πŸ“„ www            # Start script for the server
β”‚   β”œβ”€β”€ πŸ“ config             # Configuration files
β”‚   β”‚   β”œβ”€β”€ πŸ“„ redis.config   # Redis configuration
β”‚   β”‚   β”œβ”€β”€ πŸ“„ mongo.config    # MongoDB configuration
β”‚   β”‚   β”œβ”€β”€ πŸ“„ postgres.config # PostgreSQL configuration
β”‚   β”‚   └── πŸ“„ nginx.conf     # Nginx configuration file
β”‚   β”œβ”€β”€ πŸ“ controllers        # Controller files
β”‚   β”‚   β”œβ”€β”€ πŸ“„ customer.ts    # Customer-related controller
β”‚   β”‚   β”œβ”€β”€ πŸ“„ product.ts     # Product-related controller
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ πŸ“ middleware         # Middleware files
β”‚   β”‚   β”œβ”€β”€ πŸ“„ auth.ts        # Authentication middleware
β”‚   β”‚   β”œβ”€β”€ πŸ“„ logger.ts      # Logger middleware
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ πŸ“ models             # Model files
β”‚   β”‚   β”œβ”€β”€ πŸ“„ customer.ts    # Customer model
β”‚   β”‚   β”œβ”€β”€ πŸ“„ product.ts     # Product model
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ πŸ“ routes             # Route files
β”‚   β”‚   β”œβ”€β”€ πŸ“„ api.ts         # API routes
β”‚   β”‚   β”œβ”€β”€ πŸ“„ auth.ts        # Authentication routes
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ πŸ“ tests              # Test files
β”‚   β”‚   β”œβ”€β”€ πŸ“ unit           # Unit tests
β”‚   β”‚   β”œβ”€β”€ πŸ“ integration     # Integration tests
β”‚   β”‚   β”œβ”€β”€ πŸ“ e2e            # End-to-end tests
β”‚   β”‚   └── ...
β”‚   └── πŸ“ utils              # Utility files
β”‚       β”œβ”€β”€ πŸ“„ validation.ts   # Validation utilities
β”‚       β”œβ”€β”€ πŸ“„ helpers.ts      # Helper functions
β”‚       └── ...
β”œβ”€β”€ πŸ“„ Dockerfile              # Dockerfile for building the Node.js app image
β”œβ”€β”€ πŸ“„ docker-compose.yml       # Docker Compose configuration
β”œβ”€β”€ πŸ“„ nodemon.json            # Nodemon configuration for development
β”œβ”€β”€ πŸ“„ package.json            # Project dependencies and scripts
β”œβ”€β”€ πŸ“ ansible                  # Ansible directory
β”‚   β”œβ”€β”€ πŸ“„ deploy.yml          # Ansible playbook for deployment
β”‚   └── πŸ“ roles               # Ansible roles (if any)
β”‚       └── ...
└── πŸ“ helm                     # Helm chart directory
    β”œβ”€β”€ πŸ“ your-helm-chart/
    β”‚   β”œβ”€β”€ πŸ“ charts          # Charts for dependencies
    β”‚   β”œβ”€β”€ πŸ“ templates       # Template files for Kubernetes resources
    β”‚   β”‚   β”œβ”€β”€ πŸ“„ deployment.yaml   # Deployment configuration for Node.js app
    β”‚   β”‚   β”œβ”€β”€ πŸ“„ service.yaml      # Service configuration for exposing the Node.js app
    β”‚   β”‚   β”œβ”€β”€ πŸ“„ ingress.yaml      # Ingress configuration for Nginx
    β”‚   β”‚   └── πŸ“„ configmap.yaml    # ConfigMap for environment variables
    β”‚   β”œβ”€β”€ πŸ“„ Chart.yaml            # Metadata for your Helm chart
    β”‚   └── πŸ“„ values.yaml           # Default values for your templates
β”œβ”€β”€ πŸ“ jenkins                     # Jenkins directory for pipeline configuration
β”‚   β”œβ”€β”€ πŸ“„ Jenkinsfile             # Declarative pipeline for Jenkins
β”‚   β”œβ”€β”€ πŸ“„ jenkins-config.groovy    # Configuration script for Jenkins setup
β”‚   └── πŸ“ jobs                    # Jenkins job configuration files
β”‚       β”œβ”€β”€ πŸ“„ build-node-app.xml  # Jenkins job for building Node.js app
β”‚       └── πŸ“„ deploy-node-app.xml  # Jenkins job for deploying Node.js app

Detailed File and Code Examples

1. .gitignore

node_modules/
dist/
.env
npm-debug.log
.DS_Store
uploads/

2. .dockerignore

node_modules
npm-debug.log
.git
.gitignore
Dockerfile
docker-compose.yml

3. .env

NODE_ENV=production
PORT=3000
MONGO_URI=mongodb://localhost:27017/mydatabase
REDIS_URL=redis://localhost:6379
POSTGRES_URI=postgresql://user:password@localhost:5432/mydatabase
JWT_SECRET=mysecret

4. example.env

NODE_ENV=development
PORT=3000
MONGO_URI=mongodb://localhost:27017/mydatabase
REDIS_URL=redis://localhost:6379
POSTGRES_URI=postgresql://user:password@localhost:5432/mydatabase
JWT_SECRET=mysecret

5. src/server.ts

import express from 'express';
import mongoose from 'mongoose';
import { json } from 'body-parser';
import { routes } from './routes/api';
import { connectRedis } from './config/redis.config';
import { connectMongo } from './config/mongo.config';

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

app.use(json());
app.use('/api', routes);

// MongoDB and Redis connection
connectMongo();
connectRedis();

app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

6. src/bin/www

#!/usr/bin/env node

import app from '../server';

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
    console.log(`Server started on port ${PORT}`);
});

7. src/config/redis.config

import Redis from 'ioredis';

const redis = new Redis(process.env.REDIS_URL);

export const connectRedis = () => {
    redis.on('connect', () => {
        console.log('Connected to Redis');
    });

    redis.on('error', (err) => {
        console.error('Redis error:', err);
    });
};

8. src/config/mongo.config

import mongoose from 'mongoose';

export const connectMongo = async () => {
    try {
        await mongoose.connect(process.env.MONGO_URI);
        console.log('Connected to MongoDB');
    } catch (error) {
        console.error('MongoDB connection error:', error);
    }
};

9. src/config/postgres.config

// PostgreSQL configuration
// You can set up Sequelize or pg-promise here

10. src/config/nginx.conf

server {
    listen 80;

    location / {
        proxy_pass http://localhost:3000;  # Adjust according to your Node.js server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

11. src/controllers/customer.ts

import { Request, Response } from 'express';

export const getCustomers = (req: Request, res: Response) => {
    // Logic to get customers
};

export const createCustomer = (req: Request, res: Response) => {
    // Logic to create a customer
};

12. src/controllers/product.ts

import { Request, Response } from 'express';

export const getProducts = (req: Request, res: Response) => {
    // Logic to get products
};

export const createProduct = (req: Request, res: Response) => {
    // Logic to create a product
};

13. src/middleware/auth.ts

import { Request, Response, NextFunction } from 'express';

export const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
    // Authentication logic
    next();
};

14. src/middleware/logger.ts

import { Request, Response, NextFunction } from 'express';

export const loggerMiddleware = (req: Request, res: Response, next: NextFunction) => {
    console.log(`${req.method} ${req.url}`);
    next();
};

15. src/models/customer.ts

import mongoose, { Schema, Document } from 'mongoose';

export interface ICustomer extends Document {
    name: string;
    email: string;
}

const CustomerSchema: Schema = new Schema({
    name: { type: String, required: true },
    email: { type: String, required: true },
});

export const Customer = mongoose

.model<ICustomer>('Customer', CustomerSchema);

16. src/models/product.ts

import mongoose, { Schema, Document } from 'mongoose';

export interface IProduct extends Document {
    title: string;
    price: number;
}

const ProductSchema: Schema = new Schema({
    title: { type: String, required: true },
    price: { type: Number, required: true },
});

export const Product = mongoose.model<IProduct>('Product', ProductSchema);

17. src/routes/api.ts

import { Router } from 'express';
import { getCustomers, createCustomer } from '../controllers/customer';
import { getProducts, createProduct } from '../controllers/product';

const router = Router();

router.get('/customers', getCustomers);
router.post('/customers', createCustomer);
router.get('/products', getProducts);
router.post('/products', createProduct);

export const routes = router;

18. src/tests/unit/customer.test.ts

import { getCustomers } from '../../controllers/customer';
import { Request, Response } from 'express';

describe('Customer Controller', () => {
    it('should get customers', () => {
        const req = {} as Request;
        const res = {
            send: jest.fn(),
        } as unknown as Response;

        getCustomers(req, res);
        expect(res.send).toHaveBeenCalled();
    });
});

19. Dockerfile

# Use an official Node.js runtime as a parent image
FROM node:14

# Set the working directory
WORKDIR /usr/src/app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD [ "npm", "start" ]

20. docker-compose.yml

version: '3.8'

services:
  node-app:
    build: .
    ports:
      - '3000:3000'
    environment:
      NODE_ENV: development
      MONGO_URI: mongodb://mongo:27017/mydatabase
      REDIS_URL: redis://redis:6379
      POSTGRES_URI: postgresql://user:password@postgres:5432/mydatabase
    depends_on:
      - mongo
      - redis
      - postgres

  mongo:
    image: mongo
    restart: always
    ports:
      - '27017:27017'

  redis:
    image: redis
    restart: always
    ports:
      - '6379:6379'

  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    ports:
      - '5432:5432'

21. nodemon.json

{
    "watch": ["src"],
    "ext": "ts",
    "exec": "ts-node src/server.ts"
}

22. package.json

{
    "name": "node-typescript-project-with-devops",
    "version": "1.0.0",
    "scripts": {
        "start": "ts-node src/server.ts",
        "dev": "nodemon",
        "test": "jest"
    },
    "dependencies": {
        "express": "^4.17.1",
        "mongoose": "^5.10.9",
        "ioredis": "^4.17.3",
        "dotenv": "^8.2.0",
        "pg": "^8.5.1"
    },
    "devDependencies": {
        "@types/express": "^4.17.11",
        "@types/jest": "^26.0.0",
        "jest": "^26.6.0",
        "ts-jest": "^26.4.0",
        "typescript": "^4.0.3",
        "nodemon": "^2.0.4",
        "ts-node": "^9.1.1"
    }
}

23. ansible/deploy.yml

---
- hosts: all
  tasks:
    - name: Ensure Node.js is installed
      apt:
        name: nodejs
        state: present

    - name: Copy application files
      copy:
        src: /path/to/your/local/project/
        dest: /path/to/remote/server/

    - name: Install dependencies
      command: npm install
      args:
        chdir: /path/to/remote/server/

24. helm/your-helm-chart/templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
        - name: node-app
          image: your-node-app-image
          ports:
            - containerPort: 3000
          env:
            - name: NODE_ENV
              value: "production"
            - name: MONGO_URI
              value: "mongodb://mongo:27017/mydatabase"
            - name: REDIS_URL
              value: "redis://redis:6379"
            - name: POSTGRES_URI
              value: "postgresql://user:password@postgres:5432/mydatabase"

25. helm/your-helm-chart/templates/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: node-app
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 3000
  selector:
    app: node-app

26. jenkins/Jenkinsfile

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                script {
                    docker.build("your-node-app-image")
                }
            }
        }
        stage('Deploy') {
            steps {
                script {
                    sh 'docker-compose up -d'
                }
            }
        }
    }
}

27. jenkins/jenkins-config.groovy

// Jenkins configuration script for initial setup

Additional Configuration and Usage

  1. Run the Application:

    • Use npm start or npm run dev to start the application in development mode with Nodemon.
  2. Docker:

    • Build the Docker image with docker build -t your-node-app-image .
    • Run docker-compose up to start all services defined in docker-compose.yml.
  3. Ansible:

    • Execute the Ansible playbook with ansible-playbook deploy.yml.
  4. Helm:

    • Package and deploy your Helm chart using helm install your-helm-chart.
  5. Jenkins:

    • Set up your Jenkins server and create a pipeline using the Jenkinsfile provided.
  6. Testing:

    • Run tests using npm test.

This structure and configuration allow for a solid foundation for a Node.js TypeScript project with DevOps best practices, making it easier to develop, test, and deploy your application efficiently. If you have any specific requirements or changes, feel free to change this structure is't Bible :)

Happy coding...


This content originally appeared on DEV Community and was authored by Omor Faruk


Print Share Comment Cite Upload Translate Updates
APA

Omor Faruk | Sciencx (2024-10-20T13:14:27+00:00) The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included. Retrieved from https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/

MLA
" » The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included." Omor Faruk | Sciencx - Sunday October 20, 2024, https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/
HARVARD
Omor Faruk | Sciencx Sunday October 20, 2024 » The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included., viewed ,<https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/>
VANCOUVER
Omor Faruk | Sciencx - » The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/
CHICAGO
" » The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included." Omor Faruk | Sciencx - Accessed . https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/
IEEE
" » The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included." Omor Faruk | Sciencx [Online]. Available: https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/. [Accessed: ]
rf:citation
» The Ultimate Node.js TypeScript Project Setup: DevOps Essentials Included | Omor Faruk | Sciencx | https://www.scien.cx/2024/10/20/the-ultimate-node-js-typescript-project-setup-devops-essentials-included/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.