Skip to content

Commit 463abf7

Browse files
author
Saravana Kumar Rajendran
committed
Add shell frontend and nginx gateway for multi-app routing
1 parent 4e690d5 commit 463abf7

12 files changed

Lines changed: 23414 additions & 6 deletions

docker/build_and_push.Dockerfile

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,33 @@ RUN --mount=type=cache,target=/root/.cache/uv \
5252

5353
COPY ./src /app/src
5454

55+
RUN mkdir -p /app/static
56+
5557
ARG VITE_AUTO_LOGIN=true
5658
ENV VITE_AUTO_LOGIN=$VITE_AUTO_LOGIN
57-
58-
COPY src/frontend /tmp/src/frontend
59-
WORKDIR /tmp/src/frontend
60-
6159
ARG VITE_CLERK_AUTH_ENABLED=false
6260
ARG VITE_CLERK_PUBLISHABLE_KEY=""
6361
ENV VITE_CLERK_AUTH_ENABLED=$VITE_CLERK_AUTH_ENABLED
6462
ENV VITE_CLERK_PUBLISHABLE_KEY=$VITE_CLERK_PUBLISHABLE_KEY
6563

64+
COPY src/frontend-shell /tmp/src/frontend-shell
65+
WORKDIR /tmp/src/frontend-shell
66+
6667
RUN --mount=type=cache,target=/root/.npm \
6768
npm ci \
6869
&& ESBUILD_BINARY_PATH="" NODE_OPTIONS="--max-old-space-size=12288" JOBS=1 npm run build \
70+
&& mkdir -p /app/static/frontend-shell \
71+
&& cp -r build/. /app/static/frontend-shell/ \
72+
&& rm -rf /tmp/src/frontend-shell
73+
74+
COPY src/frontend /tmp/src/frontend
75+
WORKDIR /tmp/src/frontend
76+
77+
RUN --mount=type=cache,target=/root/.npm \
78+
npm ci \
79+
&& ESBUILD_BINARY_PATH="" NODE_OPTIONS="--max-old-space-size=12288" JOBS=1 npm run build \
80+
&& mkdir -p /app/static/frontend-app \
81+
&& cp -r build/. /app/static/frontend-app/ \
6982
&& cp -r build /app/src/backend/langflow/frontend \
7083
&& rm -rf /tmp/src/frontend
7184

@@ -83,7 +96,7 @@ FROM python:3.12.3-slim AS runtime
8396

8497
RUN apt-get update \
8598
&& apt-get upgrade -y \
86-
&& apt-get install -y curl git libpq5 gnupg \
99+
&& apt-get install -y curl git libpq5 gnupg nginx supervisor \
87100
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
88101
&& apt-get install -y nodejs \
89102
&& apt-get clean \
@@ -92,6 +105,17 @@ RUN apt-get update \
92105

93106
COPY --from=builder --chown=1000 /app/.venv /app/.venv
94107

108+
RUN mkdir -p /app/docker
109+
110+
COPY --from=builder --chown=1000 /app/static /app/static
111+
COPY --from=builder --chown=1000 /app/src/backend/langflow/frontend /app/src/backend/langflow/frontend
112+
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
113+
COPY docker/nginx/multi-frontend.conf /etc/nginx/conf.d/multi-frontend.conf
114+
COPY docker/supervisord.conf /app/docker/supervisord.conf
115+
116+
RUN rm -f /etc/nginx/conf.d/default.conf \
117+
&& chown -R 1000:0 /app/docker /app/static
118+
95119
# Place executables in the environment at the front of the path
96120
ENV PATH="/app/.venv/bin:$PATH"
97121

@@ -107,5 +131,5 @@ WORKDIR /app
107131
ENV LANGFLOW_HOST=0.0.0.0
108132
ENV LANGFLOW_PORT=7860
109133

110-
CMD ["langflow", "run"]
134+
CMD ["/usr/bin/supervisord", "-c", "/app/docker/supervisord.conf"]
111135

docker/nginx/multi-frontend.conf

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
server {
2+
listen 8080;
3+
listen [::]:8080;
4+
5+
# shell bundle assets
6+
location ^~ /shell-assets/ {
7+
alias /app/static/frontend-shell/shell-assets/;
8+
try_files $uri =404;
9+
add_header Cache-Control "public, max-age=31536000, immutable";
10+
}
11+
12+
# landing/login/org routes served by shell bundle
13+
location = / {
14+
root /app/static/frontend-shell;
15+
add_header Cache-Control "no-cache, no-store, must-revalidate";
16+
add_header Pragma "no-cache";
17+
add_header Expires "0";
18+
try_files /index.html =404;
19+
}
20+
21+
location = /login {
22+
root /app/static/frontend-shell;
23+
add_header Cache-Control "no-cache, no-store, must-revalidate";
24+
add_header Pragma "no-cache";
25+
add_header Expires "0";
26+
try_files /index.html =404;
27+
}
28+
29+
location = /organization {
30+
root /app/static/frontend-shell;
31+
add_header Cache-Control "no-cache, no-store, must-revalidate";
32+
add_header Pragma "no-cache";
33+
add_header Expires "0";
34+
try_files /index.html =404;
35+
}
36+
37+
# backend API proxy
38+
location ^~ /api/ {
39+
proxy_pass http://127.0.0.1:7860/api/;
40+
proxy_http_version 1.1;
41+
proxy_set_header Host $host;
42+
proxy_set_header X-Real-IP $remote_addr;
43+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
44+
proxy_set_header X-Forwarded-Proto $scheme;
45+
}
46+
47+
location = /api {
48+
proxy_pass http://127.0.0.1:7860/api;
49+
proxy_http_version 1.1;
50+
proxy_set_header Host $host;
51+
proxy_set_header X-Real-IP $remote_addr;
52+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
53+
proxy_set_header X-Forwarded-Proto $scheme;
54+
}
55+
56+
location /health {
57+
proxy_pass http://127.0.0.1:7860$request_uri;
58+
}
59+
60+
location /health_check {
61+
proxy_pass http://127.0.0.1:7860$request_uri;
62+
}
63+
64+
# primary app assets
65+
location ^~ /assets/ {
66+
alias /app/static/frontend-app/assets/;
67+
try_files $uri =404;
68+
add_header Cache-Control "public, max-age=31536000, immutable";
69+
}
70+
71+
# catch-all -> flows app
72+
location / {
73+
root /app/static/frontend-app;
74+
add_header Cache-Control "no-cache, no-store, must-revalidate";
75+
add_header Pragma "no-cache";
76+
add_header Expires "0";
77+
try_files $uri $uri/ /index.html;
78+
}
79+
}

docker/nginx/nginx.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
user user;
2+
worker_processes auto;
3+
error_log /tmp/nginx.error.log warn;
4+
pid /tmp/nginx.pid;
5+
6+
events {
7+
worker_connections 1024;
8+
}
9+
10+
http {
11+
include /etc/nginx/mime.types;
12+
default_type application/octet-stream;
13+
14+
sendfile on;
15+
keepalive_timeout 65;
16+
17+
client_max_body_size 100M;
18+
19+
access_log /tmp/nginx.access.log;
20+
21+
include /etc/nginx/conf.d/*.conf;
22+
}

docker/supervisord.conf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[supervisord]
2+
nodaemon=true
3+
logfile=/tmp/supervisord.log
4+
pidfile=/tmp/supervisord.pid
5+
6+
[program:backend]
7+
command=/app/.venv/bin/langflow run
8+
autorestart=true
9+
startsecs=5
10+
redirect_stderr=true
11+
stdout_logfile=/dev/stdout
12+
stdout_logfile_maxbytes=0
13+
stderr_logfile=/dev/stderr
14+
stderr_logfile_maxbytes=0
15+
user=user
16+
environment=LANGFLOW_HOST="0.0.0.0",LANGFLOW_PORT="7860"
17+
18+
[program:nginx]
19+
command=/usr/sbin/nginx -g "daemon off;"
20+
autorestart=true
21+
startsecs=0
22+
redirect_stderr=true
23+
stdout_logfile=/dev/stdout
24+
stdout_logfile_maxbytes=0
25+
stderr_logfile=/dev/stderr
26+
stderr_logfile_maxbytes=0

src/frontend-shell/index.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<base href="/" />
5+
<meta charset="UTF-8" />
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
9+
<meta http-equiv="Pragma" content="no-cache" />
10+
<meta http-equiv="Expires" content="0" />
11+
<link rel="icon" href="/visualaifavicon.png" />
12+
<link rel="manifest" href="/manifest.json" />
13+
<link rel="preconnect" href="https://fonts.googleapis.com" />
14+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15+
<link
16+
href="https://fonts.googleapis.com/css2?family=Chivo:ital,wght@0,100..900;1,100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap"
17+
rel="stylesheet"
18+
/>
19+
<title>Visual AI Agents Builder</title>
20+
</head>
21+
<body id="body" class="dark" style="width: 100%; height: 100%">
22+
<noscript>You need to enable JavaScript to run this app.</noscript>
23+
<div style="width: 100vw; height: 100vh" id="root"></div>
24+
<script type="module" src="/src/main.tsx"></script>
25+
</body>
26+
</html>

0 commit comments

Comments
 (0)