Skip to content

Commit 944b911

Browse files
authored
Merge pull request #75 from adn8naiagent/refactor-unified-fe-be
Unified single-container architecture
2 parents 03e6977 + 08980a5 commit 944b911

21 files changed

Lines changed: 377 additions & 419 deletions

.dockerignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.env
2+
.git
3+
.github
4+
docs
5+
*.md
6+
backend/venv
7+
backend/__pycache__
8+
backend/*.pyc
9+
backend/data/sessions
10+
backend/data/fastf1-cache
11+
backend/data/pit_loss_raw.json
12+
frontend/node_modules
13+
frontend/.next
14+
frontend/out

.env.example

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# F1 Replay Timing — Environment Variables
2+
# Copy to .env and fill in your values
3+
4+
PORT=8000
5+
DATA_DIR=/data
6+
7+
# Storage: "local" (default) or "r2"
8+
# Local stores computed session data on disk. R2 reads pre-computed data from Cloudflare R2.
9+
STORAGE_MODE=local
10+
11+
# Cloudflare R2 (only needed when STORAGE_MODE=r2)
12+
R2_ACCOUNT_ID=
13+
R2_ACCESS_KEY_ID=
14+
R2_SECRET_ACCESS_KEY=
15+
R2_BUCKET_NAME=f1timingdata
16+
17+
# Optional — authentication
18+
# AUTH_ENABLED=true
19+
# AUTH_PASSPHRASE=your-passphrase
20+
21+
# Optional — photo sync feature (requires OpenRouter API key)
22+
# OPENROUTER_API_KEY=your-key-here
23+
24+
# Only needed for pre-compute script (not required at runtime)
25+
# FASTF1_CACHE_DIR=/data/fastf1-cache

.github/workflows/pr-checks.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,3 @@ jobs:
3030
- name: npm audit
3131
run: npm audit --audit-level=high
3232

33-
osv-scan:
34-
name: Google OSV Scan
35-
runs-on: ubuntu-latest
36-
steps:
37-
- uses: actions/checkout@v4
38-
39-
- uses: google/osv-scanner-action/osv-scanner-action@v2
40-
with:
41-
scan-args: |-
42-
--recursive
43-
.
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
name: Publish Docker Images
1+
name: Publish Docker Image
22

33
on:
4-
push:
5-
tags:
6-
- "v*"
7-
branches:
8-
- dev # TEMPORARY: remove before release
4+
release:
5+
types: [published]
96

107
env:
118
REGISTRY: ghcr.io
9+
IMAGE_NAME: f1replaytiming
1210

1311
jobs:
1412
build-and-push:
@@ -17,14 +15,6 @@ jobs:
1715
contents: read
1816
packages: write
1917

20-
strategy:
21-
matrix:
22-
include:
23-
- image: f1replaytiming-backend
24-
context: ./backend
25-
- image: f1replaytiming-frontend
26-
context: ./frontend
27-
2818
steps:
2919
- name: Checkout
3020
uses: actions/checkout@v4
@@ -40,7 +30,7 @@ jobs:
4030
id: meta
4131
uses: docker/metadata-action@v5
4232
with:
43-
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.image }}
33+
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
4434
tags: |
4535
type=semver,pattern={{version}}
4636
type=semver,pattern={{major}}.{{minor}}
@@ -52,11 +42,10 @@ jobs:
5242
- name: Build and push
5343
uses: docker/build-push-action@v6
5444
with:
55-
context: ${{ matrix.context }}
45+
context: .
5646
push: true
5747
tags: ${{ steps.meta.outputs.tags }}
5848
labels: ${{ steps.meta.outputs.labels }}
59-
build-args: ${{ matrix.build-args || '' }}
6049
platforms: linux/amd64,linux/arm64
6150
cache-from: type=gha
6251
cache-to: type=gha,mode=max

CHANGELOG.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,46 @@
22

33
All notable changes to F1 Replay Timing will be documented in this file.
44

5+
## 2.0.0
6+
7+
### Migrating from v1.x
8+
9+
The Docker image has changed. The old `f1replaytiming-backend` and `f1replaytiming-frontend` images will no longer receive updates. The new image is `ghcr.io/adn8naiagent/f1replaytiming:latest` (single unified image).
10+
11+
To migrate:
12+
1. Pull the new image: `docker pull ghcr.io/adn8naiagent/f1replaytiming:latest`
13+
2. Copy `.env.example` to `.env` and configure (most defaults work out of the box)
14+
3. Replace your `docker-compose.yml` with the one from the repo. It's now a single service on one port
15+
4. `docker compose up`
16+
17+
You no longer need `NEXT_PUBLIC_API_URL`, `FRONTEND_URL`, or any CORS settings. Your session data volume carries over as-is, no reprocessing needed.
18+
19+
### Breaking Changes
20+
- **Single container architecture** — frontend and backend are now merged into a single Docker container serving everything from one port. The separate frontend and backend containers have been removed
21+
- **Simplified configuration** — all config is now in a single `.env` file. `NEXT_PUBLIC_API_URL`, `FRONTEND_URL`, and CORS configuration are no longer needed
22+
- **Static frontend** — Next.js switched from `output: 'standalone'` to `output: 'export'`, producing static HTML/CSS/JS served by FastAPI. No Node.js runtime in the final image
23+
- **URL format change** — dynamic routes (`/replay/2026/5`) replaced with query parameters (`/replay?year=2026&round=5&type=R`). Old URLs redirect automatically
24+
25+
### Improvements
26+
- **No CORS** — frontend and API are the same origin, eliminating all cross-origin issues
27+
- **Reverse proxy friendly** — single port means Traefik, nginx, and Cloudflare tunnels just work with no special configuration
28+
- **WebSocket reliability** — same-origin WebSocket connections no longer break behind TLS termination or mixed protocol proxies
29+
- **Screen wake lock** — prevents screen dimming and device sleep during replay playback and live sessions
30+
31+
---
32+
33+
## 1.3.2.2
34+
35+
### Fixes
36+
- **Replay timing drift** — replaced fixed-duration sleeps with wall-clock-anchored playback to prevent timing drift during sessions (contributed by [@stephenwilley](https://github.com/stephenwilley))
37+
38+
---
39+
540
## 1.3.2.1
641

742
### Fixes
843
- **Lap analysis lap number** — fixed showing incomplete current lap data; now only displays completed laps
9-
- **Mobile lap analysis scroll** — section is now scrollable on mobile
44+
1045

1146
---
1247

Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# ── Stage 1: Build frontend ──
2+
FROM node:20-alpine AS frontend
3+
WORKDIR /app
4+
COPY frontend/package.json frontend/package-lock.json* ./
5+
RUN npm ci
6+
COPY frontend/ ./
7+
RUN npm run build
8+
# Produces /app/out/ with static HTML/CSS/JS
9+
10+
# ── Stage 2: Production ──
11+
FROM python:3.11-slim
12+
13+
WORKDIR /app
14+
15+
# System deps (numpy/pandas, HEIC support)
16+
RUN apt-get update && apt-get install -y --no-install-recommends \
17+
gcc g++ libheif-dev && \
18+
rm -rf /var/lib/apt/lists/*
19+
20+
COPY backend/requirements.txt .
21+
RUN pip install --no-cache-dir -r requirements.txt
22+
23+
COPY backend/ .
24+
25+
# Copy frontend build output
26+
COPY --from=frontend /app/out /app/static
27+
28+
# Create data directory
29+
RUN mkdir -p /data/fastf1-cache
30+
31+
EXPOSE 8000
32+
33+
ENV PORT=8000
34+
ENV STATIC_DIR=/app/static
35+
CMD sh -c "cp -n /app/data/pit_loss.json /data/pit_loss.json 2>/dev/null; uvicorn main:app --host 0.0.0.0 --port $PORT"

0 commit comments

Comments
 (0)