Skip to content

Commit 5f40367

Browse files
authored
Merge branch 'main' into as-ci
2 parents cb57ca1 + 250e9a8 commit 5f40367

File tree

14 files changed

+257
-54
lines changed

14 files changed

+257
-54
lines changed

README.md

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,42 +50,83 @@ This command will:
5050

5151
## Docker Support
5252

53-
### Running Backend with Docker
53+
### Running with Docker
5454

55-
The backend can be run in a Docker container for easy deployment and consistency across environments.
55+
Both frontend and backend can be run in Docker containers for easy deployment and consistency across environments.
5656

5757
#### Using Docker Compose (Recommended)
5858

5959
```bash
60-
# Build and start the backend
60+
# Build and start both frontend and backend
6161
docker-compose up --build
6262

6363
# Run in background
6464
docker-compose up -d --build
6565

66-
# Stop the service
66+
# Stop both services
6767
docker-compose down
68+
69+
# Build and start only backend
70+
docker-compose up backend --build
71+
72+
# Build and start only frontend
73+
docker-compose up frontend --build
74+
```
75+
76+
#### Development Docker Setup
77+
78+
For development with hot reload and backend URL input support:
79+
80+
```bash
81+
# Start development containers
82+
./start-dev.sh
83+
84+
# Or use just commands
85+
just docker-dev # Start with logs
86+
just docker-dev-bg # Start in background
87+
just docker-dev-down # Stop containers
6888
```
6989

90+
**Development Features:**
91+
- Hot reload for both frontend and backend
92+
- Backend URL input field enabled
93+
- Separate ports (Frontend: 3000, Backend: 8080)
94+
- Source code mounted as volumes
95+
7096
#### Using Docker Commands
7197

98+
**Backend:**
7299
```bash
73-
# Build the image
100+
# Build the backend image
74101
docker build -t ah-monitoring-backend ./backend
75102

76-
# Run the container
77-
docker run -p 3000:3000 -v $(pwd)/backend/data:/app/data ah-monitoring-backend
103+
# Run the backend container
104+
docker run -p 8080:8080 -v $(pwd)/backend/data:/app/data ah-monitoring-backend
78105

79106
# Run in background
80-
docker run -d -p 3000:3000 -v $(pwd)/backend/data:/app/data --name ah-backend ah-monitoring-backend
107+
docker run -d -p 8080:8080 -v $(pwd)/backend/data:/app/data --name ah-backend ah-monitoring-backend
108+
```
81109

82-
# Stop the container
83-
docker stop ah-backend
110+
**Frontend:**
111+
```bash
112+
# Build the frontend image
113+
docker build -t ah-monitoring-frontend ./frontend
114+
115+
# Run the frontend container
116+
docker run -p 3000:3000 ah-monitoring-frontend
117+
118+
# Run in background
119+
docker run -d -p 3000:3000 --name ah-frontend ah-monitoring-frontend
120+
121+
# Stop containers
122+
docker stop ah-backend ah-frontend
84123

85-
# Remove the container
86-
docker rm ah-backend
124+
# Remove containers
125+
docker rm ah-backend ah-frontend
87126
```
88127

128+
> **Note**: For production deployment, you'll need a reverse proxy (like nginx) to route `/` to the frontend container and `/api/*` to the backend container, since the production frontend uses relative URLs.
129+
89130
#### Environment Variables with Docker
90131

91132
You can pass environment variables to the Docker container:
@@ -139,19 +180,20 @@ The application consists of two parts:
139180
The frontend connects to the backend via Server-Sent Events (SSE) at `/api/updates`.
140181

141182
**Dynamic Backend URL:**
142-
- The frontend includes a backend URL input field in the header
183+
- The frontend includes a backend URL input field in the header (development builds only)
143184
- Users can connect to any backend instance by entering the URL
144185
- Supports both local and remote backend instances
145186
- Shows connection status (connected/disconnected)
146187
- Defaults to `http://localhost:8080` in development
147188

148189
**Query Parameter Configuration:**
149-
- You can also set the backend URL via query parameter: `?backend_url=http://your-backend:8080`
190+
- You can set the backend URL via query parameter: `?backend_url=http://your-backend:8080`
150191
- Examples:
151192
- `http://localhost:3000?backend_url=http://192.168.1.100:8080`
152193
- `http://localhost:3000?backend_url=https://api.yourdomain.com`
153194
- Query parameter takes precedence over defaults but can still be overridden via the UI input field
154195
- Useful for direct links to specific backend instances or automated testing
196+
- Only available in development builds
155197

156198
**Development Setup:**
157199
- Uses `webpack.dev.js` configuration
@@ -166,16 +208,29 @@ ports:
166208
167209
**Production Setup:**
168210
- Uses `webpack.prod.js` configuration
169-
- Frontend uses relative URLs (e.g., `/api/updates`) by default
170-
- Users can still connect to remote backends via the URL input
211+
- Frontend uses relative URLs (e.g., `/api/updates`)
212+
- Backend URL input field is hidden
171213
- Build with: `yarn build` or `npm run build`
172214

173215
**Usage:**
174-
1. Click the backend URL field in the header
216+
1. Click the backend URL field in the header (development only)
175217
2. Enter the backend URL (e.g., `localhost:8080`, `api.yourdomain.com`, `192.168.1.100:8080`)
176218
3. Click "Connect" to establish the connection
177219
4. The connection status will show green (connected) or red (disconnected)
178220

221+
### Frontend Build Configuration
222+
223+
The frontend uses the `ALLOW_REMOTE_BACKEND` environment variable to control backend URL configuration:
224+
225+
- **Development builds**: `ALLOW_REMOTE_BACKEND=true` (set in `webpack.dev.js`)
226+
- Backend URL input field is visible
227+
- Query parameter backend URL works
228+
229+
- **Production builds**: `ALLOW_REMOTE_BACKEND=false` (set in `webpack.prod.js`)
230+
- Backend URL input field is hidden
231+
- Query parameter backend URL is disabled
232+
- Uses relative URLs only
233+
179234
## Available Commands
180235

181236
- `just install` - Install dependencies for both frontend and backend
@@ -186,3 +241,6 @@ ports:
186241
- `just clean` - Clean build artifacts
187242
- `just run` - Setup everything and run in development mode
188243
- `just run-clean` - Setup everything with clean database and run in development mode
244+
- `just docker-dev` - Start development Docker containers
245+
- `just docker-dev-bg` - Start development Docker containers in background
246+
- `just docker-dev-down` - Stop development Docker containers

deploy.sh

Lines changed: 0 additions & 23 deletions
This file was deleted.

docker-compose.dev.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: '3.8'
2+
3+
services:
4+
backend:
5+
build:
6+
context: ./backend
7+
dockerfile: Dockerfile
8+
ports:
9+
- "127.0.0.1:8080:8080"
10+
environment:
11+
- NODE_ENV=development
12+
- ASSET_HUB_URL=ws://host.docker.internal:63170
13+
- RELAY_CHAIN_URL=ws://host.docker.internal:63168
14+
- PORT=8080
15+
- LOG_LEVEL=debug
16+
volumes:
17+
- ./backend/data:/app/data
18+
- ./backend/src:/app/src # Mount source for hot reload
19+
restart: unless-stopped
20+
21+
frontend:
22+
build:
23+
context: ./frontend
24+
dockerfile: Dockerfile.dev
25+
ports:
26+
- "127.0.0.1:3000:3000"
27+
environment:
28+
- NODE_ENV=development
29+
- ALLOW_REMOTE_BACKEND=true
30+
volumes:
31+
- ./frontend/src:/app/src # Mount source for hot reload
32+
- ./frontend/public:/app/public
33+
restart: unless-stopped
34+
depends_on:
35+
- backend

docker-compose.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ services:
1515
- LOG_LEVEL=info
1616
volumes:
1717
- ./backend/data:/app/data
18-
restart: unless-stopped
18+
restart: unless-stopped
19+
20+
frontend:
21+
build:
22+
context: ./frontend
23+
dockerfile: Dockerfile
24+
ports:
25+
- "127.0.0.1:3000:3000"
26+
restart: unless-stopped
27+
depends_on:
28+
- backend

frontend/.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
dist
3+
.git
4+
*.log
5+
.DS_Store
6+
Thumbs.db

frontend/.yarnrc.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
compressionLevel: mixed
2+
3+
enableGlobalCache: false
4+
5+
enableImmutableInstalls: false
6+
7+
enableProgressBars: false
8+
9+
logFilters:
10+
- code: YN0013
11+
level: discard
12+
13+
nodeLinker: node-modules

frontend/Dockerfile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
FROM node:20-alpine
2+
3+
WORKDIR /app
4+
5+
RUN corepack enable
6+
7+
COPY package.json ./
8+
COPY yarn.lock ./
9+
COPY .yarnrc.yml ./
10+
COPY .yarn ./
11+
12+
# Install dependencies
13+
RUN yarn --immutable
14+
15+
# Copy source code
16+
COPY . .
17+
18+
# Build the frontend
19+
RUN yarn build
20+
21+
# Install a simple static file server
22+
RUN npm install -g serve
23+
24+
# Expose port 3000
25+
EXPOSE 3000
26+
27+
# Serve the built files
28+
CMD ["serve", "-s", "dist", "-l", "3000"]

frontend/Dockerfile.dev

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM node:20-alpine
2+
3+
WORKDIR /app
4+
5+
RUN corepack enable
6+
7+
COPY package.json ./
8+
COPY yarn.lock ./
9+
COPY .yarnrc.yml ./
10+
COPY .yarn ./
11+
12+
# Install dependencies
13+
RUN yarn --immutable
14+
15+
# Copy webpack configs and other build files
16+
COPY webpack*.js ./
17+
COPY tsconfig.json ./
18+
19+
# Expose port 3000
20+
EXPOSE 3000
21+
22+
# Start development server with hot reload
23+
CMD ["yarn", "start"]

frontend/src/App.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ function App() {
3636
<h1>Asset Hub Migration Monitor</h1>
3737
</div>
3838
<div className="header-info">
39-
<BackendUrlInput
40-
currentUrl={backendUrl}
41-
onUrlChange={handleBackendUrlChange}
42-
isConnected={isConnected}
43-
/>
39+
{process.env.ALLOW_REMOTE_BACKEND === 'true' && (
40+
<BackendUrlInput
41+
currentUrl={backendUrl}
42+
onUrlChange={handleBackendUrlChange}
43+
isConnected={isConnected}
44+
/>
45+
)}
4446
<span className="timestamp">Last updated: {new Date().toLocaleString()}</span>
4547
<div className="finalized-heads">
4648
<div className="head-display">

frontend/src/hooks/useEventSource.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@ interface EventSourceProviderProps {
1818
initialBackendUrl?: string;
1919
}
2020

21-
// Get initial backend URL - checks query param first, then defaults
21+
// Get initial backend URL - compile-time security check
2222
const getInitialBackendUrl = () => {
23-
// Check for query parameter first
23+
// Compile-time check: if remote backends are disabled, always use relative URLs
24+
if (process.env.ALLOW_REMOTE_BACKEND !== 'true') {
25+
return '';
26+
}
27+
28+
// Development mode: check for query parameter first
2429
const urlParams = new URLSearchParams(window.location.search);
2530
const backendUrlParam = urlParams.get('backend_url');
2631

2732
if (backendUrlParam) {
2833
return backendUrlParam;
2934
}
3035

31-
// Existing fallback logic
32-
if (process.env.NODE_ENV === 'development') {
33-
return 'http://localhost:8080';
34-
}
35-
// In production, use relative URL by default
36-
return '';
36+
// Development fallback
37+
return 'http://localhost:8080';
3738
};
3839

3940
export const EventSourceProvider: React.FC<EventSourceProviderProps> = ({
@@ -147,6 +148,12 @@ export const EventSourceProvider: React.FC<EventSourceProviderProps> = ({
147148
}, [backendUrl, createEventSource, clearReconnectTimeout]);
148149

149150
const setBackendUrl = useCallback((url: string) => {
151+
// Compile-time check: prevent changing backend URL when remote backends are disabled
152+
if (process.env.ALLOW_REMOTE_BACKEND !== 'true') {
153+
console.warn('Backend URL changes are disabled for security reasons');
154+
return;
155+
}
156+
150157
// Clear any pending reconnection attempts when URL changes
151158
clearReconnectTimeout();
152159
reconnectAttemptsRef.current = 0;

0 commit comments

Comments
 (0)