6 | This page provides a comprehensive reference of the most commonly used Docker commands.
7 | These commands will help you manage containers, images, volumes, networks, and more from the command line.
8 |
9 |
10 |
11 | Safe
12 | Information and listing commands
13 |
14 |
15 | Disruptive
16 | Changes state but reversible
17 |
` elements throughout the application
82 | - **Dynamic Modals**: Docker compose file viewer and other dynamically created content
83 |
84 | The dark mode now provides excellent readability and contrast across all container management interfaces! 🌙✨
--------------------------------------------------------------------------------
/DOCKER-SOURCE-TESTING.md:
--------------------------------------------------------------------------------
1 | # Docker Source Selection - Testing Guide
2 |
3 | ## What Changed
4 |
5 | 1. **Docker Source Selector** moved to the **top navbar** (no longer on dashboard)
6 | 2. The selector is now persistent across all pages
7 | 3. Changing the source will fetch containers from the selected daemon
8 |
9 | ## How to Test
10 |
11 | ### 1. Check if the selector is visible
12 | - Look at the top navbar - you should see a dropdown with "Local" and "WSL2" options
13 |
14 | ### 2. Test Local Containers
15 | - Make sure the dropdown shows "Local"
16 | - Click "Refresh" on the dashboard
17 | - You should see containers from your Docker Desktop
18 |
19 | ### 3. Test WSL2 Containers (if configured)
20 | - First, ensure your WSL2 Docker daemon is properly configured
21 | - See `WSL2-DOCKER-CONFIG.md` for setup instructions
22 | - Select "WSL2" from the navbar dropdown
23 | - Click "Refresh" on the dashboard
24 | - You should see containers from WSL2 (if different from local)
25 |
26 | ### 4. Test the debug endpoint
27 | Open your browser and navigate to:
28 | ```
29 | http://localhost:3334/api/containers/test/source?source=local
30 | http://localhost:3334/api/containers/test/source?source=wsl2
31 | ```
32 |
33 | You should see JSON responses showing:
34 | - The source being tested
35 | - Whether connection was successful
36 | - Docker information (container count, server version)
37 |
38 | Example response:
39 | ```json
40 | {
41 | "source": "local",
42 | "connected": true,
43 | "dockerInfo": {
44 | "Containers": 5,
45 | "ContainersRunning": 2,
46 | "ServerVersion": "26.0.0"
47 | }
48 | }
49 | ```
50 |
51 | ## Common Issues
52 |
53 | ### "Still seeing same containers for Local and WSL2"
54 | This is **normal** if you're using Docker Desktop with WSL2 backend. Both point to the same daemon.
55 | To see different containers, you need to:
56 | 1. Have Docker running separately in WSL2 (not Docker Desktop)
57 | 2. Configure it to expose the daemon on TCP port 2375 (see WSL2-DOCKER-CONFIG.md)
58 |
59 | ### "Source selector not appearing in navbar"
60 | - Clear browser cache and hard refresh (Ctrl+Shift+R)
61 | - Check browser console for errors
62 | - Verify the app properly reloaded
63 |
64 | ### "Changes to dropdown don't work"
65 | - Check browser console for errors
66 | - Verify the debug endpoints show different sources are being sent
67 | - Make sure backend is running and not cached
68 |
69 | ## Debug Steps
70 |
71 | 1. **Check frontend/backend communication:**
72 | ```
73 | http://localhost:3334/api/containers/test/source?source=local
74 | http://localhost:3334/api/containers/test/source?source=wsl2
75 | ```
76 |
77 | 2. **Check if containers endpoint gets source parameter:**
78 | Open DevTools → Network tab → select "local" in dropdown → Refresh
79 | - Look for request to `/api/containers?all=true&source=local`
80 |
81 | 3. **Check backend logs:**
82 | - Look at backend server output for any errors when fetching containers
83 |
84 | 4. **Check if WSL2 is properly configured:**
85 | If WSL2 Docker daemon isn't accessible, you'll see connection errors in the debug endpoint
86 |
--------------------------------------------------------------------------------
/WSL2-DOCKER-CONFIG.md:
--------------------------------------------------------------------------------
1 | # WSL2 Docker Configuration Guide
2 |
3 | This guide explains how to configure the Docker Web Desktop to access containers from both Windows Docker Desktop and WSL2 Docker daemon.
4 |
5 | ## Prerequisites
6 |
7 | - Windows with WSL2 installed
8 | - Docker Desktop for Windows OR Docker installed in WSL2
9 | - Docker Web Desktop application
10 |
11 | ## Configuration Methods
12 |
13 | ### Method 1: TCP Connection (Recommended for separate WSL2 Docker)
14 |
15 | If you have Docker running inside WSL2 (not Docker Desktop), you need to expose the Docker daemon on TCP:
16 |
17 | 1. **In your WSL2 terminal**, edit the Docker daemon configuration:
18 | ```bash
19 | sudo nano /etc/docker/daemon.json
20 | ```
21 |
22 | 2. Add TCP socket configuration:
23 | ```json
24 | {
25 | "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
26 | }
27 | ```
28 |
29 | 3. Restart Docker:
30 | ```bash
31 | sudo systemctl restart docker
32 | ```
33 |
34 | 4. **In Windows**, create/edit `.env` file in the backend directory:
35 | ```env
36 | WSL2_DOCKER_HOST=localhost
37 | WSL2_DOCKER_PORT=2375
38 | ```
39 |
40 | 5. Restart the backend server
41 |
42 | ### Method 2: Socket Path (For Docker Desktop with WSL2 integration)
43 |
44 | If using Docker Desktop with WSL2 backend, both "Local" and "WSL2" typically point to the same daemon. Docker Desktop automatically handles this integration.
45 |
46 | No additional configuration needed - just select "Local" in the dashboard dropdown.
47 |
48 | ### Method 3: Custom Socket Path
49 |
50 | If you want to access WSL2 Docker via socket path:
51 |
52 | 1. Enable WSL2 network sharing
53 | 2. In `.env` file:
54 | ```env
55 | WSL2_DOCKER_SOCKET=\\wsl$\Ubuntu\var\run\docker.sock
56 | ```
57 | (Replace `Ubuntu` with your WSL2 distribution name)
58 |
59 | ## Usage
60 |
61 | 1. Start the backend server
62 | 2. Open the dashboard
63 | 3. Use the dropdown at the top to switch between "Local" and "WSL2"
64 | 4. The dashboard will show containers from the selected source
65 |
66 | ## Troubleshooting
67 |
68 | ### "Failed to get containers" error
69 |
70 | - Check if Docker daemon is running in the selected source
71 | - For WSL2 TCP: Ensure port 2375 is accessible: `curl http://localhost:2375/version`
72 | - Check Windows Firewall settings
73 |
74 | ### Same containers showing for both Local and WSL2
75 |
76 | - This is normal if you're using Docker Desktop with WSL2 backend
77 | - Both point to the same Docker daemon managed by Docker Desktop
78 | - To use separate Docker instances, install Docker directly in WSL2 (not Docker Desktop)
79 |
80 | ### Connection timeout
81 |
82 | - Verify the WSL2_DOCKER_PORT and WSL2_DOCKER_HOST values in .env
83 | - Check if Docker is listening on the configured port:
84 | ```bash
85 | # In WSL2
86 | sudo netstat -tlnp | grep 2375
87 | ```
88 |
89 | ## Security Note
90 |
91 | ⚠️ **Warning**: Exposing Docker daemon on TCP without TLS is insecure and should only be used in development environments. For production, always use TLS certificates and authentication.
92 |
93 | See [Docker daemon socket security](https://docs.docker.com/engine/security/protect-access/) for more information.
94 |
--------------------------------------------------------------------------------
/backend/src/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const cors = require('cors');
3 | const http = require('http');
4 | const socketIo = require('socket.io');
5 | require('dotenv').config();
6 |
7 | const containerRoutes = require('./routes/containers');
8 | const imageRoutes = require('./routes/images');
9 | const volumeRoutes = require('./routes/volumes');
10 | const networkRoutes = require('./routes/networks');
11 | const serviceRoutes = require('./routes/services');
12 | const commandRoutes = require('./routes/commands');
13 | const composeRoutes = require('./routes/compose');
14 | const wslRoutes = require('./routes/wsl');
15 |
16 | const app = express();
17 | const server = http.createServer(app);
18 | const io = socketIo(server, {
19 | cors: {
20 | origin: ["http://localhost:8080", "http://localhost:5173", "http://localhost:5174"],
21 | methods: ["GET", "POST"]
22 | }
23 | });
24 |
25 | const PORT = process.env.PORT || 3000;
26 |
27 | // Middleware
28 | app.use(cors({
29 | origin: [
30 | "http://localhost:8080",
31 | "http://localhost:5173",
32 | "http://localhost:5174",
33 | "http://localhost:5175"
34 | ],
35 | methods: ["GET", "POST", "PUT", "DELETE"],
36 | credentials: true
37 | }));
38 | app.use(express.json());
39 |
40 | // Swagger UI (development only)
41 | if (process.env.NODE_ENV === 'development') {
42 | try {
43 | const swaggerUi = require('swagger-ui-express');
44 | const swaggerDocument = require('./swagger_output.json');
45 | app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument, {
46 | explorer: true,
47 | swaggerOptions: {
48 | docExpansion: 'none', // Collapse all by default
49 | tagsSorter: 'alpha', // Sort tags alphabetically
50 | operationsSorter: 'alpha',
51 | }
52 | }));
53 | console.log('Swagger UI available at /api-docs (development, swagger-autogen)');
54 | } catch (err) {
55 | console.warn('Swagger UI not available. Install swagger-ui-express and swagger-autogen to enable it.');
56 | }
57 | }
58 |
59 | // Routes
60 | app.use('/api/containers', containerRoutes);
61 | app.use('/api/images', imageRoutes);
62 | app.use('/api/volumes', volumeRoutes);
63 | app.use('/api/networks', networkRoutes);
64 | app.use('/api/services', serviceRoutes);
65 | app.use('/api/commands', commandRoutes);
66 | app.use('/api/compose', composeRoutes);
67 | app.use('/api/wsl', wslRoutes);
68 |
69 | // Health check endpoint
70 | app.get('/api/health', (req, res) => {
71 | res.json({ status: 'OK', message: 'Docker Web Desktop API is running' });
72 | });
73 |
74 | // Socket.IO for real-time updates
75 | io.on('connection', (socket) => {
76 | console.log('Client connected:', socket.id);
77 |
78 | socket.on('disconnect', () => {
79 | console.log('Client disconnected:', socket.id);
80 | });
81 | });
82 |
83 | // Make io available to routes
84 | app.set('io', io);
85 |
86 | server.listen(PORT, () => {
87 | console.log('Environment:', process.env.NODE_ENV || 'development');
88 | console.log(`Server is running on port ${PORT}`);
89 | //put the app link and swagger link here
90 | console.log(`API Endpoint: http://localhost:${PORT}/api`);
91 | console.log(`Swagger UI: http://localhost:${PORT}/api-docs`);
92 | console.log('server is running at: http://localhost:' + PORT);
93 | });
94 |
95 | module.exports = { app, io };
--------------------------------------------------------------------------------
/deploy.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | setlocal enabledelayedexpansion
3 |
4 | :: Docker Web Desktop - Deployment Script for Windows
5 |
6 | echo.
7 | echo 🐳 Docker Web Desktop - Deployment Script
8 | echo ===========================================
9 |
10 | :: Check if Docker is running
11 | docker info >nul 2>&1
12 | if errorlevel 1 (
13 | echo ❌ Docker is not running. Please start Docker and try again.
14 | exit /b 1
15 | )
16 |
17 | :: Check if Docker Compose is available
18 | docker-compose --version >nul 2>&1
19 | if errorlevel 1 (
20 | echo ❌ Docker Compose is not installed. Please install Docker Compose and try again.
21 | exit /b 1
22 | )
23 |
24 | :: Parse command
25 | set COMMAND=%1
26 | if "%COMMAND%"=="" set COMMAND=start
27 |
28 | if "%COMMAND%"=="start" goto start
29 | if "%COMMAND%"=="dev" goto dev
30 | if "%COMMAND%"=="stop" goto stop
31 | if "%COMMAND%"=="restart" goto restart
32 | if "%COMMAND%"=="logs" goto logs
33 | if "%COMMAND%"=="clean" goto clean
34 | if "%COMMAND%"=="build" goto build
35 | if "%COMMAND%"=="status" goto status
36 | if "%COMMAND%"=="help" goto help
37 | if "%COMMAND%"=="-h" goto help
38 | if "%COMMAND%"=="--help" goto help
39 |
40 | echo ❌ Unknown command: %COMMAND%
41 | echo.
42 | goto help
43 |
44 | :start
45 | echo 🚀 Starting Docker Web Desktop in production mode...
46 | docker-compose up -d --build
47 | if errorlevel 0 (
48 | echo ✅ Application started successfully!
49 | echo 🌐 Frontend: http://localhost
50 | echo 🔧 Backend API: http://localhost:3000
51 | )
52 | goto end
53 |
54 | :dev
55 | echo 🚀 Starting Docker Web Desktop in development mode...
56 | docker-compose -f docker-compose.dev.yml up --build
57 | goto end
58 |
59 | :stop
60 | echo 🛑 Stopping Docker Web Desktop...
61 | docker-compose down
62 | docker-compose -f docker-compose.dev.yml down >nul 2>&1
63 | echo ✅ Application stopped successfully!
64 | goto end
65 |
66 | :restart
67 | echo 🔄 Restarting Docker Web Desktop...
68 | docker-compose down
69 | docker-compose up -d --build
70 | if errorlevel 0 (
71 | echo ✅ Application restarted successfully!
72 | )
73 | goto end
74 |
75 | :logs
76 | echo 📋 Showing application logs...
77 | docker-compose logs -f
78 | goto end
79 |
80 | :clean
81 | echo 🧹 Cleaning up Docker Web Desktop...
82 | docker-compose down -v --rmi all --remove-orphans
83 | docker-compose -f docker-compose.dev.yml down -v --rmi all --remove-orphans >nul 2>&1
84 | echo ✅ Cleanup completed!
85 | goto end
86 |
87 | :build
88 | echo 🔨 Building Docker images...
89 | docker-compose build --no-cache
90 | if errorlevel 0 (
91 | echo ✅ Images built successfully!
92 | )
93 | goto end
94 |
95 | :status
96 | echo 📊 Container status:
97 | docker-compose ps
98 | echo.
99 | echo 📊 Development container status:
100 | docker-compose -f docker-compose.dev.yml ps >nul 2>&1 || echo No development containers running
101 | goto end
102 |
103 | :help
104 | echo Usage: %0 [COMMAND]
105 | echo.
106 | echo Commands:
107 | echo start Start the application in production mode
108 | echo dev Start the application in development mode
109 | echo stop Stop the application
110 | echo restart Restart the application
111 | echo logs Show application logs
112 | echo clean Stop and remove all containers, networks, and volumes
113 | echo build Build all Docker images
114 | echo status Show status of all containers
115 | echo.
116 | echo Examples:
117 | echo %0 start
118 | echo %0 dev
119 | echo %0 logs
120 | goto end
121 |
122 | :end
123 | echo.
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Docker Web Desktop - Deployment Script
4 |
5 | set -e
6 |
7 | echo "🐳 Docker Web Desktop - Deployment Script"
8 | echo "==========================================="
9 |
10 | # Check if Docker is running
11 | if ! docker info > /dev/null 2>&1; then
12 | echo "❌ Docker is not running. Please start Docker and try again."
13 | exit 1
14 | fi
15 |
16 | # Check if Docker Compose is available
17 | if ! command -v docker-compose > /dev/null 2>&1; then
18 | echo "❌ Docker Compose is not installed. Please install Docker Compose and try again."
19 | exit 1
20 | fi
21 |
22 | # Function to show usage
23 | show_usage() {
24 | echo "Usage: $0 [COMMAND]"
25 | echo ""
26 | echo "Commands:"
27 | echo " start Start the application in production mode"
28 | echo " dev Start the application in development mode"
29 | echo " stop Stop the application"
30 | echo " restart Restart the application"
31 | echo " logs Show application logs"
32 | echo " clean Stop and remove all containers, networks, and volumes"
33 | echo " build Build all Docker images"
34 | echo " status Show status of all containers"
35 | echo ""
36 | echo "Examples:"
37 | echo " $0 start"
38 | echo " $0 dev"
39 | echo " $0 logs"
40 | }
41 |
42 | # Parse command
43 | COMMAND=${1:-"start"}
44 |
45 | case $COMMAND in
46 | "start")
47 | echo "🚀 Starting Docker Web Desktop in production mode..."
48 | docker-compose up -d --build
49 | echo "✅ Application started successfully!"
50 | echo "🌐 Frontend: http://localhost"
51 | echo "🔧 Backend API: http://localhost:3000"
52 | ;;
53 |
54 | "dev")
55 | echo "🚀 Starting Docker Web Desktop in development mode..."
56 | docker-compose -f docker-compose.dev.yml up --build
57 | ;;
58 |
59 | "stop")
60 | echo "🛑 Stopping Docker Web Desktop..."
61 | docker-compose down
62 | docker-compose -f docker-compose.dev.yml down 2>/dev/null || true
63 | echo "✅ Application stopped successfully!"
64 | ;;
65 |
66 | "restart")
67 | echo "🔄 Restarting Docker Web Desktop..."
68 | docker-compose down
69 | docker-compose up -d --build
70 | echo "✅ Application restarted successfully!"
71 | ;;
72 |
73 | "logs")
74 | echo "📋 Showing application logs..."
75 | docker-compose logs -f
76 | ;;
77 |
78 | "clean")
79 | echo "🧹 Cleaning up Docker Web Desktop..."
80 | docker-compose down -v --rmi all --remove-orphans
81 | docker-compose -f docker-compose.dev.yml down -v --rmi all --remove-orphans 2>/dev/null || true
82 | echo "✅ Cleanup completed!"
83 | ;;
84 |
85 | "build")
86 | echo "🔨 Building Docker images..."
87 | docker-compose build --no-cache
88 | echo "✅ Images built successfully!"
89 | ;;
90 |
91 | "status")
92 | echo "📊 Container status:"
93 | docker-compose ps
94 | echo ""
95 | echo "📊 Development container status:"
96 | docker-compose -f docker-compose.dev.yml ps 2>/dev/null || echo "No development containers running"
97 | ;;
98 |
99 | "help"|"-h"|"--help")
100 | show_usage
101 | ;;
102 |
103 | *)
104 | echo "❌ Unknown command: $COMMAND"
105 | echo ""
106 | show_usage
107 | exit 1
108 | ;;
109 | esac
--------------------------------------------------------------------------------
/SOURCE_SELECTION_COMPLETE.md:
--------------------------------------------------------------------------------
1 | # Docker Source Selection - Complete Implementation
2 |
3 | All Docker resources (containers, images, volumes, networks, and services) now support switching between Local and WSL2 Docker daemons.
4 |
5 | ## Backend Changes
6 |
7 | ### Updated Routes
8 | All routes now accept a `source` query parameter (default: 'local'):
9 |
10 | 1. **images.js** - GET /api/images?source=local|wsl2
11 | - Uses `DockerService.forSource(source)` to get the appropriate Docker instance
12 |
13 | 2. **volumes.js** - GET /api/volumes?source=local|wsl2
14 | - Uses `DockerService.forSource(source)` to get the appropriate Docker instance
15 |
16 | 3. **networks.js** - GET /api/networks?source=local|wsl2
17 | - Uses `DockerService.forSource(source)` to get the appropriate Docker instance
18 |
19 | 4. **services.js** - GET /api/services?source=local|wsl2
20 | - Uses `DockerService.forSource(source)` to access Docker Swarm services
21 | - GET /api/services/:id?source=local|wsl2 for specific service details
22 |
23 | 5. **containers.js** (already updated) - GET /api/containers?source=local|wsl2
24 |
25 | 6. **commands.js** (already updated) - POST /api/commands/execute with source parameter
26 | - Wraps commands with `wsl.exe -d Ubuntu --` when source=wsl2
27 |
28 | ## Frontend Changes
29 |
30 | ### API Service (api.ts)
31 | Updated all resource fetching methods to accept source parameter:
32 | - `getImages(source: string = 'local')`
33 | - `getVolumes(source: string = 'local')`
34 | - `getNetworks(source: string = 'local')`
35 | - `getContainers(all, source: string = 'local')` (already updated)
36 | - `executeCommand(command, source: string = 'local')` (already updated)
37 | - `openCommand(command, source: string = 'local')` (already updated)
38 |
39 | ### Store (docker.ts)
40 | Updated all fetch actions to use the selected source:
41 | - `fetchImages(source?: string)` - Uses `this.containerSource` by default
42 | - `fetchVolumes(source?: string)` - Uses `this.containerSource` by default
43 | - `fetchNetworks(source?: string)` - Uses `this.containerSource` by default
44 | - `fetchContainers(source?: string)` (already updated)
45 |
46 | The `containerSource` state is:
47 | - Initialized from localStorage on app startup
48 | - Updated when user changes the dropdown in Navbar
49 | - Automatically saved to localStorage for persistence
50 |
51 | ### Navbar (Navbar.vue) (already updated)
52 | - Dropdown selector for Local/WSL2
53 | - Saves selection to localStorage
54 | - Updates the store's `containerSource`
55 | - Triggers refresh of all Docker resources
56 |
57 | ## How It Works
58 |
59 | 1. **User selects source** in Navbar dropdown (Local or WSL2)
60 | 2. **Selection is saved** to localStorage for persistence
61 | 3. **Store is updated** with new source via `setContainerSource()`
62 | 4. **All resources refresh** using the new source
63 | 5. **Backend routes** receive source parameter and use `DockerService.forSource(source)` to connect to the correct Docker daemon
64 | 6. **Commands execute** in the appropriate environment (Windows cmd for local, WSL2 bash for wsl2)
65 |
66 | ## Testing
67 |
68 | To verify the implementation:
69 |
70 | 1. Switch between Local and WSL2 in the navbar dropdown
71 | 2. Navigate to different views (Containers, Images, Volumes, Networks)
72 | 3. Verify that resources from the selected source are displayed
73 | 4. Try executing commands - they should run in the correct environment
74 | 5. Refresh the page - selection should persist
75 |
76 | ## Architecture Notes
77 |
78 | - **Backend**: `DockerService.forSource(source)` factory method creates appropriate Docker client
79 | - **Frontend**: Single source of truth in store's `containerSource` state
80 | - **Persistence**: localStorage ensures selection survives page refreshes
81 | - **Commands**: WSL2 commands wrapped with `wsl.exe -d Ubuntu --` prefix
82 |
--------------------------------------------------------------------------------
/frontend/COMPOSE_INSPECT_FIXES.md:
--------------------------------------------------------------------------------
1 | # View Compose & Inspect Tab Dark Mode Fixes
2 |
3 | ## 🐛 Issues Fixed
4 |
5 | ### 1. View Compose Modal Dark Mode Issues
6 | - **Problem**: Hardcoded light theme colors (`white`, `#f8f9fa`, `#333`) that didn't adapt to dark theme
7 | - **Solution**: Converted inline styles to CSS classes with proper dark theme support
8 |
9 | ### 2. Inspect Tab Dark Mode Issues
10 | - **Problem**: `.inspect-container` had hardcoded light background (`#f8f9fa`)
11 | - **Solution**: Added dark theme override with black background and white text
12 |
13 | ## 🎨 CSS Fixes Applied
14 |
15 | ### Compose Modal Dark Theme
16 | ```css
17 | /* Modal background and text */
18 | [data-bs-theme="dark"] .compose-modal-content {
19 | background-color: var(--bs-secondary-bg) !important;
20 | color: var(--bs-body-color) !important;
21 | }
22 |
23 | /* Code content - black background with white text */
24 | [data-bs-theme="dark"] .compose-code-content {
25 | background-color: #000000 !important;
26 | color: #ffffff !important;
27 | border: 1px solid var(--bs-border-color) !important;
28 | }
29 |
30 | /* Headers and footers with proper borders */
31 | [data-bs-theme="dark"] .compose-modal-header {
32 | border-bottom: 1px solid var(--bs-border-color) !important;
33 | }
34 |
35 | [data-bs-theme="dark"] .compose-modal-footer {
36 | border-top: 1px solid var(--bs-border-color) !important;
37 | }
38 | ```
39 |
40 | ### Inspect Container Dark Theme
41 | ```css
42 | [data-bs-theme="dark"] .inspect-container {
43 | background-color: #000000 !important;
44 | color: #ffffff !important;
45 | border-color: var(--bs-border-color) !important;
46 | }
47 | ```
48 |
49 | ## 🔧 JavaScript Changes
50 |
51 | ### Compose Modal Function Updates
52 | - **Replaced**: Hardcoded inline styles with CSS classes
53 | - **Added**: Theme-adaptive hover states using CSS classes
54 | - **Improved**: Modal structure for better theme compatibility
55 |
56 | ```javascript
57 | // Before (hardcoded colors)
58 | modalContent.style.cssText = `background: white !important; ...`
59 |
60 | // After (CSS classes)
61 | modalContent.className = 'compose-modal-content'
62 | ```
63 |
64 | ## ✅ Results
65 |
66 | ### 🌙 **Dark Theme Support**
67 | 1. **Compose Modal**:
68 | - Dark gray modal background (`var(--bs-secondary-bg)`)
69 | - Black code background with white text (`#000000`/`#ffffff`)
70 | - Proper borders and hover states
71 |
72 | 2. **Inspect Tab**:
73 | - Black background for JSON inspection data
74 | - White text for maximum readability
75 | - Consistent with other console elements
76 |
77 | ### 🌕 **Light Theme Compatibility**
78 | - Maintained original light theme appearance
79 | - Smooth transitions between themes
80 | - No visual regressions
81 |
82 | ## 🧪 Components Affected
83 |
84 | - **ContainersView.vue**: `showComposeModal` function updated
85 | - **ContainerDetailsView.vue**: `.inspect-container` styling fixed
86 | - **dark-theme.css**: Comprehensive modal and inspect styling added
87 |
88 | ## 🎯 Technical Implementation
89 |
90 | ### Modal Structure Enhancement
91 | ```html
92 |
93 |
94 |
95 |
96 |
97 | ```
98 |
99 | ### Hover State Management
100 | ```javascript
101 | // CSS class-based hover states for theme compatibility
102 | closeBtn.addEventListener('mouseenter', () => {
103 | closeBtn.classList.add('compose-close-hover')
104 | })
105 | ```
106 |
107 | The View Compose and Inspect functionality now provides excellent dark mode experience with:
108 | - **Perfect readability**: Black backgrounds with white text for all code
109 | - **Consistent theming**: Matches overall application dark theme
110 | - **Smooth interactions**: Proper hover states and transitions
111 | - **Accessibility**: High contrast maintained for all elements
112 |
113 | Both features are now fully dark-mode compatible! 🌙✨
--------------------------------------------------------------------------------
/frontend/src/components/docker/GenericModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ title }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
{{ loadingText || 'Loading...' }}
17 |
18 |
19 |
20 |
{{ emptyMessage }}
21 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
37 |
132 |
133 |
--------------------------------------------------------------------------------
/frontend/THEME_TOGGLE.md:
--------------------------------------------------------------------------------
1 | # Theme Toggle Implementation
2 |
3 | ## 🎨 Overview
4 |
5 | This implementation adds Bootstrap's built-in theme toggle functionality with minimal code changes. Users can switch between light and dark modes, and their preference is saved and restored automatically.
6 |
7 | ## ✨ Features
8 |
9 | - **Bootstrap Native**: Uses Bootstrap's built-in `data-bs-theme` attribute
10 | - **Persistent**: Theme choice saved in `localStorage` under key `theme`
11 | - **System Aware**: Respects user's system preference (`prefers-color-scheme`) on first visit
12 | - **Minimal Code**: Only a few lines added to existing files
13 | - **Accessible**: Proper icons and labels for different themes
14 |
15 | ## 🔧 Implementation Details
16 |
17 | ### Files Modified
18 |
19 | 1. **`src/main.ts`** - Theme initialization on page load
20 | 2. **`src/components/Navbar.vue`** - Theme toggle button and logic
21 |
22 | ### Code Changes
23 |
24 | #### main.ts
25 | ```typescript
26 | // Initialize theme on page load
27 | const initTheme = () => {
28 | const savedTheme = localStorage.getItem('theme')
29 | const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
30 | const theme = savedTheme || (systemPrefersDark ? 'dark' : 'light')
31 | document.documentElement.setAttribute('data-bs-theme', theme)
32 | }
33 |
34 | initTheme()
35 | ```
36 |
37 | #### Navbar.vue
38 | - Added theme toggle button in the gear dropdown menu
39 | - Added reactive theme state tracking
40 | - Added theme toggle functionality with localStorage persistence
41 |
42 | ## 🎯 How It Works
43 |
44 | ### Initialization
45 | 1. On page load, `main.ts` checks for saved theme in localStorage
46 | 2. If no saved theme, uses system preference (`prefers-color-scheme`)
47 | 3. Applies theme by setting `data-bs-theme` attribute on `` element
48 |
49 | ### Theme Toggle
50 | 1. User clicks theme toggle button in gear menu
51 | 2. Theme switches between 'light' and 'dark'
52 | 3. New theme is saved to localStorage
53 | 4. Bootstrap automatically applies theme styles
54 |
55 | ### UI Updates
56 | - **Light Mode**: Shows moon icon + "Dark Mode" text
57 | - **Dark Mode**: Shows sun icon + "Light Mode" text
58 | - Button is located in the gear dropdown menu in the navbar
59 |
60 | ## 🎨 Bootstrap Theme Support
61 |
62 | Bootstrap automatically applies themes based on the `data-bs-theme` attribute:
63 |
64 | ```html
65 |
66 |
67 |
68 |
69 |
70 | ```
71 |
72 | This affects:
73 | - Background colors
74 | - Text colors
75 | - Border colors
76 | - Component variants
77 | - And all other Bootstrap theme-aware styles
78 |
79 | ## 🔍 Usage
80 |
81 | ### For Users
82 | 1. Click the gear icon in the top navbar
83 | 2. Click "Dark Mode" or "Light Mode" to toggle
84 | 3. Theme preference is automatically saved
85 |
86 | ### For Developers
87 | The theme system is fully automatic. No additional code needed in components - they inherit Bootstrap's theme styling automatically.
88 |
89 | ## 📱 Responsive Design
90 |
91 | The theme toggle works on all screen sizes:
92 | - Desktop: Full dropdown menu with icons and text
93 | - Mobile: Collapsed menu that expands when needed
94 | - Theme applies consistently across all viewport sizes
95 |
96 | ## 🚀 Future Enhancements
97 |
98 | If needed, you could extend this system to:
99 | - Add more theme variants (e.g., high contrast)
100 | - Add animation transitions between themes
101 | - Sync theme across multiple browser tabs
102 | - Add theme-specific custom CSS properties
103 |
104 | ## 🔧 Troubleshooting
105 |
106 | ### Theme not applying
107 | - Check that `data-bs-theme` attribute is set on `` element
108 | - Ensure localStorage has read/write permissions
109 | - Verify Bootstrap CSS is loaded
110 |
111 | ### Toggle not working
112 | - Check browser console for JavaScript errors
113 | - Ensure dropdown menu is properly functioning
114 | - Verify theme state is being updated in component
115 |
116 | ## 🎉 Complete!
117 |
118 | The theme system is now fully functional with minimal code changes. Users can toggle between light and dark modes, and their preference will be remembered across sessions!
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # Development Guide
2 |
3 | ## Quick Start
4 |
5 | 1. **Backend Only**:
6 | ```bash
7 | cd backend
8 | npm start
9 | # or for development with auto-restart:
10 | npm run dev
11 | ```
12 |
13 | 2. **Frontend Only**:
14 | ```bash
15 | cd frontend
16 | npm run dev
17 | ```
18 |
19 | 3. **Both (Windows)**:
20 | ```cmd
21 | start.bat
22 | ```
23 |
24 | 4. **Both (Linux/Mac)**:
25 | ```bash
26 | chmod +x start.sh
27 | ./start.sh
28 | ```
29 |
30 | ## Testing API Endpoints
31 |
32 | ### Health Check
33 | ```bash
34 | curl http://localhost:3000/api/health
35 | ```
36 |
37 | ### Containers
38 | ```bash
39 | # List all containers
40 | curl http://localhost:3000/api/containers
41 |
42 | # Get specific container
43 | curl http://localhost:3000/api/containers/{container_id}
44 |
45 | # Start container
46 | curl -X POST http://localhost:3000/api/containers/{container_id}/start
47 |
48 | # Stop container
49 | curl -X POST http://localhost:3000/api/containers/{container_id}/stop
50 |
51 | # Remove container
52 | curl -X DELETE http://localhost:3000/api/containers/{container_id}
53 |
54 | # Get container logs
55 | curl http://localhost:3000/api/containers/{container_id}/logs?tail=50
56 | ```
57 |
58 | ### Images
59 | ```bash
60 | # List all images
61 | curl http://localhost:3000/api/images
62 |
63 | # Remove image
64 | curl -X DELETE http://localhost:3000/api/images/{image_id}
65 | ```
66 |
67 | ### Volumes
68 | ```bash
69 | # List all volumes
70 | curl http://localhost:3000/api/volumes
71 |
72 | # Remove volume
73 | curl -X DELETE http://localhost:3000/api/volumes/{volume_name}
74 | ```
75 |
76 | ### Networks
77 | ```bash
78 | # List all networks
79 | curl http://localhost:3000/api/networks
80 |
81 | # Remove network
82 | curl -X DELETE http://localhost:3000/api/networks/{network_id}
83 | ```
84 |
85 | ## Development Tips
86 |
87 | ### Backend Development
88 | - Use `npm run dev` for auto-restart on file changes
89 | - Check logs for Docker API connection issues
90 | - Ensure Docker Desktop is running before starting the backend
91 |
92 | ### Frontend Development
93 | - Hot reload is enabled by default with Vite
94 | - Check browser console for any JavaScript errors
95 | - API calls to backend should work on `http://localhost:3000`
96 |
97 | ### Real-time Features
98 | - WebSocket connection is established automatically
99 | - Real-time updates work for container state changes, removals, etc.
100 | - Check browser Developer Tools → Network tab for WebSocket connection
101 |
102 | ## Common Issues
103 |
104 | ### Backend Won't Start
105 | - **Port 3000 in use**: Kill process on port 3000 or change PORT in .env
106 | - **Docker connection error**: Ensure Docker Desktop is running
107 | - **Module not found**: Run `npm install` in backend directory
108 |
109 | ### Frontend Won't Start
110 | - **Dependencies missing**: Run `npm install` in frontend directory
111 | - **Port conflict**: Vite will automatically use next available port
112 | - **API connection issues**: Ensure backend is running on port 3000
113 |
114 | ### CORS Errors
115 | - Backend CORS is configured for `http://localhost:8080` and common Vite ports
116 | - If using different port, update CORS configuration in `backend/src/server.js`
117 |
118 | ## Production Build
119 |
120 | ### Backend
121 | ```bash
122 | cd backend
123 | npm start
124 | ```
125 |
126 | ### Frontend
127 | ```bash
128 | cd frontend
129 | npm run build
130 | npm run preview
131 | ```
132 |
133 | ## Project Structure
134 |
135 | ```
136 | docker-web-desktop/
137 | ├── backend/ # Node.js Express API
138 | │ ├── src/
139 | │ │ ├── routes/ # API endpoint definitions
140 | │ │ ├── services/ # Docker integration logic
141 | │ │ └── server.js # Main server file
142 | │ ├── package.json
143 | │ └── .env # Environment variables
144 | ├── frontend/ # Vue.js SPA
145 | │ ├── src/
146 | │ │ ├── components/ # Reusable Vue components
147 | │ │ ├── views/ # Page components
148 | │ │ ├── stores/ # Pinia state management
149 | │ │ ├── services/ # API communication
150 | │ │ └── router/ # Vue Router setup
151 | │ └── package.json
152 | ├── start.bat # Windows start script
153 | ├── start.sh # Linux/Mac start script
154 | └── README.md # Main documentation
155 | ```
--------------------------------------------------------------------------------
/.gitignore.template:
--------------------------------------------------------------------------------
1 | # Docker Web Desktop - .gitignore Template
2 | #
3 | # This file serves as a reference for what should typically be ignored
4 | # Copy relevant sections to your local .gitignore as needed
5 |
6 | # =============================================================================
7 | # ENVIRONMENT & CONFIGURATION
8 | # =============================================================================
9 |
10 | # Environment variables
11 | .env
12 | .env.local
13 | .env.development
14 | .env.production
15 | .env.test
16 | .env.*.local
17 |
18 | # Configuration files with sensitive data
19 | config/local.json
20 | config/secrets.json
21 | config/database.json
22 |
23 | # =============================================================================
24 | # DEVELOPMENT TOOLS
25 | # =============================================================================
26 |
27 | # Node.js
28 | node_modules/
29 | npm-debug.log*
30 | yarn-debug.log*
31 | yarn-error.log*
32 | package-lock.json # Uncomment if using yarn
33 | yarn.lock # Uncomment if using npm
34 |
35 | # Build outputs
36 | dist/
37 | build/
38 | coverage/
39 |
40 | # Cache directories
41 | .cache/
42 | .npm/
43 | .yarn/
44 |
45 | # =============================================================================
46 | # EDITORS & IDEs
47 | # =============================================================================
48 |
49 | # VS Code
50 | .vscode/
51 | !.vscode/extensions.json
52 | !.vscode/settings.json
53 |
54 | # JetBrains IDEs
55 | .idea/
56 |
57 | # Sublime Text
58 | *.sublime-*
59 |
60 | # Vim
61 | *.swp
62 | *.swo
63 | *~
64 |
65 | # =============================================================================
66 | # OPERATING SYSTEMS
67 | # =============================================================================
68 |
69 | # macOS
70 | .DS_Store
71 | .DS_Store?
72 | ._*
73 | .Spotlight-V100
74 | .Trashes
75 |
76 | # Windows
77 | Thumbs.db
78 | ehthumbs.db
79 | Desktop.ini
80 |
81 | # Linux
82 | *~
83 |
84 | # =============================================================================
85 | # DOCKER & DEPLOYMENT
86 | # =============================================================================
87 |
88 | # Docker
89 | docker-compose.override.yml
90 | Dockerfile.local
91 | .dockerignore.local
92 |
93 | # Deployment
94 | deploy-config/
95 | *.pem
96 | *.key
97 | *.crt
98 |
99 | # =============================================================================
100 | # DATABASES & STORAGE
101 | # =============================================================================
102 |
103 | # SQLite
104 | *.sqlite
105 | *.sqlite3
106 | *.db
107 |
108 | # Uploads
109 | uploads/
110 | storage/
111 | public/uploads/
112 |
113 | # =============================================================================
114 | # LOGS & MONITORING
115 | # =============================================================================
116 |
117 | # Log files
118 | logs/
119 | *.log
120 | access.log
121 | error.log
122 |
123 | # PM2
124 | .pm2/
125 |
126 | # =============================================================================
127 | # TESTING & QUALITY ASSURANCE
128 | # =============================================================================
129 |
130 | # Coverage reports
131 | coverage/
132 | .nyc_output/
133 |
134 | # Test results
135 | test-results/
136 | cypress/videos/
137 | cypress/screenshots/
138 |
139 | # =============================================================================
140 | # SECURITY
141 | # =============================================================================
142 |
143 | # SSL certificates
144 | *.pem
145 | *.key
146 | *.crt
147 | *.csr
148 | ssl/
149 |
150 | # JWT secrets
151 | jwt-secret.txt
152 |
153 | # API keys
154 | api-keys.json
155 |
156 | # =============================================================================
157 | # BACKUP & TEMPORARY FILES
158 | # =============================================================================
159 |
160 | # Backup files
161 | *.bak
162 | *.backup
163 | *.old
164 | *.orig
165 |
166 | # Temporary files
167 | *.tmp
168 | *.temp
169 | tmp/
170 | temp/
171 |
172 | # =============================================================================
173 | # COMMON IGNORE PATTERNS BY TECHNOLOGY
174 | # =============================================================================
175 |
176 | # Vue.js specific
177 | .vite/
178 | dist-ssr/
179 |
180 | # React specific
181 | .next/
182 | out/
183 |
184 | # Angular specific
185 | .angular/
186 |
187 | # Svelte specific
188 | .svelte-kit/
189 |
190 | # Express.js specific
191 | sessions/
--------------------------------------------------------------------------------
/frontend/src/components/docker/ContainerRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
{{ containerName }}
13 | {{ container.Id.slice(0, 12) }}
14 |
15 |
16 |
17 |
18 | {{ container.Image }}
19 |
20 |
21 |
25 |
26 | {{ container.State }}
27 |
28 |
29 |
30 |
31 |
32 |
33 | {{ formattedDate }}
34 |
35 |
36 |
37 |
45 |
53 |
60 |
67 |
68 |
69 |
70 |
71 |
72 |
144 |
145 |
--------------------------------------------------------------------------------
/frontend/src/components/docker/ComposeModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/frontend/ENVIRONMENT_GUIDE.md:
--------------------------------------------------------------------------------
1 | # Environment Variables Configuration Guide
2 |
3 | ## 📋 Overview
4 |
5 | This Vue.js application supports three different environment configurations:
6 |
7 | - **Development** (`.env`) - Local development
8 | - **Production** (`.env.production`) - Production deployment
9 | - **Docker** (`.env.docker`) - Docker container deployment
10 |
11 | ## 🔧 Environment Files
12 |
13 | ### `.env` (Development)
14 | ```env
15 | VITE_API_BASE_URL=http://localhost:3000
16 | VITE_APP_TITLE=Docker Web Desktop
17 | VITE_APP_VERSION=1.0.0
18 | VITE_DEBUG=true
19 | VITE_SOCKET_URL=http://localhost:3000
20 | VITE_LOG_LEVEL=debug
21 | ```
22 |
23 | ### `.env.production` (Production)
24 | ```env
25 | VITE_API_BASE_URL=https://your-production-api.com
26 | VITE_APP_TITLE=Docker Web Desktop
27 | VITE_APP_VERSION=1.0.0
28 | VITE_DEBUG=false
29 | VITE_SOCKET_URL=https://your-production-api.com
30 | VITE_LOG_LEVEL=error
31 | ```
32 |
33 | ### `.env.docker` (Docker)
34 | ```env
35 | VITE_API_BASE_URL=http://backend:3000
36 | VITE_APP_TITLE=Docker Web Desktop
37 | VITE_APP_VERSION=1.0.0
38 | VITE_DEBUG=false
39 | VITE_SOCKET_URL=http://backend:3000
40 | VITE_LOG_LEVEL=warn
41 | ```
42 |
43 | ## 🚀 Usage Commands
44 |
45 | ### Development
46 | ```bash
47 | npm run dev # Uses .env
48 | npm run build # Uses .env for development build
49 | ```
50 |
51 | ### Production
52 | ```bash
53 | npm run build:production # Uses .env.production
54 | npm run preview:production # Preview production build
55 | ```
56 |
57 | ### Docker
58 | ```bash
59 | npm run dev:docker # Uses .env.docker for development
60 | npm run build:docker # Uses .env.docker for build
61 | npm run preview:docker # Preview docker build
62 | ```
63 |
64 | ## 📝 Available Environment Variables
65 |
66 | | Variable | Description | Default |
67 | |----------|-------------|---------|
68 | | `VITE_API_BASE_URL` | Backend API base URL | `http://localhost:3000` |
69 | | `VITE_APP_TITLE` | Application title | `Docker Web Desktop` |
70 | | `VITE_APP_VERSION` | Application version | `1.0.0` |
71 | | `VITE_DEBUG` | Enable debug logging | `false` |
72 | | `VITE_SOCKET_URL` | Socket.IO server URL | Same as API URL |
73 | | `VITE_LOG_LEVEL` | Logging level | `info` |
74 |
75 | ## 💻 TypeScript Support
76 |
77 | Environment variables are fully typed in `src/env.d.ts`:
78 |
79 | ```typescript
80 | interface ImportMetaEnv {
81 | readonly VITE_API_BASE_URL: string
82 | readonly VITE_APP_TITLE: string
83 | readonly VITE_APP_VERSION: string
84 | readonly VITE_DEBUG: string
85 | readonly VITE_SOCKET_URL: string
86 | readonly VITE_LOG_LEVEL: string
87 | }
88 | ```
89 |
90 | ## 🛠️ Usage in Code
91 |
92 | ### Direct Access
93 | ```typescript
94 | const apiUrl = import.meta.env.VITE_API_BASE_URL
95 | const debug = import.meta.env.VITE_DEBUG === 'true'
96 | ```
97 |
98 | ### Using Environment Utility
99 | ```typescript
100 | import Environment from '@/utils/environment'
101 |
102 | // Get configuration
103 | const config = Environment.config
104 |
105 | // Logging with environment-aware levels
106 | Environment.debug('Debug message')
107 | Environment.info('Info message')
108 | Environment.warn('Warning message')
109 | Environment.error('Error message')
110 |
111 | // Environment checks
112 | if (Environment.isDevelopment) {
113 | // Development-only code
114 | }
115 |
116 | if (Environment.isProduction) {
117 | // Production-only code
118 | }
119 | ```
120 |
121 | ## 🐳 Docker Configuration
122 |
123 | When building for Docker, the application expects the backend to be accessible at `http://backend:3000`. Make sure your Docker Compose or container setup uses the correct service names.
124 |
125 | Example `docker-compose.yml`:
126 | ```yaml
127 | services:
128 | frontend:
129 | build: .
130 | ports:
131 | - "80:80"
132 | depends_on:
133 | - backend
134 |
135 | backend:
136 | # Your backend configuration
137 | ports:
138 | - "3000:3000"
139 | ```
140 |
141 | ## 🔍 Environment Detection
142 |
143 | The application can detect its environment:
144 |
145 | ```typescript
146 | import Environment from '@/utils/environment'
147 |
148 | console.log('Current mode:', Environment.mode)
149 | console.log('Is development:', Environment.isDevelopment)
150 | console.log('Is production:', Environment.isProduction)
151 | ```
152 |
153 | ## 🎯 Best Practices
154 |
155 | 1. **Never commit sensitive data** to environment files
156 | 2. **Use different API URLs** for different environments
157 | 3. **Enable debug only in development**
158 | 4. **Set appropriate log levels** for each environment
159 | 5. **Use TypeScript** for environment variable type safety
160 |
161 | ## 🔒 Security Notes
162 |
163 | - Environment variables starting with `VITE_` are exposed to the client
164 | - Never put secrets or sensitive data in these files
165 | - Use server-side environment variables for sensitive configuration
166 |
167 | ## 🆘 Troubleshooting
168 |
169 | ### Issue: Environment variables not loading
170 | **Solutions:**
171 | 1. Ensure variable names start with `VITE_`
172 | 2. Restart the dev server after changes
173 | 3. Check file naming (`.env.production`, not `.env-production`)
174 |
175 | ### Issue: Wrong environment being used
176 | **Solutions:**
177 | 1. Use the correct npm script for your target environment
178 | 2. Check that the `.env` file exists for the target mode
179 | 3. Verify the `--mode` flag in package.json scripts
--------------------------------------------------------------------------------
/frontend/src/components/docker/ContainerGroup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |