Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
ai company
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
ai company
Commits
b777c5b5
Commit
b777c5b5
authored
Mar 17, 2026
by
Vũ Hoàng Anh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: multi-stage Docker builds, .dockerignore, singleton StarRocks connection
parent
1f2700e1
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
122 additions
and
28 deletions
+122
-28
.dockerignore
backend/.dockerignore
+43
-5
Dockerfile.dev
backend/Dockerfile.dev
+31
-13
Dockerfile.prod
backend/Dockerfile.prod
+43
-5
product_route.py
backend/api/product_route.py
+5
-5
No files found.
backend/.dockerignore
View file @
b777c5b5
# ═══ Git & IDE ═══
.git
.gitignore
.vscode
.idea
*.swp
*.swo
# ═══ Python cache ═══
__pycache__
*.pyc
.env
*.pyo
*.egg-info
.pytest_cache
.mypy_cache
.ruff_cache
# ═══ Virtual environments ═══
.venv
venv
.git
.gitignore
env
# ═══ Docker ═══
Dockerfile*
docker-compose*
.dockerignore
logs
data
# ═══ Dev & test files ═══
tests/
*.test.py
setup_readonly_user.py
# ═══ Docs & artifacts ═══
*.md
LICENSE
# ═══ OS files ═══
.DS_Store
Thumbs.db
# ═══ Logs ═══
*.log
logs/
# ═══ Local env backup ═══
.env.local
.env.backup
.env.example
backend/Dockerfile.dev
View file @
b777c5b5
# ============================================================
# DOCKERFILE.DEV
- Local Development (Hot Reload + Cache
)
# DOCKERFILE.DEV
— Multi-stage Dev Build (Hot Reload
)
# ============================================================
# Sử dụng Python 3.11 Slim để tối ưu dung lượng
# Stage 1: Builder — install dependencies
# Stage 2: Runtime — dev server with reload
# ============================================================
# ──── Stage 1: Builder ────
FROM python:3.11-slim AS builder
WORKDIR /build
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt \
&& pip install --no-cache-dir --user watchdog[watchmedo]
# ──── Stage 2: Runtime ────
FROM python:3.11-slim
# Thiết lập thư mục làm việc
WORKDIR /app
# Thiết lập biến môi trường
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 curl \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge -y --auto-remove
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV ENV=development
# Copy requirements.txt trước để tận dụng Docker cache
COPY requirements.txt .
# Cài đặt thư viện Python (Docker layer cache)
RUN pip install -r requirements.txt && pip install watchdog[watchmedo]
# Copy installed packages from builder
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
#
Copy toàn bộ source code vào image
#
Source code mounted via volume in docker-compose (not COPY)
COPY . .
# Expose port 5000
EXPOSE 5000
# Health check (optional)
HEALTHCHECK --interval=10s --timeout=5s --start-period=5s --retries=2 \
CMD
python -c "import requests; requests.get('http://localhost:5000/docs')"
|| exit 1
CMD
curl -f http://localhost:5000/docs
|| exit 1
CMD ["gunicorn", "--workers", "1", "--worker-class", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:5000", "--timeout", "120", "--reload", "server:app"]
backend/Dockerfile.prod
View file @
b777c5b5
# ============================================================
# DOCKERFILE.PROD — Multi-stage Production Build
# ============================================================
# Stage 1: Build — install dependencies in isolated layer
# Stage 2: Runtime — minimal image with only what's needed
# ============================================================
FROM python:3.11-slim
# ──── Stage 1: Builder ────
FROM python:3.11-slim AS builder
WORKDIR /build
# Install only build-time system deps (if any wheels need compiling)
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
# Install to user site-packages (no root pollution)
RUN pip install --no-cache-dir --user -r requirements.txt
# ──── Stage 2: Runtime ────
FROM python:3.11-slim
WORKDIR /app
# Minimal runtime deps only
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 curl \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge -y --auto-remove
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV ENV=
development
ENV ENV=
production
COPY requirements.txt .
RUN pip install -r requirements.txt
# Copy only installed packages from builder (no pip cache, no gcc)
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
# Copy application source
COPY . .
EXPOSE 5000
...
...
@@ -19,4 +48,13 @@ EXPOSE 5000
ENV WORKERS=1
ENV TIMEOUT=60
CMD gunicorn server:app --workers $WORKERS --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:5000 --timeout $TIMEOUT
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -f http://localhost:5000/docs || exit 1
CMD gunicorn server:app \
--workers $WORKERS \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:5000 \
--timeout $TIMEOUT \
--access-logfile - \
--error-logfile -
backend/api/product_route.py
View file @
b777c5b5
...
...
@@ -9,7 +9,7 @@ from typing import Optional
from
fastapi
import
APIRouter
,
Query
from
fastapi.responses
import
JSONResponse
from
common.starrocks_connection
import
StarRocksC
onnection
from
common.starrocks_connection
import
get_db_c
onnection
from
agent.tools.product_mapping
import
resolve_color
,
resolve_product_name
,
SYNONYM_TO_DB
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -21,7 +21,7 @@ TABLE_NAME = "shared_source.magento_product_dimension_with_text_embedding"
@
router
.
get
(
"/api/products/overview"
,
summary
=
"Product catalog KPI overview"
)
async
def
products_overview
():
"""Return aggregate KPIs for the product catalog."""
db
=
StarRocksC
onnection
()
db
=
get_db_c
onnection
()
try
:
rows
=
await
db
.
execute_query_async
(
f
"""
SELECT
...
...
@@ -104,7 +104,7 @@ async def products_list(
offset
:
int
=
Query
(
0
,
ge
=
0
),
):
"""Return paginated product listing grouped by internal_ref_code."""
db
=
StarRocksC
onnection
()
db
=
get_db_c
onnection
()
# Build WHERE clauses
clauses
=
[]
...
...
@@ -234,7 +234,7 @@ async def products_colors(
code
:
str
=
Query
(
...
,
description
=
"internal_ref_code"
),
):
"""Return all color variants for a given internal_ref_code."""
db
=
StarRocksC
onnection
()
db
=
get_db_c
onnection
()
try
:
variants
=
await
db
.
execute_query_async
(
f
"""
...
...
@@ -266,7 +266,7 @@ async def products_colors(
@
router
.
get
(
"/api/products/filters"
,
summary
=
"Available filter options"
)
async
def
products_filters
():
"""Return all available filter values for color, product_line, age, season."""
db
=
StarRocksC
onnection
()
db
=
get_db_c
onnection
()
try
:
colors
=
await
db
.
execute_query_async
(
f
"""
SELECT master_color, COUNT(DISTINCT internal_ref_code) AS cnt
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment