Skip to content

Commit 477d09f

Browse files
MohsinHashmi-DataInnmohsin-wiserclaude
authored
feat: add traefik systemd service for shared dev server (#385)
* chore: gitignore user-specific docker-compose files & update lockfile - Add pattern to ignore generated docker-compose.*.yml files in proxy dir - Keep docker-compose.user.yml and docker-compose.proxy.yml tracked - Update package-lock.json with typescript peer dependency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add traefik systemd service for shared dev server - add install-traefik-service.sh for systemd setup - add uninstall-traefik-service.sh for cleanup - add traefik.service systemd unit file - update setup-user.sh to check for running proxy - update README.md with systemd installation instructions - remove unused @emotion/styled from vite.config.js optimizeDeps 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Mohsin Hashmi <mhashmi@wiser.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4685d23 commit 477d09f

6 files changed

Lines changed: 272 additions & 20 deletions

File tree

.devcontainer/proxy/README.md

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,31 @@ Each user environment includes:
2121

2222
## Quick Start
2323

24+
### Step 1: Install Traefik (One-time, on the dev server)
25+
26+
```bash
27+
# Install Traefik as a system service (runs on boot)
28+
sudo ./install-traefik-service.sh
29+
```
30+
31+
This installs Traefik as a systemd service that:
32+
- Starts automatically on server boot
33+
- Runs continuously in the background
34+
- Routes traffic to all user dev containers
35+
36+
### Step 2: Setup Your Environment
37+
2438
```bash
25-
# One command to setup everything
2639
./setup-user.sh <your-username>
2740

2841
# Example:
2942
./setup-user.sh alice
3043
```
3144

32-
That's it! The script will:
45+
The script will:
3346

34-
1. Start the Traefik proxy (if not running)
35-
2. Create your isolated environment (devcontainer + database + redis)
47+
1. Create your isolated environment (devcontainer + database + redis)
48+
2. Register with Traefik for routing
3649
3. Print your access URLs
3750

3851
## Architecture
@@ -220,16 +233,43 @@ Then point client DNS to the dev server.
220233
# 192.168.1.100 alice-api.dev.simpleaccounts.local
221234
```
222235

236+
## Traefik Service Management
237+
238+
Once installed via `install-traefik-service.sh`, manage Traefik with:
239+
240+
```bash
241+
# Check status
242+
sudo systemctl status traefik-proxy
243+
244+
# View logs
245+
journalctl -u traefik-proxy -f
246+
247+
# Restart
248+
sudo systemctl restart traefik-proxy
249+
250+
# Stop
251+
sudo systemctl stop traefik-proxy
252+
253+
# Start
254+
sudo systemctl start traefik-proxy
255+
256+
# Uninstall completely
257+
sudo ./uninstall-traefik-service.sh
258+
```
259+
223260
## Files
224261

225-
| File | Purpose |
226-
| ---------------------------- | ------------------------------------ |
227-
| `docker-compose.proxy.yml` | Traefik reverse proxy configuration |
228-
| `docker-compose.user.yml` | Template for user environments |
229-
| `docker-compose.<user>.yml` | Generated user-specific config |
230-
| `setup-user.sh` | User setup script |
231-
| `generate-hosts.sh` | DNS helper for /etc/hosts |
232-
| `idle-shutdown.sh` | Auto-shutdown idle containers |
262+
| File | Purpose |
263+
| ------------------------------ | ------------------------------------ |
264+
| `docker-compose.proxy.yml` | Traefik reverse proxy configuration |
265+
| `docker-compose.user.yml` | Template for user environments |
266+
| `docker-compose.<user>.yml` | Generated user-specific config |
267+
| `setup-user.sh` | User setup script |
268+
| `generate-hosts.sh` | DNS helper for /etc/hosts |
269+
| `idle-shutdown.sh` | Auto-shutdown idle containers |
270+
| `install-traefik-service.sh` | Install Traefik as systemd service |
271+
| `uninstall-traefik-service.sh` | Remove Traefik systemd service |
272+
| `traefik.service` | Systemd unit file |
233273

234274
## How It Works
235275

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash
2+
# =============================================================================
3+
# Install Traefik as a systemd service
4+
# =============================================================================
5+
# This script installs Traefik as a system service that starts automatically
6+
# on boot and runs continuously to route traffic to dev containers.
7+
#
8+
# Usage: sudo ./install-traefik-service.sh
9+
# =============================================================================
10+
11+
set -e
12+
13+
# Colors
14+
RED='\033[0;31m'
15+
GREEN='\033[0;32m'
16+
YELLOW='\033[1;33m'
17+
BLUE='\033[0;34m'
18+
NC='\033[0m'
19+
20+
print_header() {
21+
echo -e "${BLUE}=====================================${NC}"
22+
echo -e "${BLUE}$1${NC}"
23+
echo -e "${BLUE}=====================================${NC}"
24+
}
25+
26+
print_success() {
27+
echo -e "${GREEN}$1${NC}"
28+
}
29+
30+
print_warning() {
31+
echo -e "${YELLOW}$1${NC}"
32+
}
33+
34+
print_error() {
35+
echo -e "${RED}$1${NC}"
36+
}
37+
38+
# Check if running as root
39+
if [ "$EUID" -ne 0 ]; then
40+
print_error "Please run as root: sudo $0"
41+
exit 1
42+
fi
43+
44+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
45+
INSTALL_DIR="/opt/simpleaccounts-proxy"
46+
47+
print_header "Installing Traefik Proxy Service"
48+
49+
# Check prerequisites
50+
echo "Checking prerequisites..."
51+
52+
if ! command -v docker &> /dev/null; then
53+
print_error "Docker is not installed. Please install Docker first."
54+
exit 1
55+
fi
56+
print_success "Docker is installed"
57+
58+
if ! docker compose version &> /dev/null; then
59+
print_error "Docker Compose is not installed. Please install Docker Compose first."
60+
exit 1
61+
fi
62+
print_success "Docker Compose is installed"
63+
64+
# Create installation directory
65+
echo ""
66+
echo "Setting up installation directory..."
67+
mkdir -p "$INSTALL_DIR"
68+
print_success "Created $INSTALL_DIR"
69+
70+
# Copy docker-compose file
71+
cp "$SCRIPT_DIR/docker-compose.proxy.yml" "$INSTALL_DIR/"
72+
print_success "Copied docker-compose.proxy.yml"
73+
74+
# Install systemd service
75+
echo ""
76+
echo "Installing systemd service..."
77+
cp "$SCRIPT_DIR/traefik.service" /etc/systemd/system/traefik-proxy.service
78+
print_success "Installed traefik-proxy.service"
79+
80+
# Reload systemd
81+
systemctl daemon-reload
82+
print_success "Reloaded systemd daemon"
83+
84+
# Enable service to start on boot
85+
systemctl enable traefik-proxy.service
86+
print_success "Enabled traefik-proxy service (starts on boot)"
87+
88+
# Start the service
89+
echo ""
90+
echo "Starting Traefik..."
91+
systemctl start traefik-proxy.service
92+
93+
# Wait for container to be ready
94+
sleep 3
95+
96+
# Check status
97+
if systemctl is-active --quiet traefik-proxy.service; then
98+
print_success "Traefik proxy is running!"
99+
else
100+
print_error "Failed to start Traefik. Check logs with: journalctl -u traefik-proxy.service"
101+
exit 1
102+
fi
103+
104+
# Detect server IP
105+
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
106+
if [ -z "$SERVER_IP" ]; then
107+
SERVER_IP=$(ip route get 1 2>/dev/null | awk '{print $7; exit}')
108+
fi
109+
NIP_IP=$(echo "$SERVER_IP" | tr '.' '-')
110+
111+
# Print summary
112+
print_header "Installation Complete!"
113+
echo ""
114+
echo -e "Traefik is now running as a system service."
115+
echo ""
116+
echo -e "${YELLOW}Service Management:${NC}"
117+
echo -e " Status: ${GREEN}sudo systemctl status traefik-proxy${NC}"
118+
echo -e " Stop: ${GREEN}sudo systemctl stop traefik-proxy${NC}"
119+
echo -e " Start: ${GREEN}sudo systemctl start traefik-proxy${NC}"
120+
echo -e " Restart: ${GREEN}sudo systemctl restart traefik-proxy${NC}"
121+
echo -e " Logs: ${GREEN}journalctl -u traefik-proxy -f${NC}"
122+
echo ""
123+
echo -e "${YELLOW}Dashboard:${NC}"
124+
echo -e " http://proxy.${NIP_IP}.nip.io:8090"
125+
echo -e " http://localhost:8090"
126+
echo ""
127+
echo -e "${YELLOW}Next Steps:${NC}"
128+
echo -e " Each developer runs: ${GREEN}./setup-user.sh <username>${NC}"
129+
echo ""

.devcontainer/proxy/setup-user.sh

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,18 @@ NIP_IP=$(echo "$SERVER_IP" | tr '.' '-')
7878

7979
print_success "Detected server IP: $SERVER_IP"
8080

81-
# Check if proxy network exists
81+
# Check if proxy is running
8282
if ! docker network ls | grep -q "dev-proxy-network"; then
83-
print_warning "Proxy network not found. Starting proxy first..."
84-
docker compose -f "$SCRIPT_DIR/docker-compose.proxy.yml" up -d
85-
sleep 3
86-
print_success "Proxy started"
87-
else
88-
print_success "Proxy network exists"
83+
print_error "Traefik proxy is not running!"
84+
echo ""
85+
echo "Please install the Traefik proxy first:"
86+
echo -e " ${GREEN}sudo ./install-traefik-service.sh${NC}"
87+
echo ""
88+
echo "Or start it manually:"
89+
echo -e " ${GREEN}docker compose -f $SCRIPT_DIR/docker-compose.proxy.yml up -d${NC}"
90+
exit 1
8991
fi
92+
print_success "Traefik proxy is running"
9093

9194
# Create user-specific compose file
9295
USER_COMPOSE="$SCRIPT_DIR/docker-compose.$USERNAME.yml"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[Unit]
2+
Description=Traefik Reverse Proxy for Dev Containers
3+
Documentation=https://doc.traefik.io/traefik/
4+
After=docker.service
5+
Requires=docker.service
6+
7+
[Service]
8+
Type=oneshot
9+
RemainAfterExit=yes
10+
WorkingDirectory=/opt/simpleaccounts-proxy
11+
ExecStartPre=/usr/bin/docker compose -f docker-compose.proxy.yml pull --quiet
12+
ExecStart=/usr/bin/docker compose -f docker-compose.proxy.yml up -d
13+
ExecStop=/usr/bin/docker compose -f docker-compose.proxy.yml down
14+
ExecReload=/usr/bin/docker compose -f docker-compose.proxy.yml up -d --force-recreate
15+
Restart=on-failure
16+
RestartSec=10
17+
18+
[Install]
19+
WantedBy=multi-user.target
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/bash
2+
# =============================================================================
3+
# Uninstall Traefik systemd service
4+
# =============================================================================
5+
# Usage: sudo ./uninstall-traefik-service.sh
6+
# =============================================================================
7+
8+
set -e
9+
10+
RED='\033[0;31m'
11+
GREEN='\033[0;32m'
12+
YELLOW='\033[1;33m'
13+
NC='\033[0m'
14+
15+
# Check if running as root
16+
if [ "$EUID" -ne 0 ]; then
17+
echo -e "${RED}Please run as root: sudo $0${NC}"
18+
exit 1
19+
fi
20+
21+
INSTALL_DIR="/opt/simpleaccounts-proxy"
22+
23+
echo -e "${YELLOW}Uninstalling Traefik Proxy Service...${NC}"
24+
25+
# Stop and disable service
26+
if systemctl is-active --quiet traefik-proxy.service 2>/dev/null; then
27+
echo "Stopping Traefik..."
28+
systemctl stop traefik-proxy.service
29+
fi
30+
31+
if systemctl is-enabled --quiet traefik-proxy.service 2>/dev/null; then
32+
echo "Disabling service..."
33+
systemctl disable traefik-proxy.service
34+
fi
35+
36+
# Remove systemd service file
37+
if [ -f /etc/systemd/system/traefik-proxy.service ]; then
38+
rm /etc/systemd/system/traefik-proxy.service
39+
echo -e "${GREEN}✓ Removed systemd service${NC}"
40+
fi
41+
42+
# Reload systemd
43+
systemctl daemon-reload
44+
45+
# Remove installation directory
46+
if [ -d "$INSTALL_DIR" ]; then
47+
rm -rf "$INSTALL_DIR"
48+
echo -e "${GREEN}✓ Removed $INSTALL_DIR${NC}"
49+
fi
50+
51+
# Remove Docker network (if no containers using it)
52+
if docker network ls | grep -q "dev-proxy-network"; then
53+
if docker network inspect dev-proxy-network --format '{{len .Containers}}' | grep -q "^0$"; then
54+
docker network rm dev-proxy-network 2>/dev/null || true
55+
echo -e "${GREEN}✓ Removed dev-proxy-network${NC}"
56+
else
57+
echo -e "${YELLOW}⚠ dev-proxy-network still has containers attached, keeping it${NC}"
58+
fi
59+
fi
60+
61+
echo ""
62+
echo -e "${GREEN}Traefik proxy service has been uninstalled.${NC}"

apps/frontend/vite.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export default defineConfig({
5858
'dayjs', // Pre-bundle dayjs to avoid initialization issues
5959
'bootstrap', // Pre-bundle bootstrap to ensure jQuery is loaded first
6060
'@emotion/react', // Pre-bundle emotion to ensure React is available
61-
'@emotion/styled', // Pre-bundle emotion styled
6261
],
6362
// Exclude large dependencies from optimization to save memory
6463
exclude: [

0 commit comments

Comments
 (0)