ui selector
This commit is contained in:
@@ -95,10 +95,12 @@ services:
|
|||||||
- "80:80"
|
- "80:80"
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./landing.html:/etc/nginx/landing.html:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
- django
|
- django
|
||||||
- fastapi
|
- fastapi
|
||||||
- timeline
|
- timeline
|
||||||
|
- chunker
|
||||||
- minio
|
- minio
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -162,6 +164,17 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ../ui/timeline/src:/app/src
|
- ../ui/timeline/src:/app/src
|
||||||
|
|
||||||
|
chunker:
|
||||||
|
build:
|
||||||
|
context: ../ui/chunker
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- "5174:5174"
|
||||||
|
environment:
|
||||||
|
VITE_ALLOWED_HOSTS: ${VITE_ALLOWED_HOSTS:-}
|
||||||
|
volumes:
|
||||||
|
- ../ui/chunker/src:/app/src
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
redis-data:
|
redis-data:
|
||||||
|
|||||||
107
ctrl/landing.html
Normal file
107
ctrl/landing.html
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>MPR</title>
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
|
||||||
|
background: #0f0f0f;
|
||||||
|
color: #e0e0e0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 600px;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.subtitle {
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
.cards {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
a.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 2rem 1.5rem;
|
||||||
|
background: #141414;
|
||||||
|
border: 1px solid #2a2a2a;
|
||||||
|
border-radius: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #e0e0e0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
a.card:hover {
|
||||||
|
border-color: #3b82f6;
|
||||||
|
background: #1a1a2e;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
.card-icon {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.card-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.card-desc {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.links {
|
||||||
|
margin-top: 2rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.links a {
|
||||||
|
color: #555;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
.links a:hover { color: #94a3b8; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>MPR</h1>
|
||||||
|
<p class="subtitle">Media Processing & Review</p>
|
||||||
|
<div class="cards">
|
||||||
|
<a class="card" href="/timeline/">
|
||||||
|
<div class="card-icon">▶</div>
|
||||||
|
<div class="card-title">Timeline</div>
|
||||||
|
<div class="card-desc">Browse assets, trim, transcode</div>
|
||||||
|
</a>
|
||||||
|
<a class="card" href="/chunker/">
|
||||||
|
<div class="card-icon">▦</div>
|
||||||
|
<div class="card-title">Chunker</div>
|
||||||
|
<div class="card-desc">Split media into segments, pipeline visualization</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="links">
|
||||||
|
<a href="/admin/">Admin</a>
|
||||||
|
<a href="/api/graphql">GraphQL</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -21,6 +21,10 @@ http {
|
|||||||
server timeline:5173;
|
server timeline:5173;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upstream chunker {
|
||||||
|
server chunker:5174;
|
||||||
|
}
|
||||||
|
|
||||||
upstream minio {
|
upstream minio {
|
||||||
server minio:9000;
|
server minio:9000;
|
||||||
}
|
}
|
||||||
@@ -29,6 +33,12 @@ http {
|
|||||||
listen 80;
|
listen 80;
|
||||||
server_name mpr.local.ar;
|
server_name mpr.local.ar;
|
||||||
|
|
||||||
|
# Landing page
|
||||||
|
location = / {
|
||||||
|
root /etc/nginx;
|
||||||
|
try_files /landing.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
# Django Admin
|
# Django Admin
|
||||||
location /admin {
|
location /admin {
|
||||||
proxy_pass http://django;
|
proxy_pass http://django;
|
||||||
@@ -54,7 +64,7 @@ http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Timeline UI
|
# Timeline UI
|
||||||
location /ui {
|
location /timeline/ {
|
||||||
proxy_pass http://timeline;
|
proxy_pass http://timeline;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@@ -62,8 +72,17 @@ http {
|
|||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Vite HMR websocket
|
# Chunker UI
|
||||||
location /@vite {
|
location /chunker/ {
|
||||||
|
proxy_pass http://chunker;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Vite HMR websocket (timeline)
|
||||||
|
location /timeline/@vite {
|
||||||
proxy_pass http://timeline;
|
proxy_pass http://timeline;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
@@ -71,6 +90,15 @@ http {
|
|||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Vite HMR websocket (chunker)
|
||||||
|
location /chunker/@vite {
|
||||||
|
proxy_pass http://chunker;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
# Media files - proxied from MinIO (local) or S3 (AWS)
|
# Media files - proxied from MinIO (local) or S3 (AWS)
|
||||||
location /media/in/ {
|
location /media/in/ {
|
||||||
proxy_pass http://minio/mpr-media-in/;
|
proxy_pass http://minio/mpr-media-in/;
|
||||||
@@ -81,13 +109,5 @@ http {
|
|||||||
proxy_pass http://minio/mpr-media-out/;
|
proxy_pass http://minio/mpr-media-out/;
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Default to Timeline UI
|
|
||||||
location / {
|
|
||||||
proxy_pass http://timeline;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
ui/chunker/.dockerignore
Normal file
2
ui/chunker/.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
12
ui/chunker/Dockerfile
Normal file
12
ui/chunker/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 5174
|
||||||
|
|
||||||
|
CMD ["npm", "run", "dev"]
|
||||||
@@ -2,11 +2,15 @@ import { defineConfig } from "vite";
|
|||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
base: "/chunker/",
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
server: {
|
server: {
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
port: 5174,
|
port: 5174,
|
||||||
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
|
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
|
||||||
|
hmr: {
|
||||||
|
path: "/chunker/@vite/client",
|
||||||
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://fastapi:8702",
|
target: "http://fastapi:8702",
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ import { defineConfig } from "vite";
|
|||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
base: "/timeline/",
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
server: {
|
server: {
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
port: 5173,
|
port: 5173,
|
||||||
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
|
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
|
||||||
|
hmr: {
|
||||||
|
path: "/timeline/@vite/client",
|
||||||
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://fastapi:8702",
|
target: "http://fastapi:8702",
|
||||||
|
|||||||
Reference in New Issue
Block a user