docker compose file added for deployment

This commit is contained in:
2026-01-22 22:34:12 +05:30
parent 9d7109b60f
commit c76d533783
13 changed files with 267 additions and 4 deletions

13
.env.prod Normal file
View File

@@ -0,0 +1,13 @@
# Database Configuration
# Connecting to existing 'postgres-db' container in 'arbit-app_arbit-network'
DB_USER=postgres
DB_PASSWORD='M@tr!x#149@dm!N'
DB_NAME=ocr_db
DB_HOST=postgres-db
DB_PORT=5432
# Mail Configuration (IMAP)
MAIL_SERVER=imap.gmail.com
MAIL_PORT=993
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password

96
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,96 @@
# OCR Application Deployment Guide
This guide describes how to deploy the OCR application on a Linux host (e.g., Ubuntu/Debian).
## Architecture
- **Backend**: Containerized (FastAPI, Python 3.9).
- **Database**: Containerized (PostgreSQL 15).
- **Frontend**: Static files (Angular) served by Host Nginx.
- **Reverse Proxy**: Host Nginx proxies requests to Frontend (Static) and Backend (API).
## Prerequisites
- Docker & Docker Compose installed on the host.
- Nginx installed on the host.
- Node.js & NPM (for building Angular).
---
## 1. Full Stack Deployment (Docker)
The app connects to your **existing Postgres container** (`postgres-db`) in the `arbit-app_arbit-network`.
1. **Create the Database**:
Since we are using an existing postgres instance, we must manually create the `ocr_db`.
```bash
# Run this on your host to create the DB inside the existing container
docker exec -it postgres-db psql -U postgres -c "CREATE DATABASE ocr_db;"
```
2. **Navigate to project root**:
```bash
cd /path/to/OCR
```
3. **Verify Environment**:
Ensure `.env.prod` exists and points to `DB_HOST=postgres-db`.
**Also configure your Email credentials** in `.env.prod` if you want the Mailbox feature to work (Gmail requires an App Password).
```bash
cat .env.prod
```
4. **Start App Containers**:
This will start `ocr_backend` and `ocr_frontend`.
```bash
# Build and start in detached mode
docker-compose --env-file .env.prod up -d --build
```
5. **Verify Status**:
```bash
docker-compose ps
```
You should see `ocr_backend` and `ocr_frontend` running.
---
## 2. Nginx Configuration (Host Reverse Proxy)
Since the Frontend is now running in a container on port 8080 (serving `/ocrf/`), we configure the Host Nginx to proxy traffic to it.
1. **Create Config File**:
Copy the provided config to `/etc/nginx/sites-available/ocr`.
```bash
sudo cp deployment/nginx.conf /etc/nginx/sites-available/ocr
```
2. **Enable Site**:
```bash
sudo ln -s /etc/nginx/sites-available/ocr /etc/nginx/sites-enabled/
```
3. **Test & Reload**:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
---
## 3. Verification
- **Url**: `http://app.technobeesolutions.in/ocrf/` (Proxies to Frontend Container)
- **API**: `http://app.technobeesolutions.in/ocrb/` (Proxies to Backend Container)
---
## 4. Troubleshooting
- **Logs**:
```bash
docker-compose logs -f backend
```
- **Database**:
Connect via the existing container:
```bash
docker exec -it postgres-db psql -U postgres -d ocr_db
```

30
backend/Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
# Use official lightweight Python image
FROM python:3.9-slim
# Install system dependencies
# tesseract-ocr: for pytesseract
# poppler-utils: for pdf2image
# libtesseract-dev: development headers
RUN apt-get update && apt-get install -y \
tesseract-ocr \
poppler-utils \
libtesseract-dev \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy requirements first to leverage Docker cache
COPY requirements.txt .
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY . .
# Expose port (default for Uvicorn)
EXPOSE 8000
# Run the application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

View File

@@ -10,3 +10,4 @@ imap-tools
apscheduler apscheduler
python-dotenv python-dotenv
pdfplumber pdfplumber
pdf2image

22
deployment/nginx.conf Normal file
View File

@@ -0,0 +1,22 @@
server {
listen 80;
server_name app.technobeesolutions.in;
# Proxy Angular Frontend Container
location /ocrf/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Proxy API requests to the Docker Backend
location /ocrb/ {
proxy_pass http://localhost:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

41
docker-compose.yaml Normal file
View File

@@ -0,0 +1,41 @@
services:
# Backend API
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: ocr_backend
restart: always
environment:
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_NAME: ${DB_NAME}
# Mail Config
MAIL_SERVER: ${MAIL_SERVER}
MAIL_PORT: ${MAIL_PORT}
MAIL_USERNAME: ${MAIL_USERNAME}
MAIL_PASSWORD: ${MAIL_PASSWORD}
ports:
- "8000:8000"
networks:
- arbit-network
# Frontend Angular App
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: ocr_frontend
restart: always
ports:
- "8080:80"
networks:
- arbit-network
networks:
arbit-network:
external: true
name: arbit-app_arbit-network

36
frontend/Dockerfile Normal file
View File

@@ -0,0 +1,36 @@
# Stage 1: Build the Angular application
FROM node:18 as build
WORKDIR /app
# Install dependencies first (better caching)
COPY package*.json ./
RUN npm install
# Copy source code
COPY . .
# Build for production with specific base-href
RUN npm run build -- --configuration production --base-href /ocrf/
# Stage 2: Serve via Nginx
FROM nginx:alpine
# Remove default nginx static assets
RUN rm -rf /usr/share/nginx/html/*
# Create target directory (since we use /ocrf/ base-href)
RUN mkdir -p /usr/share/nginx/html/ocrf
# Copy built assets from builder stage
# Note: Adjust 'dist/frontend/browser' based on your angular.json output path.
# Angular 17+ creates 'browser' folder.
COPY --from=build /app/dist/frontend/browser /usr/share/nginx/html/ocrf
# Copy custom nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port 80
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

16
frontend/nginx.conf Normal file
View File

@@ -0,0 +1,16 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html/ocrf;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Optional: Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
}

View File

@@ -7,7 +7,7 @@ import { Observable, of, tap } from 'rxjs';
providedIn: 'root' providedIn: 'root'
}) })
export class AuthService { export class AuthService {
private apiUrl = 'http://localhost:8000/api'; private apiUrl = '/ocrb/api';
constructor(private http: HttpClient, private router: Router) { } constructor(private http: HttpClient, private router: Router) { }

View File

@@ -28,8 +28,8 @@ export interface EmailListResponse {
providedIn: 'root' providedIn: 'root'
}) })
export class MailboxService { export class MailboxService {
private apiUrl = 'http://localhost:8000/api/emails'; private apiUrl = '/ocrb/api/emails';
private attachmentUrl = 'http://localhost:8000/api/attachments'; private attachmentUrl = '/ocrb/api/attachments';
constructor(private http: HttpClient) {} constructor(private http: HttpClient) {}

View File

@@ -6,7 +6,7 @@ import { Observable } from 'rxjs';
providedIn: 'root' providedIn: 'root'
}) })
export class OcrService { export class OcrService {
private apiUrl = 'http://localhost:8000/api/ocr'; private apiUrl = '/ocrb/api/ocr';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
@@ -15,4 +15,12 @@ export class OcrService {
formData.append('file', file); formData.append('file', file);
return this.http.post(`${this.apiUrl}/extract`, formData); return this.http.post(`${this.apiUrl}/extract`, formData);
} }
extractWithAI(text: string, filePath: string | null, modelType: string): Observable<any> {
return this.http.post(`/ocrb/api/extract/ai`, { text, file_path: filePath, model_type: modelType });
}
saveDocument(data: any): Observable<any> {
return this.http.post(`/ocrb/api/documents/save`, data);
}
} }