Files
AutoGPT/autogpt_platform/frontend/src/lib/env-config.ts
Zamil Majdy 4bfeddc03d feat(platform/docker): add frontend service to docker-compose with env config improvements (#10615)
## Summary
This PR adds the frontend service to the Docker Compose configuration,
enabling `docker compose up` to run the complete stack, including the
frontend. It also implements comprehensive environment variable
improvements, unified .env file support, and fixes Docker networking
issues.

## Key Changes

### 🐳 Docker Compose Improvements
- **Added frontend service** to `docker-compose.yml` and
`docker-compose.platform.yml`
- **Production build**: Uses `pnpm build + serve` instead of dev server
for better stability and lower memory usage
- **Service dependencies**: Frontend now waits for backend services
(`rest_server`, `websocket_server`) to be ready
- **YAML anchors**: Implemented DRY configuration to avoid duplicating
environment values

### 📁 Unified .env File Support
- **Frontend .env loading**: Automatically loads `.env` file during
Docker build and runtime
- **Backend .env loading**: Optional `.env` file support with fallback
to sensible defaults in `settings.py`
- **Single source of truth**: All `NEXT_PUBLIC_*` and API keys can be
defined in respective `.env` files
- **Docker integration**: Updated `.dockerignore` to include `.env`
files in build context
- **Git tracking**: Frontend and backend `.env` files are now trackable
(removed from gitignore)

### 🔧 Environment Variable Architecture
- **Dual environment strategy**: 
- Server-side code uses Docker service names
(`http://rest_server:8006/api`)
  - Client-side code uses localhost URLs (`http://localhost:8006/api`)
- **Comprehensive config**: Added build args and runtime environment
variables
- **Network compatibility**: Fixes connection issues between frontend
and backend containers
- **Shared backend variables**: Common environment variables (service
hosts, auth settings) centralized using YAML anchors

### 🛠️ Code Improvements
- **Centralized env-config helper** (`/frontend/src/lib/env-config.ts`)
with server-side priority
- **Updated all frontend code** to use shared environment helpers
instead of direct `process.env` access
- **Consistent API**: All environment variable access now goes through
helper functions
- **Settings.py improvements**: Better defaults for CORS origins and
optional .env file loading

### 🔗 Files Changed
- `docker-compose.yml` & `docker-compose.platform.yml` - Added frontend
service and shared backend env vars
- `frontend/Dockerfile` - Simplified build process to use .env files
directly
- `backend/settings.py` - Optional .env loading and better defaults
- `frontend/src/lib/env-config.ts` - New centralized environment
configuration
- `.dockerignore` - Allow .env files in build context
- `.gitignore` - Updated to allow frontend/backend .env files
- Multiple frontend files - Updated to use env helpers
- Updates to both auto installer scripts to work with the latest setup!

## Benefits
-  **Single command deployment**: `docker compose up` now runs
everything
-  **Better reliability**: Production build reduces memory usage and
crashes
-  **Network compatibility**: Proper container-to-container
communication
-  **Maintainable config**: Centralized environment variable management
with .env files
-  **Development friendly**: Works in both Docker and local development
-  **API key management**: Easy configuration through .env files for
all services
-  **No more manual env vars**: Frontend and backend automatically load
their respective .env files

## Testing
-  Verified Docker service communication works correctly
-  Frontend responds and serves content properly  
-  Environment variables are correctly resolved in both server and
client contexts
-  No connection errors after implementing service dependencies
-  .env file loading works correctly in both build and runtime phases
-  Backend services work with and without .env files present

### Checklist 📋

#### For configuration changes:
- [x] `.env.default` is updated or already compatible with my changes
- [x] `docker-compose.yml` is updated or already compatible with my
changes
- [x] I have included a list of my configuration changes in the PR
description (under **Changes**)

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Lluis Agusti <hi@llu.lu>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Nicholas Tindle <nicholas.tindle@agpt.co>
Co-authored-by: Claude <claude@users.noreply.github.com>
Co-authored-by: Bentlybro <Github@bentlybro.com>
2025-08-14 03:28:18 +00:00

66 lines
2.1 KiB
TypeScript

/**
* Environment configuration helper
*
* Provides unified access to environment variables with server-side priority.
* Server-side code uses Docker service names, client-side falls back to localhost.
*/
import { isServerSide } from "./utils/is-server-side";
/**
* Gets the AGPT server URL with server-side priority
* Server-side: Uses AGPT_SERVER_URL (http://rest_server:8006/api)
* Client-side: Falls back to NEXT_PUBLIC_AGPT_SERVER_URL (http://localhost:8006/api)
*/
export function getAgptServerApiUrl(): string {
// If server-side and server URL exists, use it
if (isServerSide() && process.env.AGPT_SERVER_URL) {
return process.env.AGPT_SERVER_URL;
}
// Otherwise use the public URL
return process.env.NEXT_PUBLIC_AGPT_SERVER_URL || "http://localhost:8006/api";
}
export function getAgptServerBaseUrl(): string {
return getAgptServerApiUrl().replace("/api", "");
}
/**
* Gets the AGPT WebSocket URL with server-side priority
* Server-side: Uses AGPT_WS_SERVER_URL (ws://websocket_server:8001/ws)
* Client-side: Falls back to NEXT_PUBLIC_AGPT_WS_SERVER_URL (ws://localhost:8001/ws)
*/
export function getAgptWsServerUrl(): string {
// If server-side and server URL exists, use it
if (isServerSide() && process.env.AGPT_WS_SERVER_URL) {
return process.env.AGPT_WS_SERVER_URL;
}
// Otherwise use the public URL
return process.env.NEXT_PUBLIC_AGPT_WS_SERVER_URL || "ws://localhost:8001/ws";
}
/**
* Gets the Supabase URL with server-side priority
* Server-side: Uses SUPABASE_URL (http://kong:8000)
* Client-side: Falls back to NEXT_PUBLIC_SUPABASE_URL (http://localhost:8000)
*/
export function getSupabaseUrl(): string {
// If server-side and server URL exists, use it
if (isServerSide() && process.env.SUPABASE_URL) {
return process.env.SUPABASE_URL;
}
// Otherwise use the public URL
return process.env.NEXT_PUBLIC_SUPABASE_URL || "http://localhost:8000";
}
/**
* Gets the Supabase anon key
* Uses NEXT_PUBLIC_SUPABASE_ANON_KEY since anon keys are public and same across environments
*/
export function getSupabaseAnonKey(): string {
return process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "";
}