Skip to content

Commit 04413f4

Browse files
committed
address env overwrite
1 parent ae5f7b7 commit 04413f4

File tree

9 files changed

+935
-34
lines changed

9 files changed

+935
-34
lines changed

dockerize/build-secretai-docker.sh

Lines changed: 668 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#!/bin/bash
2+
3+
# =====================================
4+
# Docker Build Script for MONAI Breast Density Classification
5+
# =====================================
6+
7+
set -e
8+
9+
# Configuration
10+
IMAGE_NAME="monai-breast-density"
11+
IMAGE_TAG="latest"
12+
DOCKERFILE="Dockerfile"
13+
14+
# Colors for output
15+
RED='\033[0;31m'
16+
GREEN='\033[0;32m'
17+
YELLOW='\033[1;33m'
18+
BLUE='\033[0;34m'
19+
NC='\033[0m' # No Color
20+
21+
# Function to print colored output
22+
print_status() {
23+
echo -e "${BLUE}[INFO]${NC} $1"
24+
}
25+
26+
print_success() {
27+
echo -e "${GREEN}[SUCCESS]${NC} $1"
28+
}
29+
30+
print_warning() {
31+
echo -e "${YELLOW}[WARNING]${NC} $1"
32+
}
33+
34+
print_error() {
35+
echo -e "${RED}[ERROR]${NC} $1"
36+
}
37+
38+
# Function to check prerequisites
39+
check_prerequisites() {
40+
print_status "Checking prerequisites..."
41+
42+
# Check if Docker is installed
43+
if ! command -v docker &> /dev/null; then
44+
print_error "Docker is not installed. Please install Docker first."
45+
exit 1
46+
fi
47+
48+
# Check if Docker daemon is running
49+
if ! docker info &> /dev/null; then
50+
print_error "Docker daemon is not running. Please start Docker."
51+
exit 1
52+
fi
53+
54+
# Check for NVIDIA Docker support (for GPU)
55+
if ! docker info | grep -q "nvidia"; then
56+
print_warning "NVIDIA Docker runtime not detected. GPU support may not work."
57+
print_warning "Install nvidia-container-toolkit for GPU support."
58+
fi
59+
60+
# Check if required files exist
61+
if [ ! -f "$DOCKERFILE" ]; then
62+
print_error "Dockerfile not found in current directory."
63+
exit 1
64+
fi
65+
66+
if [ ! -f "requirements-docker.txt" ]; then
67+
print_error "requirements-docker.txt not found in current directory."
68+
exit 1
69+
fi
70+
71+
# Check if model-core mount point directory exists (for documentation)
72+
if [ ! -d "/mnt/secure/.fetch/model-core" ]; then
73+
print_warning "Model-core mount point /mnt/secure/.fetch/model-core not found."
74+
print_warning "This is expected if running on a development machine."
75+
print_warning "Ensure the mount point is available when deploying to production."
76+
fi
77+
78+
print_success "Prerequisites check passed."
79+
}
80+
81+
# Function to build Docker image
82+
build_image() {
83+
print_status "Building Docker image: ${IMAGE_NAME}:${IMAGE_TAG}"
84+
85+
# Build the image with build context
86+
docker build \
87+
--target production \
88+
--tag "${IMAGE_NAME}:${IMAGE_TAG}" \
89+
--file "${DOCKERFILE}" \
90+
--progress=plain \
91+
--no-cache \
92+
.
93+
94+
if [ $? -eq 0 ]; then
95+
print_success "Docker image built successfully: ${IMAGE_NAME}:${IMAGE_TAG}"
96+
else
97+
print_error "Failed to build Docker image."
98+
exit 1
99+
fi
100+
}
101+
102+
# Function to verify the built image
103+
verify_image() {
104+
print_status "Verifying built image..."
105+
106+
# Check if image exists
107+
if docker images | grep -q "${IMAGE_NAME}"; then
108+
local image_size=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" | grep "${IMAGE_NAME}:${IMAGE_TAG}" | awk '{print $2}')
109+
print_success "Image verification passed. Size: ${image_size}"
110+
111+
# Show image details
112+
print_status "Image details:"
113+
docker images "${IMAGE_NAME}:${IMAGE_TAG}"
114+
else
115+
print_error "Image verification failed. Image not found."
116+
exit 1
117+
fi
118+
}
119+
120+
# Function to create necessary directories
121+
create_directories() {
122+
print_status "Creating necessary directories..."
123+
124+
mkdir -p logs
125+
mkdir -p temp
126+
mkdir -p model-store
127+
mkdir -p credentials
128+
129+
print_success "Directories created."
130+
}
131+
132+
# Function to show usage instructions
133+
show_usage() {
134+
echo ""
135+
print_success "Build completed successfully!"
136+
echo ""
137+
echo "Next steps:"
138+
echo "1. Copy .env.example to .env and configure your API keys:"
139+
echo " cp .env.example .env"
140+
echo ""
141+
echo "2. Edit .env file with your actual API keys and configuration"
142+
echo ""
143+
echo "3. If using GCP, place your service account JSON file in ./credentials/"
144+
echo ""
145+
echo "4. IMPORTANT: Ensure the model-core mount point is available:"
146+
echo " The pre-built MAR file should be at:"
147+
echo " /mnt/secure/.fetch/model-core/monai-breast-density-classification_model-store_monai-breast-density-classification.mar"
148+
echo ""
149+
echo "5. Run the container using Docker Compose (recommended):"
150+
echo " docker-compose up -d"
151+
echo ""
152+
echo "6. Or run directly with Docker (ensure mount point exists):"
153+
echo " docker run --gpus all -d \\"
154+
echo " --name monai-breast-density \\"
155+
echo " -p 127.0.0.1:8085:8085 \\"
156+
echo " -p 127.0.0.1:8086:8086 \\"
157+
echo " -p 127.0.0.1:8082:8082 \\"
158+
echo " -e OPENAI_API_KEY=your_key_here \\"
159+
echo " -v /mnt/secure/.fetch/model-core:/mnt/secure/.fetch/model-core:ro \\"
160+
echo " -v \$(pwd)/logs:/home/model-server/logs \\"
161+
echo " -v \$(pwd)/model-store:/home/model-server/model-store \\"
162+
echo " ${IMAGE_NAME}:${IMAGE_TAG}"
163+
echo ""
164+
echo "7. Check container health:"
165+
echo " curl http://localhost:8082/ping"
166+
echo ""
167+
echo "8. Check if model loaded successfully:"
168+
echo " curl http://localhost:8086/models/monai-breast-density-classification"
169+
echo ""
170+
echo "9. Test inference:"
171+
echo " curl -X POST http://localhost:8085/predictions/monai-breast-density-classification \\"
172+
echo " -H 'Content-Type: application/json' \\"
173+
echo " -d @examples/monai-breast-density-classification.json"
174+
echo ""
175+
echo "Note: The container will automatically copy the pre-built MAR file from the mount point"
176+
echo " to the local model store and load it at startup."
177+
echo ""
178+
}
179+
180+
# Main execution
181+
main() {
182+
echo "========================================="
183+
echo "MONAI Breast Density Classification"
184+
echo "Docker Build Script"
185+
echo "========================================="
186+
echo ""
187+
188+
check_prerequisites
189+
create_directories
190+
build_image
191+
verify_image
192+
show_usage
193+
}
194+
195+
# Parse command line arguments
196+
while [[ $# -gt 0 ]]; do
197+
case $1 in
198+
--tag)
199+
IMAGE_TAG="$2"
200+
shift 2
201+
;;
202+
--name)
203+
IMAGE_NAME="$2"
204+
shift 2
205+
;;
206+
--help|-h)
207+
echo "Usage: $0 [OPTIONS]"
208+
echo ""
209+
echo "Options:"
210+
echo " --tag TAG Set image tag (default: latest)"
211+
echo " --name NAME Set image name (default: monai-breast-density)"
212+
echo " --help, -h Show this help message"
213+
exit 0
214+
;;
215+
*)
216+
print_error "Unknown option: $1"
217+
echo "Use --help for usage information."
218+
exit 1
219+
;;
220+
esac
221+
done
222+
223+
# Run main function
224+
main

dockerize/docker-compose.yaml

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
version: '3.8'
2-
31
services:
42
torchserve:
53
# build:
64
# context: .
75
# dockerfile: Dockerfile
86
# target: production
97
image: monai-breast-density:latest
10-
container_name: fetch
8+
container_name: torchserve
119
privileged: true
1210

1311
# GPU support
@@ -35,8 +33,6 @@ services:
3533
- "127.0.0.1:8082:8082" # Metrics API
3634
- "127.0.0.1:7070:7070" # gRPC Inference
3735
- "127.0.0.1:7071:7071" # gRPC Management
38-
- "127.0.0.1:8090:8090" # REST API
39-
4036

4137
# Volume mounts
4238
volumes:
@@ -58,17 +54,17 @@ services:
5854
memlock: -1
5955
stack: 67108864
6056

61-
# Health check
57+
# Token-based health check - checks for key_file.json presence
6258
healthcheck:
63-
test: ["CMD", "curl", "-f", "http://localhost:8082/ping"]
59+
test: ["CMD", "test", "-f", "/home/model-server/key_file.json"]
6460
interval: 30s
65-
timeout: 30s
61+
timeout: 10s
6662
start_period: 120s
6763
retries: 3
6864

6965
# Restart policy
7066
restart: unless-stopped
71-
67+
7268
# Logging configuration
7369
logging:
7470
driver: "json-file"
@@ -77,14 +73,15 @@ services:
7773
max-file: "5"
7874

7975
networks:
80-
- monai-network
76+
- monai-network
8177

8278
# FastAPI Authentication & Gateway Service
8379
auth-gateway:
84-
build:
85-
context: ./secretai
86-
dockerfile: Dockerfile
87-
container_name: fetch-auth-gateway
80+
image: monai-secretai:dev
81+
# build:
82+
# context: ./secretai
83+
# dockerfile: Dockerfile
84+
container_name: auth-gateway
8885

8986
environment:
9087
- TORCHSERVE_URL=http://torchserve:8085
@@ -125,8 +122,7 @@ services:
125122

126123
# Networks
127124
networks:
128-
default:
129-
name: monai-network
125+
monai-network:
130126
driver: bridge
131127

132128
# Volumes for persistent data

dockerize/secretai/Dockerfile

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,12 @@ COPY *.py ./
2424
COPY .env ./
2525

2626
# Create non-root user for security
27-
RUN groupadd -r authuser && useradd -r -g authuser authuser
28-
RUN chown -R authuser:authuser /app
29-
USER authuser
27+
RUN groupadd -r model-server && useradd -r -g model-server -u 1000 model-server
28+
RUN chown -R model-server:model-server /app
29+
USER model-server
3030

3131
# Environment variables
3232
ENV PYTHONUNBUFFERED=1
33-
ENV JWT_SECRET_KEY=""
34-
ENV REST_API_USERNAME=""
35-
ENV REST_API_PASSWORD=""
36-
ENV TORCHSERVE_URL="http://torchserve:8085"
3733

3834
# Expose port
3935
EXPOSE 8090

dockerize/secretai/build-info.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"build_time": "2025-06-24T23:26:59Z",
3+
"image_name": "monai-secretai",
4+
"image_tag": "dev",
5+
"git_commit": "ae5f7b77802f5b3b11a6e4911c38353c0df15f4d",
6+
"git_branch": "master",
7+
"platform": "",
8+
"builder": "ubuntu@158-101-123-7"
9+
}

dockerize/secretai/env.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import os
2+
from pathlib import Path
3+
from dotenv import load_dotenv
4+
5+
# Try multiple locations
6+
env_paths = [
7+
'/app/.env',
8+
'.env',
9+
Path(__file__).parent / '.env'
10+
]
11+
12+
for env_path in env_paths:
13+
if os.path.exists(env_path):
14+
print(f"🏗️ Loading environment variables from {env_path}")
15+
load_dotenv(env_path)
16+
for key, value in os.environ.items():
17+
print(f"🔑 {key} = {value}")
18+
break

dockerize/secretai/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
FastAPI Authentication & Gateway Service for MONAI Breast Density Classification
33
Provides JWT-based authentication and proxies requests to TorchServe with token support
44
"""
5+
import env
56

67
import os
78
import sys

dockerize/secretai/settings.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
import os
22
import sys
33
import secrets
4-
from datetime import datetime, timedelta
5-
from typing import Optional, Dict, Any
6-
7-
import jwt
8-
from fastapi import FastAPI, HTTPException, Depends, status
9-
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
10-
from fastapi.middleware.cors import CORSMiddleware
11-
from pydantic import BaseModel, Field
12-
import bcrypt
13-
from contextlib import asynccontextmanager
14-
154
from dotenv import load_dotenv, find_dotenv
165

176
_ = load_dotenv(find_dotenv()) # read local .env file

dockerize/tokens/config/config-docker.properties

Whitespace-only changes.

0 commit comments

Comments
 (0)