• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

? Enterprise-Grade Containerization for Node.js Backends

Sascha Онлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,559
Баллы
155


This comprehensive guide details the pattern for containerizing a Node.js backend with PostgreSQL using a multi-stage Dockerfile and Podman Compose. The configuration is optimized for security, efficiency, and resilience, providing a robust framework suitable for any Node.js application deployment.

1. Core Application Configuration

1.1 package.json (The Essential Execution Scripts)


The package.json defines the build and runtime scripts used within the container environment. The primary goal is to execute compiled code after migrations are complete.

ScriptCommand (Generic)Detailed Rationale
"build"[YOUR_BUILD_COMMAND]Compiles source code (e.g., TypeScript) into production JavaScript files, typically placed in a ./dist directory.
"db:migrate"[YOUR_DB_CLI_TOOL] [migration:run_command] Database Integrity: Command to run the necessary database schema migrations before the server starts.
"start"node ./dist/src/index.js Application Startup: Command to execute the main compiled entry point.
1.2 .env (Environment Variables)


This file manages configuration data, using generic placeholders for sensitive data.


# --- Application Configuration ---
PORT=3000
APP_ENV=production

# --- Database Credentials (Internal Application Use) ---
DB_USER=app_user
DB_PASS=secure_db_pass
DB_NAME=app_db

# --- Postgres Image Required Variables (Used by the Container Image) ---
POSTGRES_USER=${DB_USER}
POSTGRES_PASSWORD=${DB_PASS}
POSTGRES_DB=${DB_NAME}



2. The Multi-Stage Dockerfile (Security and Efficiency)


A multi-stage build separates the environment with large development dependencies from the small, secure runtime environment.

Dockerfile


# --- STAGE 1: Build & Compilation (AS builder) ---
FROM node:20-alpine AS builder
WORKDIR /app

# 1. Dependency Installation: Install all dependencies (including devDependencies for compilation)
COPY package*.json ./
RUN npm ci

# 2. Source Compilation
COPY . .
RUN npm run build

# --- STAGE 2: Production Runtime (AS final) ---
FROM node:20-alpine as final
WORKDIR /usr/src/app

# Security Best Practice: Create and use a dedicated non-root user
RUN adduser --system --uid 1001 nodejs && \
mkdir -p /usr/src/app && \
chown -R 1001:1001 /usr/src/app
USER nodejs

# Configuration Copy (Temporarily elevating to copy system scripts)
USER root
COPY bin/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
USER nodejs # Switch back to non-root user

# 1. Dependency Optimization: Install ONLY production dependencies
COPY package*.json ./
RUN npm ci --omit=dev

# 2. Application Files: Copy ONLY the compiled output from the 'builder' stage
COPY --from=builder --chown=1001:1001 /app/dist ./dist

# Final configuration
EXPOSE 3000
ENTRYPOINT [ "entrypoint.sh" ]

# EXECUTION: Executes the 'start' script from package.json
CMD ["npm", "run", "start"]



SectionDetailed Rationale
Stage 1 (builder)Handles compilation. The large footprint of devDependencies is isolated here and discarded after the build.
USER nodejs Security: The application runs as a non-root user (uid 1001). This limits the privileges an attacker would gain if the container were compromised.
npm ci --omit=dev Efficiency: Installing only production dependencies significantly reduces the final image size and minimizes the security surface area.
3. The Database Entrypoint & Migrations


The entrypoint.sh script is the crucial element for reliable startup, managing the dependency on the PostgreSQL database.

bin/entrypoint.sh


#!/bin/sh

# This script ensures Postgres is up before running migrations and starting the app.

# Hostname is the service name in docker-compose (internal DNS resolution)
DB_HOST="postgres"
DB_PORT="5432"

echo "Waiting for PostgreSQL ($DB_HOST:$DB_PORT)..."

# Loop until the database service is ready (using netcat for port check)
while ! nc -z $DB_HOST $DB_PORT; do
sleep 0.5
done

echo "PostgreSQL started. Running migrations..."

# Executes the database migration script
npm run db:migrate

echo "Migrations complete. Starting application..."

# Execute the application's main command (CMD from Dockerfile)
# 'exec' ensures proper signal handling and process management.
exec "$@"



ComponentDetailed Rationale
while ! nc -z $DB_HOST $DB_PORT; do ... Race Condition Prevention: This loop forces the application to wait until the PostgreSQL port is open and listening, preventing a "Connection Refused" error upon startup.
npm run db:migrate Schema Integrity: Guarantees that the database schema is updated to the latest version before the main server process attempts to use the tables.
exec "$@" Process Management: The exec command replaces the current shell process with the final application process (npm run start). This is essential for ensuring that signals (like SIGTERM from Podman Compose on shutdown) are correctly received and handled by the Node.js process, allowing for graceful termination.
4. Podman Compose & Container Networking (CNI Explained)


Podman Compose defines and orchestrates the multi-container application and relies on the Container Network Interface (CNI) for connectivity.

CNI (Container Network Interface) Explained


CNI is the standard that governs how container runtimes (like Podman) create, manage, and connect containers to networks. When you define an app_network with driver: bridge, Podman utilizes the CNI to:

  1. Establish a Virtual Network: A private bridge network is created on the host machine.
  2. Enable Internal DNS: All services connected to this network are assigned IP addresses and can resolve each other using their service names (e.g., the backend container can connect to the database simply by using the hostname postgres).
docker-compose.yaml (Podman Compose)


services:
# --- BACKEND APPLICATION SERVICE ---
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:3000" # Host port 8080 -> Container port 3000
env_file:
- .env # Load environment variables
environment:
DB_HOST: postgres # Internal service name resolution
DB_PORT: 5432
networks:
- app_network
depends_on:
- postgres

# --- POSTGRESQL DATABASE SERVICE ---
postgres:
image: postgres:15-alpine
ports:
# Security: Binds the port ONLY to the localhost interface
- "127.0.0.1:5432:5432"
env_file:
- .env # Loads POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB
volumes:
- postgres_data:/var/lib/postgresql/data # Persistent storage for data
networks:
- app_network

# --- VOLUMES & NETWORKS ---
volumes:
postgres_data:
networks:
app_network:
driver: bridge # Specifies the CNI bridge network type



ComponentDetailed Rationale
DB_HOST: postgresThe application uses the service name as the database hostname, leveraging the CNI's internal DNS resolver for efficient inter-container communication.
ports: 127.0.0.1:5432:5432 Security: Binding to the host's loopback address (127.0.0.1) prevents external connections to the database, ensuring the database is only accessible from the host itself and the internal app_network.
volumes: postgres_data Persistence: Ensures the database data survives container removal, preventing data loss during updates or redeployments.
Conclusion


This documentation outlines a robust and production-ready pattern for containerizing a Node.js backend. The integration of multi-stage builds, non-root execution, and CNI-managed networking provides a foundation that is secure, efficient, and resilient against common deployment failures. By strictly separating compilation from runtime and sequencing the database startup, this pattern guarantees a predictable and reliable deployment lifecycle.

Deployment and Cleanup Commands


  1. Build and Run (Initial or Full Redeployment):

    podman-compose up --build

  2. Remove Containers AND Persistent Volumes (Use with Caution):

    podman-compose down -v


    (Use the -v flag to delete the data volume if you need a completely clean start.)

Example of where you can find these files

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. But do not use it in this project ? as you will faced some problem as it's an old one i did inn hurry.



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу