Skip to content

Commit 8a18cda

Browse files
authored
Merge pull request #17 from smashingtags/feature/cors
finally
2 parents 790d2d1 + 1ca31f7 commit 8a18cda

26 files changed

+4386
-329
lines changed

.env.example

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ AUTH_TOKEN=your-secure-token-here
77
CORS_ORIGIN=https://your-domain.com
88

99
# Docker Configuration
10-
DOCKER_SOCKET=/var/run/docker.sock
10+
# Path to Docker socket - usually /var/run/docker.sock on Linux systems
11+
DOCKER_SOCKET=/var/run/docker.sock
12+
13+
# Docker group ID - MUST match your host system's docker group ID
14+
# Find your system's docker group ID with:
15+
# Linux: getent group docker | cut -d: -f3
16+
# Linux (alternative): cat /etc/group | grep docker
17+
# Common values: 999, 998, 994 (varies by system)
18+
DOCKER_GID=999

.env.production

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ NODE_ENV=production
33

44
# Backend Configuration
55
PORT=3001
6-
CORS_ORIGIN=http://localhost:8087
6+
CORS_ORIGIN=*
77

88
# Docker Configuration
99
DOCKER_SOCKET=/var/run/docker.sock
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Design Document
2+
3+
## Overview
4+
5+
The Docker socket permission error (EACCES) occurs because the homelabarr-backend container lacks proper permissions to access the Docker daemon socket at `/var/run/docker.sock`. The current implementation attempts to change socket permissions using `chmodSync()`, but this fails because the container runs as a non-root user (`node`) and cannot modify system-level socket permissions.
6+
7+
The solution involves configuring proper Docker group membership and socket access through container orchestration rather than runtime permission changes.
8+
9+
## Architecture
10+
11+
The fix operates at multiple layers:
12+
13+
1. **Container Build Layer** - Ensure proper user/group configuration in Dockerfile
14+
2. **Container Runtime Layer** - Configure group membership and socket mounting in docker-compose
15+
3. **Application Layer** - Implement robust error handling and retry logic
16+
4. **Monitoring Layer** - Add proper logging and health checks for Docker connectivity
17+
18+
## Components and Interfaces
19+
20+
### Docker Group Configuration
21+
- **Host Group Mapping**: Map the host's docker group ID to the container
22+
- **User Group Membership**: Add the container user to the docker group
23+
- **Socket Permissions**: Ensure socket is accessible to docker group members
24+
25+
### Container Configuration
26+
- **Dockerfile Updates**: Configure proper group membership during build
27+
- **Docker Compose Updates**: Set correct group_add configuration
28+
- **Environment Variables**: Configure socket path and connection settings
29+
30+
### Application Layer Improvements
31+
- **Connection Retry Logic**: Implement exponential backoff for failed connections
32+
- **Error Handling**: Graceful degradation when Docker is unavailable
33+
- **Health Monitoring**: Enhanced health checks for Docker connectivity
34+
35+
### Security Considerations
36+
- **Least Privilege**: Grant minimal necessary permissions
37+
- **Group-based Access**: Use group membership instead of privileged mode
38+
- **Socket Protection**: Maintain socket security while enabling access
39+
40+
## Data Models
41+
42+
### Docker Connection Configuration
43+
```javascript
44+
interface DockerConfig {
45+
socketPath: string;
46+
timeout: number;
47+
retryAttempts: number;
48+
retryDelay: number;
49+
healthCheckInterval: number;
50+
}
51+
```
52+
53+
### Connection State Management
54+
```javascript
55+
interface DockerConnectionState {
56+
isConnected: boolean;
57+
lastError: Error | null;
58+
lastSuccessfulConnection: Date | null;
59+
retryCount: number;
60+
nextRetryAt: Date | null;
61+
}
62+
```
63+
64+
### Error Classification
65+
```javascript
66+
interface DockerError {
67+
type: 'permission' | 'connection' | 'timeout' | 'unknown';
68+
code: string;
69+
message: string;
70+
recoverable: boolean;
71+
retryAfter?: number;
72+
}
73+
```
74+
75+
## Error Handling
76+
77+
### Permission Errors (EACCES)
78+
- **Root Cause**: Container user lacks docker group membership
79+
- **Detection**: Monitor for EACCES errors on socket connection
80+
- **Resolution**: Configure proper group membership in container
81+
- **Fallback**: Log error and continue with degraded functionality
82+
83+
### Connection Failures
84+
- **Retry Strategy**: Exponential backoff with maximum retry limit
85+
- **Circuit Breaker**: Temporarily stop retrying after consecutive failures
86+
- **Recovery**: Automatic reconnection when Docker becomes available
87+
88+
### Socket Unavailability
89+
- **Detection**: Monitor socket file existence and permissions
90+
- **Logging**: Detailed error messages for troubleshooting
91+
- **Graceful Degradation**: Continue serving non-Docker endpoints
92+
93+
## Testing Strategy
94+
95+
### Permission Testing
96+
- Verify container can access Docker socket after configuration changes
97+
- Test that docker group membership is properly configured
98+
- Validate socket permissions are correctly set
99+
100+
### Connection Resilience Testing
101+
- Test behavior when Docker daemon is stopped/started
102+
- Verify retry logic works correctly with various failure scenarios
103+
- Test graceful degradation when Docker is unavailable
104+
105+
### Security Testing
106+
- Ensure container doesn't run with unnecessary privileges
107+
- Verify socket access is limited to required operations
108+
- Test that security boundaries are maintained
109+
110+
### Integration Testing
111+
- Test full container deployment with fixed configuration
112+
- Verify Docker operations work correctly after fix
113+
- Test health check endpoints report correct Docker status
114+
115+
## Implementation Approach
116+
117+
### Phase 1: Container Configuration Fix
118+
1. Update Dockerfile to properly configure docker group
119+
2. Modify docker-compose.yml to set correct group_add values
120+
3. Remove ineffective chmod attempts from application code
121+
122+
### Phase 2: Application Layer Improvements
123+
1. Implement robust Docker connection management
124+
2. Add retry logic with exponential backoff
125+
3. Enhance error logging and monitoring
126+
127+
### Phase 3: Health and Monitoring
128+
1. Improve health check to properly report Docker status
129+
2. Add connection state monitoring
130+
3. Implement graceful degradation for Docker unavailability
131+
132+
### Phase 4: Security Hardening
133+
1. Verify minimal privilege configuration
134+
2. Add security validation for Docker operations
135+
3. Implement proper error boundaries
136+
137+
## Security Considerations
138+
139+
### Docker Socket Access
140+
- Use group-based permissions instead of privileged mode
141+
- Limit socket access to necessary operations only
142+
- Monitor and log all Docker API calls
143+
144+
### Container Security
145+
- Run as non-root user with minimal required permissions
146+
- Use specific group membership rather than broad privileges
147+
- Implement proper input validation for Docker operations
148+
149+
### Host System Protection
150+
- Ensure container cannot escape to host system
151+
- Limit Docker operations to safe, necessary functions
152+
- Implement proper audit logging for security monitoring
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Requirements Document
2+
3+
## Introduction
4+
5+
This feature addresses the Docker socket permission error (EACCES) that prevents the homelabarr-backend from accessing Docker containers. The application is running in a Docker container and needs to communicate with the Docker daemon on the host system to manage other containers, but lacks the necessary permissions to access /var/run/docker.sock.
6+
7+
## Requirements
8+
9+
### Requirement 1
10+
11+
**User Story:** As a homelabarr-backend service, I want to access the Docker socket, so that I can fetch and manage Docker containers without permission errors.
12+
13+
#### Acceptance Criteria
14+
15+
1. WHEN the backend attempts to connect to /var/run/docker.sock THEN the connection SHALL succeed without EACCES errors
16+
2. WHEN the Docker socket is mounted in the container THEN the backend process SHALL have read/write permissions
17+
3. WHEN fetching containers THEN the API calls SHALL complete successfully without permission denials
18+
19+
### Requirement 2
20+
21+
**User Story:** As a system administrator, I want secure Docker socket access, so that the container can manage Docker resources without compromising host security.
22+
23+
#### Acceptance Criteria
24+
25+
1. WHEN mounting the Docker socket THEN only necessary permissions SHALL be granted
26+
2. WHEN the container accesses Docker THEN it SHALL use the least privilege principle
27+
3. WHEN running in production THEN Docker socket access SHALL be properly secured
28+
29+
### Requirement 3
30+
31+
**User Story:** As a developer, I want consistent Docker socket access across environments, so that the application works reliably in development, testing, and production.
32+
33+
#### Acceptance Criteria
34+
35+
1. WHEN running via docker-compose THEN Docker socket access SHALL work consistently
36+
2. WHEN running on different host systems THEN the socket mounting SHALL adapt to the environment
37+
3. WHEN deploying to different platforms THEN Docker access SHALL remain functional
38+
39+
### Requirement 4
40+
41+
**User Story:** As a homelabarr user, I want the backend to gracefully handle Docker connection failures, so that the application remains stable even when Docker access is temporarily unavailable.
42+
43+
#### Acceptance Criteria
44+
45+
1. WHEN Docker socket access fails THEN the backend SHALL log appropriate error messages
46+
2. WHEN Docker is temporarily unavailable THEN the backend SHALL implement retry logic with exponential backoff
47+
3. WHEN Docker access is restored THEN the backend SHALL automatically reconnect without requiring restart
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Implementation Plan
2+
3+
- [x] 1. Fix Docker group configuration in Dockerfile.backend
4+
5+
6+
7+
8+
9+
- Remove the hardcoded docker group creation and use dynamic group ID detection
10+
- Update the group_add configuration to use the correct docker group ID
11+
- Ensure the node user is properly added to the docker group
12+
- _Requirements: 1.1, 1.2, 2.1_
13+
14+
- [x] 2. Update docker-compose.yml for proper Docker socket access
15+
16+
17+
18+
19+
20+
- Fix the group_add configuration to use the correct docker group ID for the host system
21+
- Verify the Docker socket volume mount is correctly configured
22+
- Add environment variable for Docker socket path configuration
23+
- _Requirements: 1.1, 1.2, 3.1_
24+
25+
- [x] 3. Remove ineffective socket permission code from server/index.js
26+
27+
28+
29+
30+
31+
- Remove the chmodSync call that attempts to change socket permissions
32+
- Remove the try-catch block around the chmod operation
33+
- Clean up related console.warn messages about socket permissions
34+
- _Requirements: 1.1, 2.1_
35+
36+
- [x] 4. Implement robust Docker connection management in server/index.js
37+
38+
39+
40+
41+
42+
- Create a DockerConnectionManager class to handle connection state
43+
- Implement retry logic with exponential backoff for failed connections
44+
- Add connection health monitoring and automatic reconnection
45+
- _Requirements: 4.1, 4.2, 4.3_
46+
47+
- [x] 5. Add proper error handling for Docker connection failures
48+
49+
50+
51+
52+
53+
- Implement error classification to distinguish between different failure types
54+
- Add graceful degradation when Docker is temporarily unavailable
55+
- Create proper error responses for Docker-dependent endpoints
56+
- _Requirements: 4.1, 4.2, 4.3_
57+
58+
- [x] 6. Enhance health check endpoint for Docker connectivity status
59+
60+
61+
62+
63+
64+
- Update the /health endpoint to properly report Docker connection status
65+
- Add detailed error information when Docker connection fails
66+
- Implement connection retry status in health check response
67+
- _Requirements: 4.1, 4.3_
68+
69+
- [x] 7. Add comprehensive logging for Docker connection issues
70+
71+
72+
73+
74+
75+
- Implement structured logging for Docker connection attempts
76+
- Add debug logging for connection state changes
77+
- Create informative error messages for troubleshooting
78+
- _Requirements: 4.1, 4.3_
79+
80+
- [x] 8. Create Docker connection retry mechanism
81+
82+
83+
84+
85+
86+
- Implement exponential backoff algorithm for connection retries
87+
- Add maximum retry limits to prevent infinite retry loops
88+
- Create circuit breaker pattern for consecutive failures
89+
- _Requirements: 4.2, 4.3_
90+
91+
- [x] 9. Test and validate Docker socket access fix
92+
93+
94+
95+
96+
97+
98+
99+
- Create test script to verify Docker socket permissions
100+
- Test container deployment with updated configuration
101+
- Verify all Docker operations work correctly after fix
102+
- _Requirements: 1.1, 1.2, 1.3, 3.1_

.kiro/specs/error-cleanup/tasks.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
# Implementation Plan
22

3-
- [] 1. Install project dependencies and verify module resolution
3+
- [x] 1. Install project dependencies and verify module resolution
44
- Run npm install to install all dependencies from package.json
55
- Verify that node_modules directory is created with all required packages
66
- Test that React and lucide-react modules can be imported without errors
77
- _Requirements: 1.1, 1.2, 1.3_
88

9-
- [] 2. Fix TypeScript configuration for proper JSX support
9+
- [x] 2. Fix TypeScript configuration for proper JSX support
1010
- Update tsconfig.app.json to ensure proper JSX runtime configuration
1111
- Verify that JSX.IntrinsicElements interface is properly recognized
1212
- Test that React components compile without JSX-related errors
1313
- _Requirements: 2.1, 2.2, 2.3_
1414

15-
- [] 3. Resolve implicit any type errors in event handlers
15+
- [x] 3. Resolve implicit any type errors in event handlers
1616
- Add explicit type annotations for event handler parameters in App.tsx
1717
- Fix setState callback parameter types to remove implicit any errors
1818
- Ensure all event handlers have proper TypeScript types
1919
- _Requirements: 3.1, 3.2, 3.3_
2020

21-
- [] 4. Fix React component prop type issues
21+
- [x] 4. Fix React component prop type issues
2222
- Review and fix component prop interfaces to align with usage
2323
- Separate React key props from component prop interfaces
2424
- Ensure all component props are properly typed and validated
2525
- _Requirements: 4.1, 4.2, 4.3_
2626

27-
- [] 5. Verify compilation and test application functionality
27+
- [x] 5. Verify compilation and test application functionality
2828
- Run TypeScript compilation to ensure no errors remain
2929
- Test that the development server starts successfully
3030
- Verify that all React components render without runtime errors

DEPLOYMENT.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ The application requires access to the Docker socket for container management. T
8585
- Authentication required for all container operations
8686
- Health checks for service monitoring
8787

88+
**Docker Group Configuration:**
89+
The application uses the host's docker group for socket access. To find your docker group ID:
90+
```bash
91+
getent group docker | cut -d: -f3
92+
```
93+
Set this value in your `.env` file:
94+
```bash
95+
DOCKER_GID=999 # Replace with your actual docker group ID
96+
```
97+
8898
#### Network Security
8999
- Frontend and backend communicate over internal Docker network
90100
- Only necessary ports are exposed

0 commit comments

Comments
 (0)