Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,21 @@ RUN npm run build
# Production stage - serve with nginx
FROM nginx:alpine

# Install envsubst (part of gettext package)
RUN apk add --no-cache gettext

# Copy built assets from builder stage
COPY --from=builder /app/build /usr/share/nginx/html

# Copy nginx configuration (optional - uses default if not provided)
# COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy nginx configuration template
COPY nginx.conf.template /etc/nginx/conf.d/default.conf.template

# Copy and set up entrypoint script
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Expose port 80
EXPOSE 80

# Start nginx
CMD ["nginx", "-g", "daemon off;"]
# Use custom entrypoint
ENTRYPOINT ["/docker-entrypoint.sh"]
16 changes: 16 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
set -e

# Substitute environment variables in nginx config template
API_SERVER_URL=${API_SERVER_URL:-http://forkspacer-api-server:8080}

echo "Configuring nginx with API_SERVER_URL: $API_SERVER_URL"

# Replace the placeholder with actual API server URL
envsubst '${API_SERVER_URL}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf

# Verify configuration
nginx -t

# Start nginx
exec nginx -g 'daemon off;'
6 changes: 3 additions & 3 deletions helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ spec:
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
env:
- name: REACT_APP_API_BASE_URL
value: {{ include "operator-ui.apiUrl" . | quote }}
- name: API_SERVER_URL
value: {{ .Values.env.API_SERVER_URL | default (include "operator-ui.apiUrl" .) | quote }}
{{- range $key, $value := .Values.env }}
{{- if ne $key "REACT_APP_API_BASE_URL" }}
{{- if and (ne $key "API_SERVER_URL") (ne $key "REACT_APP_API_BASE_URL") }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
Expand Down
6 changes: 5 additions & 1 deletion helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ resources:
memory: 128Mi

env:
REACT_APP_API_BASE_URL: "http://forkspacer-api-server:8080"
# API server URL for nginx server-side proxying (internal cluster service)
API_SERVER_URL: "http://forkspacer-api-server:8080"
# Leave REACT_APP_API_BASE_URL empty to use relative paths (/api/v1)
# which nginx will proxy to API_SERVER_URL
REACT_APP_API_BASE_URL: ""

livenessProbe:
httpGet:
Expand Down
54 changes: 54 additions & 0 deletions nginx.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
server {
listen 80;
server_name _;

root /usr/share/nginx/html;
index index.html;

# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;

# Proxy API requests to backend server
location /api/v1/ {
proxy_pass ${API_SERVER_URL}/api/v1/;
proxy_http_version 1.1;

# Forward headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Buffering
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}

# Serve static files
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}

# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
2 changes: 1 addition & 1 deletion src/components/WorkspaceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const WorkspaceCard: React.FC<WorkspaceCardProps> = ({
</div>
<div className="module-details">
<div className="module-name">{module.name}</div>
<div className="module-type">SERVICE</div>
<div className="module-type">{module.type}</div>
</div>
</div>
<div className="module-status-actions">
Expand Down
19 changes: 8 additions & 11 deletions src/components/WorkspaceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,19 @@ export const WorkspaceList: React.FC = () => {
// Load all modules once
const allModules = await apiService.listModules();

// Group workspaces by namespace and only show modules under the first workspace in each namespace
// Group modules by workspace reference (not namespace)
const modulesMap = new Map<string, Module[]>();
const namespacesProcessed = new Set<string>();

workspacesData.forEach((workspace) => {
const workspaceKey = `${workspace.namespace}-${workspace.name}`;

if (!namespacesProcessed.has(workspace.namespace)) {
// This is the first workspace in this namespace, assign all modules from this namespace
const namespaceModules = allModules.filter(module => module.namespace === workspace.namespace);
modulesMap.set(workspaceKey, namespaceModules);
namespacesProcessed.add(workspace.namespace);
} else {
// Not the first workspace in this namespace, no modules
modulesMap.set(workspaceKey, []);
}
// Filter modules that reference this specific workspace
const workspaceModules = allModules.filter(module =>
module.workspace?.name === workspace.name &&
module.workspace?.namespace === workspace.namespace
);

modulesMap.set(workspaceKey, workspaceModules);
});

setModulesByWorkspace(modulesMap);
Expand Down
1 change: 1 addition & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface Module {
phase: ModulePhase;
message?: string;
hibernated: boolean;
type: string;
workspace?: ModuleWorkspaceReference;
}

Expand Down
Loading