Skip to content

Commit 5f3c16e

Browse files
authored
Merge pull request #1 from flare-foundation/ui
updates
2 parents 966f1c8 + 67b0c98 commit 5f3c16e

File tree

9 files changed

+326
-142
lines changed

9 files changed

+326
-142
lines changed

.github/workflows/build_and_push.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Build and Push
33
on:
44
push:
55
# tags: ["v*.*.*"] # Match semantic versioning tags like v1.0.0
6-
branches: ["main"]
6+
branches: ["main", "ui"]
77
workflow_dispatch: # Allow manual triggering of the workflow
88

99
env:
@@ -40,7 +40,7 @@ jobs:
4040

4141
# Cache Docker layers to speed up builds
4242
- name: Cache Docker layers
43-
uses: actions/cache@v3 # Pin to a specific version
43+
uses: actions/cache@v3
4444
with:
4545
path: /tmp/.buildx-cache
4646
key: ${{ runner.os }}-docker-${{ github.ref }}
@@ -49,7 +49,7 @@ jobs:
4949
5050
# Build and push Docker image
5151
- name: Build and push Docker image
52-
uses: docker/build-push-action@v6 # Pin to a specific version
52+
uses: docker/build-push-action@v6
5353
id: push
5454
with:
5555
context: .

.github/workflows/lint.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ jobs:
1111
runs-on: "ubuntu-latest"
1212
steps:
1313
- name: Checkout repository
14-
uses: actions/checkout@v4 # Pin to specific version
14+
uses: actions/checkout@v4
1515

1616
# Set up Python environment
1717
- name: Set up uv
18-
uses: astral-sh/setup-uv@v5 # Pin to specific version
18+
uses: astral-sh/setup-uv@v5
1919
with:
2020
version: "0.5.24"
2121

@@ -30,7 +30,7 @@ jobs:
3030
# Lint code with ruff
3131
- name: Lint with ruff
3232
run: uv run ruff check --diff
33-
continue-on-error: false # Fail if issues are found
33+
continue-on-error: false
3434

3535
# Type check with pyright
3636
- name: Type check with pyright

Dockerfile

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
1-
# Stage 1: Build Stage
2-
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
1+
# Stage 1: Build Frontend
2+
FROM node:18-alpine AS frontend-builder
3+
WORKDIR /frontend
4+
COPY chat-ui/ .
5+
RUN npm install
6+
RUN npm run build
7+
8+
# Stage 2: Build Backend
9+
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS backend-builder
310
ADD . /flare-ai-core
411
WORKDIR /flare-ai-core
512
RUN uv sync --frozen
613

7-
# Stage 2: Production Stage (Final Image)
14+
# Stage 3: Final Image
815
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
916

17+
# Install nginx
18+
RUN apt-get update && apt-get install -y nginx supervisor curl && \
19+
rm -rf /var/lib/apt/lists/*
20+
1021
WORKDIR /app
22+
COPY --from=backend-builder /flare-ai-core/.venv ./.venv
23+
COPY --from=backend-builder /flare-ai-core/src ./src
24+
COPY --from=backend-builder /flare-ai-core/pyproject.toml .
25+
COPY --from=backend-builder /flare-ai-core/README.md .
26+
27+
# Copy frontend files
28+
COPY --from=frontend-builder /frontend/build /usr/share/nginx/html
29+
30+
# Copy nginx configuration
31+
COPY nginx.conf /etc/nginx/sites-enabled/default
1132

12-
COPY --from=builder /flare-ai-core/.venv ./.venv
13-
COPY --from=builder /flare-ai-core/src ./src
14-
COPY --from=builder /flare-ai-core/pyproject.toml .
15-
COPY --from=builder /flare-ai-core/README.md .
33+
# Setup supervisor configuration
34+
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
1635

1736
# Allow workload operator to override environment variables
1837
LABEL "tee.launch_policy.allow_env_override"="GEMINI_API_KEY,GEMINI_MODEL,WEB3_PROVIDER_URL,WEB3_EXPLORER_URL,SIMULATE_ATTESTATION"
1938
LABEL "tee.launch_policy.log_redirect"="always"
2039

21-
EXPOSE 8080
40+
EXPOSE 80
2241

23-
# Define the entrypoint
24-
ENTRYPOINT ["uv", "run", "start-backend"]
42+
# Start supervisor (which will start both nginx and the backend)
43+
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

README.md

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,106 @@
1-
# AI Core
1+
# Flare AI Core
2+
3+
A confidential computing solution for AI workloads on Google Cloud Platform, supporting both AMD SEV and Intel TDX architectures.
4+
5+
## Prerequisites
6+
7+
- Google Cloud Platform account with access to the `google-hackathon-project`
8+
- Gemini API key
9+
- `gcloud` CLI installed and configured
10+
11+
## Environment Setup
12+
13+
1. Add the following environment variables to your shell configuration file (`~/.bashrc` or `~/.zshrc`):
14+
15+
```bash
16+
export TEE_IMAGE_REFERENCE=ghcr.io/flare-foundation/flare-ai-core:main
17+
export GEMINI_API_KEY=<your-gemini-api-key>
18+
export WEB3_PROVIDER_URL=https://coston2-api.flare.network/ext/C/rpc
19+
export WEB3_EXPLORER_URL=https://coston2-explorer.flare.network/
20+
export TEAM_NAME=<your-team-name>
21+
```
22+
23+
2. Reload your shell configuration:
24+
25+
```bash
26+
source ~/.bashrc # or ~/.zshrc
27+
```
28+
29+
3. Verify the configuration:
30+
31+
```bash
32+
echo $TEE_IMAGE_REFERENCE # Should output: ghcr.io/flare-foundation/flare-ai-core:main
33+
```
34+
35+
## Deployment
36+
37+
### AMD SEV Deployment
38+
39+
Deploy an AMD SEV-enabled instance with the following configuration:
40+
41+
```bash
42+
gcloud compute instances create ai-core-$TEAM_NAME \
43+
--project=google-hackathon-project \
44+
--zone=us-central1-c \
45+
--machine-type=n2d-standard-2 \
46+
--network-interface=network-tier=PREMIUM,nic-type=GVNIC,stack-type=IPV4_ONLY,subnet=default \
47+
--metadata=tee-image-reference=$TEE_IMAGE_REFERENCE,\
48+
tee-container-log-redirect=true,\
49+
tee-env-GEMINI_API_KEY=$GEMINI_API_KEY,\
50+
tee-env-GEMINI_MODEL=gemini-1.5-flash,\
51+
tee-env-WEB3_PROVIDER_URL=$WEB3_PROVIDER_URL,\
52+
tee-env-SIMULATE_ATTESTATION=false \
53+
--maintenance-policy=MIGRATE \
54+
--provisioning-model=STANDARD \
55+
--service-account=confidential-sa@flare-network-sandbox.iam.gserviceaccount.com \
56+
--scopes=https://www.googleapis.com/auth/cloud-platform \
57+
--min-cpu-platform="AMD Milan" \
58+
--tags=flare-ai-core,http-server,https-server \
59+
--create-disk=auto-delete=yes,\
60+
boot=yes,\
61+
device-name=ai-core-$TEAM_NAME,\
62+
image=projects/confidential-space-images/global/images/confidential-space-debug-250100,\
63+
mode=rw,\
64+
size=11,\
65+
type=pd-standard \
66+
--shielded-secure-boot \
67+
--shielded-vtpm \
68+
--shielded-integrity-monitoring \
69+
--labels=goog-ec-src=vm_add-gcloud \
70+
--reservation-affinity=any \
71+
--confidential-compute-type=SEV
72+
```
73+
74+
### Intel TDX Deployment
75+
76+
For Intel TDX machines, use this alternative configuration:
77+
78+
```bash
79+
gcloud compute instances create ai-core-$TEAM_NAME \
80+
--project=google-hackathon-project \
81+
--machine-type=c3-standard-4 \
82+
--maintenance-policy=TERMINATE \
83+
--zone=us-central1-c \
84+
--network-interface=network-tier=PREMIUM,nic-type=GVNIC,stack-type=IPV4_ONLY,subnet=default \
85+
--metadata=tee-image-reference=$TEE_IMAGE_REFERENCE,\
86+
tee-container-log-redirect=true,\
87+
tee-env-GEMINI_API_KEY=$GEMINI_API_KEY,\
88+
tee-env-GEMINI_MODEL=gemini-1.5-flash,\
89+
tee-env-WEB3_PROVIDER_URL=$WEB3_PROVIDER_URL,\
90+
tee-env-SIMULATE_ATTESTATION=false \
91+
--provisioning-model=STANDARD \
92+
--service-account=confidential-sa@flare-network-sandbox.iam.gserviceaccount.com \
93+
--scopes=https://www.googleapis.com/auth/cloud-platform \
94+
--tags=flare-ai-core,http-server,https-server \
95+
--create-disk=auto-delete=yes,\
96+
boot=yes,\
97+
device-name=ai-core-$TEAM_NAME,\
98+
image=projects/confidential-space-images/global/images/confidential-space-debug-0-tdxpreview-c38b622,\
99+
mode=rw,\
100+
size=11,\
101+
type=pd-balanced \
102+
--shielded-secure-boot \
103+
--shielded-vtpm \
104+
--shielded-integrity-monitoring \
105+
--confidential-compute-type=TDX
106+
```

chat-ui/src/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const ChatInterface = () => {
2626

2727
const handleSendMessage = async (text) => {
2828
try {
29-
const response = await fetch(`${process.env.REACT_APP_API_URL}/api/routes/chat/`, {
29+
const response = await fetch('api/routes/chat/', {
3030
method: 'POST',
3131
headers: {
3232
'Content-Type': 'application/json',

nginx.conf

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
server {
2+
listen 80 default_server;
3+
listen [::]:80 default_server;
4+
5+
root /usr/share/nginx/html;
6+
index index.html;
7+
8+
# Enable gzip compression
9+
gzip on;
10+
gzip_vary on;
11+
gzip_min_length 10240;
12+
gzip_proxied expired no-cache no-store private auth;
13+
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
14+
gzip_disable "MSIE [1-6]\.";
15+
16+
# Security headers
17+
add_header X-Frame-Options "SAMEORIGIN";
18+
add_header X-XSS-Protection "1; mode=block";
19+
add_header X-Content-Type-Options "nosniff";
20+
add_header Referrer-Policy "strict-origin-when-cross-origin";
21+
22+
# Cache static assets
23+
location /static/ {
24+
expires 1y;
25+
add_header Cache-Control "public, no-transform";
26+
}
27+
28+
# Handle React routing
29+
location / {
30+
try_files $uri $uri/ /index.html;
31+
32+
# Don't cache index.html
33+
add_header Cache-Control "no-store, no-cache, must-revalidate";
34+
}
35+
36+
# API proxy configuration
37+
location /api/ {
38+
proxy_pass http://127.0.0.1:8080;
39+
proxy_http_version 1.1;
40+
proxy_set_header Upgrade $http_upgrade;
41+
proxy_set_header Connection 'upgrade';
42+
proxy_set_header Host $host;
43+
proxy_set_header X-Real-IP $remote_addr;
44+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45+
proxy_set_header X-Forwarded-Proto $scheme;
46+
proxy_cache_bypass $http_upgrade;
47+
48+
# CORS settings
49+
add_header 'Access-Control-Allow-Origin' '*';
50+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
51+
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
52+
53+
# Handle preflight requests
54+
if ($request_method = 'OPTIONS') {
55+
add_header 'Access-Control-Allow-Origin' '*';
56+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
57+
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
58+
add_header 'Access-Control-Max-Age' 1728000;
59+
add_header 'Content-Type' 'text/plain charset=UTF-8';
60+
add_header 'Content-Length' 0;
61+
return 204;
62+
}
63+
}
64+
65+
# Handle 404 errors
66+
error_page 404 /index.html;
67+
}

src/flare_ai_core/settings.py

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,21 @@
1818
class Settings(BaseSettings):
1919
"""
2020
Application settings model that provides configuration for all components.
21-
22-
Attributes:
23-
simulate_attestation (bool): Flag to enable/disable attestation simulation.
24-
Defaults to False.
25-
26-
cors_origins (list[str]): List of allowed CORS origins.
27-
Defaults to ["*"] allowing all origins.
28-
29-
gemini_api_key (str): API key for accessing Google's Gemini AI service.
30-
Must be provided via environment variable or .env file.
31-
Defaults to empty string.
32-
33-
gemini_model (str): The Gemini model identifier to use.
34-
Defaults to "gemini-1.5-flash".
35-
36-
api_version (str): Version string for the API.
37-
Defaults to "v1".
38-
39-
web3_provider_url (str): URL for the Flare Network Web3 provider.
40-
Defaults to Coston2 testnet RPC endpoint:
41-
"https://coston2-api.flare.network/ext/C/rpc"
42-
43-
web3_explorer_url (str): URL for the Flare Network block explorer.
44-
Defaults to Coston2 testnet explorer:
45-
"https://coston2-explorer.flare.network/"
46-
47-
Environment Variables:
48-
All settings can be overridden by environment variables with the same name
49-
in uppercase, e.g.:
50-
- SIMULATE_ATTESTATION
51-
- CORS_ORIGINS
52-
- GEMINI_API_KEY
53-
- GEMINI_MODEL
54-
- API_VERSION
55-
- WEB3_PROVIDER_URL
56-
- WEB3_EXPLORER_URL
5721
"""
5822

23+
# Flag to enable/disable attestation simulation
5924
simulate_attestation: bool = False
25+
# Restrict backend listener to specific IPs
6026
cors_origins: list[str] = ["*"]
27+
# API key for accessing Google's Gemini AI service
6128
gemini_api_key: str = ""
29+
# The Gemini model identifier to use
6230
gemini_model: str = "gemini-1.5-flash"
31+
# API version to use at the backend
6332
api_version: str = "v1"
33+
# URL for the Flare Network RPC provider
6434
web3_provider_url: str = "https://coston2-api.flare.network/ext/C/rpc"
35+
# URL for the Flare Network block explorer
6536
web3_explorer_url: str = "https://coston2-explorer.flare.network/"
6637

6738
model_config = SettingsConfigDict(

supervisord.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[supervisord]
2+
nodaemon=true
3+
user=root
4+
5+
[program:nginx]
6+
command=nginx -g 'daemon off;'
7+
autostart=true
8+
autorestart=true
9+
stdout_logfile=/dev/stdout
10+
stdout_logfile_maxbytes=0
11+
stderr_logfile=/dev/stderr
12+
stderr_logfile_maxbytes=0
13+
14+
[program:backend]
15+
command=uv run start-backend
16+
directory=/app
17+
autostart=true
18+
autorestart=true
19+
stdout_logfile=/dev/stdout
20+
stdout_logfile_maxbytes=0
21+
stderr_logfile=/dev/stderr
22+
stderr_logfile_maxbytes=0

0 commit comments

Comments
 (0)