Electron & Caddy Integration
Relevant source files
The following files were used as context for generating this wiki page:
The Electron & Caddy integration in the Duplicator project provides a portable, cross-platform environment for a PHP-based accounting application. By embedding the Caddy web server directly within the Electron shell, the application eliminates external dependencies on traditional web server stacks (like Apache or Nginx) while maintaining a high-performance production-ready environment.
The integration serves as a bridge between the Electron frontend and the PHP backend logic, using Caddy as a reverse proxy to manage traffic and serve static assets. This architecture ensures that the complex document processing features, such as PDF imposition and color separation, function consistently across Windows, Linux, and macOS.
Sources: README.md:3-8, main-caddy.js:784-793, caddy/README.md:124-129
System Architecture
The integration follows a multi-process architecture where Electron manages the application lifecycle and two child processes: the Caddy web server and a PHP-SAPI (built-in server) or PHP-FPM process.
Core Components
- Electron (Main Process): Orchestrates the startup of Caddy and PHP, manages windows, and handles system-level IPC commands.
- Caddy Server: Acts as the primary entry point for the frontend, handling static file serving and reverse-proxying dynamic requests to the PHP process.
- PHP Process: Executes the core business logic, database operations (SQLite), and PDF processing.
The following diagram illustrates the lifecycle and communication flow during application startup:
The diagram shows how Electron initializes the networking environment before spawning the necessary backend services.
Sources: main-caddy.js:779-843, main-caddy.js:891-950
Caddy Configuration and Management
Caddy is managed via a Caddyfile located in the application resources. The configuration is dynamically adjusted at runtime, especially on Windows, to accommodate random free ports and platform-specific log paths.
Runtime Configuration
When the application starts, it performs the following steps to configure Caddy:
- Port Discovery: On Windows, it finds a free port to avoid conflicts with other local services.
- Path Resolution: It identifies the location of the Caddy binary based on whether the app is running as an AppImage, a Windows executable, or in a development environment.
- Config Generation: It reads the base
Caddyfile, replaces placeholders (like:8000), and writes a temporary configuration if necessary.
| Feature | Implementation Detail | Source |
|---|---|---|
| Reverse Proxy | Routes traffic from serverPort to PHP_SERVER_PORT (8001) | main-caddy.js:798-802 |
| Static Serving | Serves files from the app/public directory | main-caddy.js:828-837 |
| Binary Search | Checks asar.unpacked and resourcesPath | main-caddy.js:567-595 |
Sources: main-caddy.js:564-600, main-caddy.js:784-815, Caddyfile:1-10
PHP Process Integration
The system uses a PHP process (usually the built-in server -S) to handle backend requests. Electron monitors the standard output (STDOUT) and error (STDERR) of this process to detect fatal errors and communicate status updates to the renderer.
Process Monitoring and Recovery
The integration includes a robust monitoring system for the PHP process:
- Fatal Error Detection: Monitors logs for patterns like
PHP Fatal errororUncaught Exception. - Auto-Restart: Attempts to restart the PHP process up to 3 times if it crashes unexpectedly.
- Status Reporting: Sends IPC messages (channel
php-process-status) to the frontend to inform the user of the backend state.
The sequence diagram details the error handling and recovery loop between Electron and the PHP child process.
Sources: main-caddy.js:108-142, main-caddy.js:337-376, main-caddy.js:393-418
Networking and Inter-Process Communication
The integration relies on local networking and Electron's IPC (Inter-Process Communication) to bridge the frontend and backend.
Technical Network Details
- Default Proxy Port: 8000 (Primary entry point).
- Internal PHP Port: 8001 (Internal communication only).
- Fallback Mechanism: If Caddy fails to start or respond within 5 seconds, the application attempts to load the PHP server directly as a fallback.
IPC Handlers
Electron provides several handlers to allow the web interface to interact with the system environment managed by Caddy/PHP:
| IPC Channel | Action | Description |
|---|---|---|
open-file | shell.openPath | Opens processed PDFs in the system's default viewer. |
restart-php | restartPhpProcess | Manually triggers a backend restart from the UI. |
get-database-path | getDatabasePath | Returns the path to the persistent SQLite DB in userData. |
cleanup-tmp-files | cleanupTmpFiles | Deletes temporary files in app/public/tmp. |
Sources: main-caddy.js:45-77, main-caddy.js:984-1010, main-caddy.js:1044-1065, tests/unit/main-caddy.test.js:103-125
Conclusion
The integration of Electron and Caddy transforms a standard PHP web application into a portable desktop tool. By automating port management, process monitoring, and reverse proxy configuration, the system provides a seamless user experience while leveraging the stability of the Caddy web server and the flexibility of the PHP ecosystem.
Sources: README.md:65-72, main-caddy.js:1150-1165