Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Deploying a Multi-Service RAG Application to Alibaba Cloud ECS via Docker

Tech May 17 2

Project Overview

This guide documents the process of containerizing and deploying a Retrieval-Augmented Generation (RAG) platform to Alibaba Cloud ECS. The stack consists of three distinct services:

  • Client Interface: React PWA served via Nginx.
  • API Service: Node.js backend using Koa and MongoDB.
  • AI Engine: Python service using FastAPI, MongoDB, and ChromaDB.

Creating Dockerfiles

1. Frontend Configuration (React + Nginx)

The frontend build process uses a multi-stage Dockerfile. The first stage compiles the React application, and the second stage serves the static assets using Nginx.

When configuring Nginx within Docker, note that the configuration file copied into the container typically represents the server block rather than the full http or main context. It is usually placed in /etc/nginx/conf.d/default.conf.

Key Nginx Settings:

  • Request Size: Increase the body size limit to allow large file uploads (avoid 413 errors).
  • MIME Types: Ensure proper handling of modern assets like JavaScript modules and WOFF2 fonts.
  • Caching: Disable caching for index.html to ensure users receive the latest PWA updates.
server {
    listen 80;
    client_max_body_size 50m; 

    types {
        application/javascript js mjs;
        font/woff2 woff2;
        # ... other types
    }

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }

    # Proxy API requests to the Node service
    location /koapi/ {
        proxy_pass http://node-api:3001/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Note: The trailing slash in proxy_pass http://node-api:3001/; replaces the /koapi/ path. Omitting it would append the path.

2. Node.js Service

The Koa service Dockerfile should install dependencies and start the application. No complex build steps are required beyond npm install.

3. Python AI Service

For the FastAPI service, we use Poetry for dependency management. Since a container runs a single process, we disable Poetry's virtual environment creation to use the system Python direct.

# Disable virtual environment creation inside the container
ENV POETRY_VIRTUALENVS_CREATE=false \
    POETRY_VIRTUALENVS_IN_PROJECT=false

# Install dependencies and run
RUN poetry install --no-interaction --no-ansi
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Defining Services with Docker Compose

We use docker-compose.yml to orchestrate the multi-container setup. This includes the application services and the MongoDB instance.

Critical Configurations:

  • Volumes: Map host directoreis to container paths for MongoDB data persistence and shared uploaded files.
  • Networks: Create a custom bridge network (e.g., app-net) so services can communicate using container names (e.g., node-api).
  • Dependencies: Use depends_on to ensure the database starts before the applications.
version: '3.8'
services:
  node-api:
    build: ./koa-node
    container_name: node-api
    restart: always
    env_file:
      - ./koa-node/.env
    volumes:
      - uploads_volume:/app/public/uploads
    networks:
      - app-net

  ai-engine:
    build: ./python-for-ai
    container_name: ai-engine
    restart: always
    volumes:
      - chroma_volume:/app/chroma
      - uploads_volume:/app/public/uploads
    depends_on:
      - mongo-db
    networks:
      - app-net

  mongo-db:
    image: mongo:7
    container_name: mongo-db
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: secret
    volumes:
      - mongo_data:/data/db
    networks:
      - app-net

volumes:
  uploads_volume:
  chroma_volume:
  mongo_data:

networks:
  app-net:
    driver: bridge

Cross-Platform Builds and Alibaba Cloud Deployment

Handling Architecture Differences

If building on an Apple Silicon (ARM) Mac but deploying to an Alibaba Cloud ECS (x86/AMD64), you must build the images for the correct platform. Use docker buildx to create AMD64 images from an ARM machine.

# Build for x86 architecture and push directly to registry
docker buildx build --platform linux/amd64 \
  -t registry.cn-guangzhou.aliyuncs.com/user/rag:backend-latest \
  ./koa-node --push

ECS Configuration

  1. Install Docker and Docker Compose on the Alibaba Cloud ECS instance.
  2. Configure the Security Group to allow inbound traffic on port 22 (SSH) and port 80 (HTTP).
  3. Transfer the docker-compose.yml to the server using SFTP/SCP.
  4. Update docker-compose.yml to use image: instead of build: if the images are already in a registry (like Alibaba Cloud Container Registry).
  5. Run docker compose pull and docker compose up -d.

Code Adjustments for Containerization

When moving to a containerized environment, file system operations may behave differently. For example, moving files between mounted volumes and local container storage often fails with rename due to cross-device links.

Solution: Use copy and unlink instead of rename.

try {
    // Avoid using rename() when dealing with volume mounts
    // await fs.promises.rename(sourcePath, destinationPath);
    
    await fs.promises.copyFile(sourcePath, destinationPath);
    await fs.promises.unlink(sourcePath);
    console.log('File moved successfully');
} catch (error) {
    console.error('File operation failed', error);
    ctx.status = 500;
    ctx.body = { error: 'Failed to save file' };
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.