Skip to content

Commit 3ccbc81

Browse files
committed
feat(frontend): Implement runtime API URL configuration and entrypoint script
- Add docker-entrypoint.sh to dynamically set API URL at runtime - Update API URL retrieval logic in client.ts and voice.ts to prioritize runtime configuration - Modify Dockerfile.prod to include entrypoint script and ensure executable permissions - Enhance flexibility for API URL configuration in production environments
1 parent bf8805a commit 3ccbc81

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

frontend/Dockerfile.prod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ COPY --from=builder /app/public ./public
3535
COPY --from=builder /app/next.config.ts ./next.config.ts
3636
COPY --from=builder /app/node_modules ./node_modules
3737

38+
# Copy entrypoint script for runtime configuration
39+
COPY docker-entrypoint.sh /docker-entrypoint.sh
40+
RUN chmod +x /docker-entrypoint.sh
41+
3842
EXPOSE 3000
43+
ENTRYPOINT ["/docker-entrypoint.sh"]
3944
CMD ["npm", "run", "start"]
4045

frontend/lib/api/client.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@ import { getAccessToken, isTokenExpired, getRefreshToken, storeTokens, clearToke
77
import { refreshToken as refreshTokenApi } from './auth';
88

99
const getApiBaseUrl = () => {
10-
// Use environment variable (baked in at build time) or fallback to localhost for dev
10+
// Check for runtime config first (injected by docker-entrypoint.sh in production)
11+
if (typeof window !== 'undefined' && (window as any).NEXT_PUBLIC_API_URL) {
12+
const runtimeUrl = (window as any).NEXT_PUBLIC_API_URL;
13+
// Don't use placeholder value
14+
if (runtimeUrl !== '__PLACEHOLDER__') {
15+
return runtimeUrl;
16+
}
17+
}
18+
// Fallback to build-time environment variable or localhost for dev
1119
return process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
1220
};
1321

frontend/lib/api/voice.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,19 @@
44

55
import { getAccessToken } from '../auth/token-storage';
66

7-
// Use environment variable (baked in at build time) or fallback to localhost for dev
8-
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
7+
// Get API base URL from runtime config or build-time env var
8+
const getApiBaseUrl = () => {
9+
// Check for runtime config first (injected by docker-entrypoint.sh in production)
10+
if (typeof window !== 'undefined' && (window as any).NEXT_PUBLIC_API_URL) {
11+
const runtimeUrl = (window as any).NEXT_PUBLIC_API_URL;
12+
// Don't use placeholder value
13+
if (runtimeUrl !== '__PLACEHOLDER__') {
14+
return runtimeUrl;
15+
}
16+
}
17+
// Fallback to build-time environment variable or localhost for dev
18+
return process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
19+
};
920

1021
export interface VoiceTranscript {
1122
role: 'user' | 'assistant';
@@ -41,10 +52,11 @@ export function connectVoiceAgent(
4152
testMode: boolean = false
4253
): WebSocket {
4354
const accessToken = getAccessToken();
55+
const apiBaseUrl = getApiBaseUrl();
4456

4557
// WebSocket URL (ws:// for http, wss:// for https)
46-
const wsProtocol = API_BASE_URL.startsWith('https') ? 'wss' : 'ws';
47-
const wsBaseUrl = API_BASE_URL.replace(/^https?:\/\//, '');
58+
const wsProtocol = apiBaseUrl.startsWith('https') ? 'wss' : 'ws';
59+
const wsBaseUrl = apiBaseUrl.replace(/^https?:\/\//, '');
4860

4961
// Build URL with test mode or API key
5062
let url = `${wsProtocol}://${wsBaseUrl}/api/v1/voice/${agentId}/${actorId}/${sessionId}`;

0 commit comments

Comments
 (0)