Skip to content

Commit 213530b

Browse files
MohsinHashmi-DataInnmohsin-wiserclaude
authored
docs(coder): add server deployment guide (#467)
* feat(ui): enhance remember me toggle with neumorphic curved design Improved the "Remember me" toggle on the login page with a more pronounced curved neumorphic design that better matches the design system. Changes: - Increased toggle size (h-7 w-14) for better visibility and proportions - Applied neumorphic shadows: - OFF state: Inset shadow (pressed/recessed appearance) - ON state: Raised shadow with primary gradient background - Enhanced knob styling with gradient and subtle shadow - Improved curve appearance with consistent rounded-full styling - Smoother transitions (300ms) for better visual feedback - Added focus ring for better accessibility The toggle now properly follows the neumorphic design system with: - Dual shadows (light + dark) for depth - Rounded corners matching design guidelines - Primary blue gradient for active state - Soft neumorphic background for inactive state 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ui): ensure toggle has perfect pill-shaped rounded corners - Explicitly set borderRadius: 9999px for perfect rounding - Added overflow: hidden for clean edges - Increased size to h-8/w-16 for better curved appearance - Larger knob (h-6/w-6) for better visibility - Removed focus ring classes that may cause rectangular appearance - Added border-0 to prevent any border issues This ensures the toggle appears as a smooth, curved pill shape without any rectangular appearance. * chore(debug): add console logging to diagnose login redirect issue Added detailed console logs to track: - Login action response and type - Action fulfillment status - Target route for navigation - AccessToken presence in localStorage - Navigate function execution This will help debug why login success message shows but redirect to dashboard is not happening. * feat(ui): use logo green color for input focus border Changed input field focus styling from black to logo green (#21d8aa): - Added 2px green border on focus state - Updated focus shadow to use subtle green tint - Maintains neumorphic inset shadow effect - Error state shows red border for validation This matches the SimpleAccounts brand green color from the logo. * fix(login): remove black outline from input focus, show only green border - Added focus:outline-none to email and password input fields - Removes default browser outline causing double border appearance - Only custom green border (#21d8aa from logo) now shows on focus - Fixes issue where both black and green borders appeared simultaneously 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ui): remove default focus ring from input component - Removed focus-visible:ring-2 and focus-visible:ring-ring classes - Removed focus-visible:ring-offset-2 class - Allows custom neumorphic focus styles without ring interference - Fixes black border appearing on input focus across the app 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(auth): add authorization header to api requests - Added request interceptor to attach accessToken to all api requests - Fixes login redirect loop where checkAuthStatus() was failing - The /rest/user/current call now includes bearer token - Resolves issue where user couldn't navigate to /admin after login 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(login): use replace navigation to prevent history issues - Changed navigate() to navigate(targetRoute, { replace: true }) - Prevents login page from staying in browser history - May help resolve redirect issues after successful login 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(auth): add null check for access token in auth api interceptor - prevent sending 'Bearer null' or 'Bearer undefined' to backend - only add authorization header if access token exists in local storage - fixes login redirect issue where auth check fails immediately after login * fix(auth): improve token validation and add debug logging - add robust token validation in both api and authApi interceptors - check for empty/whitespace-only tokens - add comprehensive debug logging to admin layout component - log token presence, length, and checkAuthStatus responses - helps diagnose login redirect loop issue * fix(backend): resolve hibernate lazy initialization errors Fix multiple 500 errors caused by Hibernate lazy loading issues when serializing entities to JSON after session closes. Backend Changes: - Add @transactional annotations to keep session open during JSON serialization - UserController.currentUser(): Added @transactional and explicit Hibernate.initialize() - CompanyController.getCompanyDetails(): @transactional - CurrencyConversionController.getActiveCurrencyList(): @transactional - BankAccountController.getBankAccountList(): @transactional - RoleModuleController.getModuleListByRoleCode(): @transactional - Add @JsonIgnoreProperties to User entity for Hibernate proxies - Add exception logging to UserController - Add JWT header logging to JwtRequestFilter Frontend Changes: - Fix API_ROOT_URL to route through Vite proxy (config.js) - Add debug logging to axios interceptor (auth_api.js) - Add proxy logging to Vite config - Remove invalid datasetKeyProvider prop from Chart.js components (bank_account, cash_flow, paid_invoices) Testing: - Add Playwright E2E test for login redirect flow Fixes: - Empty sidebar navigation (roleModule 500 error) - Dashboard API failures (company details, currency conversion, bank list) - Login redirect after authentication - React console warnings about invalid DOM props 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * feat(ui): migrate from neumorphic to minimal corporate theme Complete UI redesign following modern SaaS design patterns (Stripe, Linear, OpenAI): BREAKING CHANGES: - Replaced neumorphic soft UI with clean corporate design - Updated all CSS variables from --neu-* to --corp-* - Changed from gray backgrounds (#e8eef5) to white (#ffffff) - Replaced dual shadows with subtle single shadows + borders Core Changes: - index.css: Complete CSS variable rewrite for corporate theme - tailwind.config.js: Added corporate color system and utilities - DESIGN-GUIDE.md: Comprehensive design system documentation - MIGRATION-TO-CORPORATE.md: Step-by-step migration guide - CLAUDE.md: Updated to reference corporate design system Layout Updates: - sidebar.jsx: Fixed visibility bug (removed hidden class), applied corporate styling - header.jsx: Updated to corporate theme with clean borders - admin/index.js: Corporate page header and breadcrumb styling Dashboard Migration: - screen.js: All inline neumorphic styles replaced with corporate variables - style.scss: Complete SCSS rewrite with corporate mixins and classes Design Features: - White/light gray backgrounds for maximum readability - Clean 1px borders with subtle shadows - Professional minimal appearance - Proper hover states and transitions - WCAG AA accessibility compliance - Brand blue (#2064d8) reserved for primary actions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * test(sidebar): update test to match corporate theme active state Changed test assertion from checking amber border to checking blue background + white text, matching the new corporate theme active state styling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * feat(coder): add code-server web ide support - Add official code-server module to Coder template - Configure auto-install of VS Code extensions from devcontainer.json - Remove redundant code-server installation from Dockerfile - Reduces Docker image size and improves Coder integration This enables browser-based VS Code access through Coder's app system with proper authentication and automatic URL handling. * fix(coder): upgrade coder provider to v2.13.1 for code-server compatibility - Update coder provider version from ~> 0.12 to >= 2.5.0 - code-server module requires coder provider >= 2.5.0 - Regenerate .terraform.lock.hcl with upgraded provider versions - Fixes CI/CD template deployment failure * feat(coder): add app shortcuts for frontend, backend, and swagger ui - Add Frontend app (React on port 3000) with healthcheck - Add Backend API app (Spring Boot on port 8080) with healthcheck - Add Swagger UI app for API documentation - Apps appear in Coder workspace UI for easy access - Enables one-click access to running applications * fix(coder): use existing endpoint for backend healthcheck and preserve neu utilities - Change backend healthcheck from /actuator/health to /rest/config/getreleasenumber (actuator endpoint doesn't exist, was causing 404 and unhealthy status) - Add neu-* shadow and color utilities to Tailwind config for backward compatibility (existing screens still use neu classes during migration to corporate theme) Addresses PR review comments on #466 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * docs(coder): add server deployment guide with docker configuration * feat(devcontainer): auto-start frontend and backend on workspace startup - Add automatic startup of Frontend (React + Vite) on port 3000 - Add automatic startup of Backend (Spring Boot) on port 8080 - Servers run in background with logs at /tmp/frontend.log and /tmp/backend.log - Display helpful commands for viewing logs and stopping servers - Prevents duplicate starts if servers are already running 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * feat(coder): make workspace apps optional to avoid confusion - Add 'Enable Workspace Apps' parameter (default: disabled) - Frontend, Backend, and Swagger apps only show when enabled - Prevents confusing unhealthy app links in workspace UI - Users can enable apps via workspace parameters when needed --------- Co-authored-by: Mohsin Hashmi <mhashmi@wiser.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent fd75f83 commit 213530b

3 files changed

Lines changed: 282 additions & 0 deletions

File tree

.coder/DEPLOYMENT.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# Coder Server Deployment Guide
2+
3+
This document describes how to deploy and configure the Coder server for SimpleAccounts-UAE.
4+
5+
## Prerequisites
6+
7+
- Docker and Docker Compose installed
8+
- Domain: `coder.dev.simpleaccounts.io`
9+
- Wildcard DNS: `*.apps.coder.dev.simpleaccounts.io` → server IP
10+
- GitHub OAuth App credentials
11+
12+
## Server Configuration
13+
14+
### 1. Docker Compose Setup
15+
16+
Create `/home/mohsin/coder/docker-compose.yaml`:
17+
18+
```yaml
19+
services:
20+
database:
21+
image: postgres:17
22+
container_name: coder-database-1
23+
environment:
24+
POSTGRES_USER: ${POSTGRES_USER}
25+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
26+
POSTGRES_DB: ${POSTGRES_DB}
27+
volumes:
28+
- coder_coder_data:/var/lib/postgresql/data
29+
healthcheck:
30+
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
31+
interval: 5s
32+
timeout: 5s
33+
retries: 5
34+
restart: unless-stopped
35+
networks:
36+
- coder_network
37+
38+
coder:
39+
image: ghcr.io/coder/coder:latest
40+
container_name: coder-coder-1
41+
depends_on:
42+
database:
43+
condition: service_healthy
44+
environment:
45+
CODER_PG_CONNECTION_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database/${POSTGRES_DB}?sslmode=disable
46+
CODER_HTTP_ADDRESS: 0.0.0.0:7080
47+
CODER_ACCESS_URL: ${CODER_ACCESS_URL}
48+
CODER_WILDCARD_ACCESS_URL: ${CODER_WILDCARD_ACCESS_URL}
49+
CODER_OAUTH2_GITHUB_CLIENT_ID: ${CODER_OAUTH2_GITHUB_CLIENT_ID}
50+
CODER_OAUTH2_GITHUB_CLIENT_SECRET: ${CODER_OAUTH2_GITHUB_CLIENT_SECRET}
51+
CODER_OAUTH2_GITHUB_ALLOWED_ORGS: SimpleAccounts
52+
CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS: true
53+
volumes:
54+
- /var/run/docker.sock:/var/run/docker.sock
55+
# CRITICAL: Add docker group (988) so Terraform can provision workspaces
56+
group_add:
57+
- '988'
58+
labels:
59+
- 'traefik.enable=true'
60+
- 'traefik.http.routers.coder.rule=Host(`coder.dev.simpleaccounts.io`)'
61+
- 'traefik.http.routers.coder.entrypoints=websecure'
62+
- 'traefik.http.routers.coder.tls.certresolver=letsencrypt'
63+
- 'traefik.http.services.coder.loadbalancer.server.port=7080'
64+
# Wildcard apps routing
65+
- 'traefik.http.routers.coder-apps.rule=HostRegexp(`{subdomain:[a-z0-9-]+}.apps.coder.dev.simpleaccounts.io`)'
66+
- 'traefik.http.routers.coder-apps.entrypoints=websecure'
67+
- 'traefik.http.routers.coder-apps.tls.certresolver=letsencrypt'
68+
- 'traefik.http.routers.coder-apps.tls.domains[0].main=apps.coder.dev.simpleaccounts.io'
69+
- 'traefik.http.routers.coder-apps.tls.domains[0].sans=*.apps.coder.dev.simpleaccounts.io'
70+
restart: unless-stopped
71+
networks:
72+
- coder_network
73+
- dev-proxy-network
74+
75+
networks:
76+
coder_network:
77+
name: coder_network
78+
dev-proxy-network:
79+
external: true
80+
81+
volumes:
82+
coder_coder_data:
83+
external: true
84+
```
85+
86+
### 2. Environment Variables
87+
88+
Create `/home/mohsin/coder/.env`:
89+
90+
```env
91+
CODER_ACCESS_URL=https://coder.dev.simpleaccounts.io
92+
CODER_WILDCARD_ACCESS_URL=*.apps.coder.dev.simpleaccounts.io
93+
POSTGRES_USER=coder
94+
POSTGRES_PASSWORD=coder_secure_password_123
95+
POSTGRES_DB=coder
96+
CODER_OAUTH2_GITHUB_CLIENT_ID=<your-github-oauth-client-id>
97+
CODER_OAUTH2_GITHUB_CLIENT_SECRET=<your-github-oauth-client-secret>
98+
```
99+
100+
### 3. Important Configuration Notes
101+
102+
#### Docker Socket Access
103+
104+
The `group_add: ["988"]` setting is **CRITICAL**. It adds the docker group to the Coder container so Terraform's Docker provider can provision workspaces. Without this, workspace creation will fail with:
105+
106+
```
107+
Error: permission denied while trying to connect to the Docker daemon socket
108+
```
109+
110+
#### Wildcard Access URL
111+
112+
The `CODER_WILDCARD_ACCESS_URL` enables subdomain-based workspace applications. Without this, apps with `subdomain = true` will show a warning and won't be accessible.
113+
114+
## Deployment Steps
115+
116+
1. **Create directory structure**:
117+
118+
```bash
119+
mkdir -p /home/mohsin/coder
120+
cd /home/mohsin/coder
121+
```
122+
123+
2. **Copy configuration files** (docker-compose.yaml and .env)
124+
125+
3. **Create database volume** (if first time):
126+
127+
```bash
128+
docker volume create coder_coder_data
129+
```
130+
131+
4. **Start Coder**:
132+
133+
```bash
134+
docker compose up -d
135+
```
136+
137+
5. **Verify**:
138+
```bash
139+
docker compose logs -f coder
140+
```
141+
142+
## Updating Coder
143+
144+
To update to the latest Coder version:
145+
146+
```bash
147+
cd /home/mohsin/coder
148+
docker compose pull
149+
docker compose up -d
150+
```
151+
152+
## Troubleshooting
153+
154+
### Workspace Creation Fails with Docker Permission Error
155+
156+
**Symptom**: `Error: permission denied while trying to connect to the Docker daemon socket`
157+
158+
**Solution**: Ensure `group_add: ["988"]` is in docker-compose.yaml
159+
160+
**Verify**:
161+
162+
```bash
163+
docker exec coder-coder-1 id
164+
# Should show: groups=988,1000(coder)
165+
```
166+
167+
### Subdomain Apps Show Warning
168+
169+
**Symptom**: "One or more apps in this workspace have subdomain = true, but subdomain applications are not configured"
170+
171+
**Solution**: Ensure `CODER_WILDCARD_ACCESS_URL` is set in .env and DNS wildcard is configured
172+
173+
**Verify**:
174+
175+
```bash
176+
docker exec coder-coder-1 env | grep WILDCARD
177+
# Should show: CODER_WILDCARD_ACCESS_URL=*.apps.coder.dev.simpleaccounts.io
178+
179+
dig +short test.apps.coder.dev.simpleaccounts.io
180+
# Should return server IP
181+
```
182+
183+
## Template Deployment
184+
185+
The workspace template is automatically deployed via GitHub Actions when changes are pushed to `develop` or `main` branches. See `.github/workflows/coder-template-push.yml`.
186+
187+
## Backup
188+
189+
The Coder database is stored in the `coder_coder_data` Docker volume. To backup:
190+
191+
```bash
192+
docker run --rm \
193+
-v coder_coder_data:/source \
194+
-v $(pwd):/backup \
195+
alpine \
196+
tar czf /backup/coder-backup-$(date +%Y%m%d).tar.gz -C /source .
197+
```
198+
199+
## Restore
200+
201+
To restore from backup:
202+
203+
```bash
204+
docker volume create coder_coder_data
205+
docker run --rm \
206+
-v coder_coder_data:/target \
207+
-v $(pwd):/backup \
208+
alpine \
209+
tar xzf /backup/coder-backup-YYYYMMDD.tar.gz -C /target
210+
```

.coder/template.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ data "coder_parameter" "git_clone_url" {
4040
icon = "/icon/git.svg"
4141
}
4242

43+
data "coder_parameter" "enable_workspace_apps" {
44+
name = "enable_workspace_apps"
45+
display_name = "Enable Workspace Apps"
46+
description = "Show app shortcuts for Frontend, Backend API, and Swagger UI. Only enable if you're running these services."
47+
type = "bool"
48+
default = "false"
49+
mutable = true
50+
icon = "/icon/apps.svg"
51+
}
52+
4353
# Docker provider configuration
4454
provider "docker" {
4555
host = "unix:///var/run/docker.sock"
@@ -394,7 +404,10 @@ module "code-server" {
394404
}
395405

396406
# Frontend application (React + Vite on port 3000)
407+
# Only shown if workspace apps are enabled via parameter
397408
resource "coder_app" "frontend" {
409+
count = data.coder_parameter.enable_workspace_apps.value == "true" ? 1 : 0
410+
398411
agent_id = coder_agent.main.id
399412
slug = "frontend"
400413
display_name = "Frontend (React)"
@@ -411,7 +424,10 @@ resource "coder_app" "frontend" {
411424
}
412425

413426
# Backend API application (Spring Boot on port 8080)
427+
# Only shown if workspace apps are enabled via parameter
414428
resource "coder_app" "backend" {
429+
count = data.coder_parameter.enable_workspace_apps.value == "true" ? 1 : 0
430+
415431
agent_id = coder_agent.main.id
416432
slug = "backend"
417433
display_name = "Backend API"
@@ -428,7 +444,10 @@ resource "coder_app" "backend" {
428444
}
429445

430446
# Swagger UI for API documentation
447+
# Only shown if workspace apps are enabled via parameter
431448
resource "coder_app" "swagger" {
449+
count = data.coder_parameter.enable_workspace_apps.value == "true" ? 1 : 0
450+
432451
agent_id = coder_agent.main.id
433452
slug = "swagger"
434453
display_name = "API Docs (Swagger)"

.devcontainer/post-start.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,56 @@ echo ""
310310
echo "MCP Servers (pre-installed):"
311311
echo " SonarQube - Code quality analysis (~/.local/share/mcp-servers/)"
312312
echo ""
313+
314+
# =============================================================================
315+
# Auto-start Frontend and Backend Development Servers
316+
# =============================================================================
317+
echo "🚀 Starting development servers..."
318+
319+
# Start Backend (Spring Boot)
320+
if [ -f "apps/backend/mvnw" ]; then
321+
if ! pgrep -f "spring-boot:run" > /dev/null; then
322+
echo "☕ Starting Backend API (Spring Boot) on port 8080..."
323+
cd apps/backend
324+
nohup ./mvnw spring-boot:run > /tmp/backend.log 2>&1 &
325+
echo "✅ Backend started (logs: /tmp/backend.log)"
326+
cd ../..
327+
else
328+
echo "✅ Backend already running"
329+
fi
330+
else
331+
echo "⚠️ Backend mvnw not found, skipping auto-start"
332+
fi
333+
334+
# Start Frontend (Vite)
335+
if [ -f "apps/frontend/package.json" ]; then
336+
if ! pgrep -f "vite" > /dev/null; then
337+
echo "⚛️ Starting Frontend (React + Vite) on port 3000..."
338+
cd apps/frontend
339+
nohup npm start > /tmp/frontend.log 2>&1 &
340+
echo "✅ Frontend started (logs: /tmp/frontend.log)"
341+
cd ../..
342+
else
343+
echo "✅ Frontend already running"
344+
fi
345+
else
346+
echo "⚠️ Frontend package.json not found, skipping auto-start"
347+
fi
348+
349+
echo ""
350+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
351+
echo "🎯 Development Servers:"
352+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
353+
echo " Frontend: http://localhost:3000 (React + Vite)"
354+
echo " Backend: http://localhost:8080 (Spring Boot)"
355+
echo " Swagger: http://localhost:8080/swagger-ui.html"
356+
echo ""
357+
echo "📋 View logs:"
358+
echo " Frontend: tail -f /tmp/frontend.log"
359+
echo " Backend: tail -f /tmp/backend.log"
360+
echo ""
361+
echo "🛑 Stop servers:"
362+
echo " pkill -f vite (stop frontend)"
363+
echo " pkill -f spring-boot:run (stop backend)"
364+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
365+
echo ""

0 commit comments

Comments
 (0)