Understanding Zerops Build Cache
Zerops implements a sophisticated two-layer caching strategy that optimizes build times while maintaining complete control over the build environment. This documentation explores the architecture, configuration patterns, and practical implementation of the build cache system.
Architecture Overview​
The build cache operates through two distinct layers:
- Base Layer: Comprises the OS, installed dependencies, and prepare commands
- Build Layer: Contains the state after executing build commands
The layers work together to create an efficient and predictable build environment, though they are currently coupled in their cache invalidation behavior (invalidating one layer affects the other).
Cache Implementation​
The caching mechanism is implemented through an efficient file movement strategy. This approach ensures near-instantaneous cache operations through simple directory relocation within the container, implementing the following characteristics:
- Files are moved between
/build/source
and/build/cache
using container-level rename operations - No packaging, compression, or network transfer is involved
- Cache preservation is achieved through simple directory relocation within the container
- Files maintain their original state and permissions throughout the process
See detailed build process lifecycle.
Configuration Guide​
Essential zerops.yml Fields​
The following fields in zerops.yml
affect build cache behavior:
Direct Cache Configuration:
build.cache
: Explicitly defines what should be cached through paths or patterns
Cache Invalidation Triggers: These parameters trigger cache invalidation when modified:
build.os
: Base operating system selectionbuild.base
: Pre-installed software stacks and runtimesbuild.prepareCommands
: System preparation and dependency installationbuild.cache
: Changes to cache configuration
Build Artifact Generation:
build.buildCommands
: Generates the build artifact that will be deployed.
Cache Configuration Patterns​
Pattern 1: System-Wide Cache Control​
The boolean values provide system-wide cache control:
cache: true
:
- Preserves the entire build container state
- Maintains system-level package installations
- Ideal for globally installed packages (Python/PHP packages, Go modules)
cache: false
:
- Intended to disable all caching
- Currently, due to layer coupling, only files within
/build/source
are not cached - Everything outside
/build/source
remains cached (see Common Pitfalls: Layer Coupling)
Pattern 2: Path-Specific Caching​
Execution flow:
- Source code extraction to
/build/source
- Build command execution
- Specified path preservation in
/build/cache
- Cached content restoration (no-clobber mode - source files take precedence)
Ideal for non-versioned dependencies in your working directory (e.g., node_modules
, vendor
, .venv
).
Path Pattern Reference​
Zerops supports Go's filepath.Match syntax. Consider this example structure:
Pattern examples and matches:
All patterns resolve relative to /build/source
. Path variations like ./node_modules
, node_modules
, and node_modules/
are treated identically.
Build Process Lifecycle​
-
Initialization Phase
- Build container startup
- Builder process launch
- Source code loading into
/build/source
-
Cache Restoration Phase
- Cached file movement to
/build/source
(no-clobber mode) - Source file precedence handling
- Conflict logging (no build interruption)
- Cache directory cleanup
- Cached file movement to
-
Build Execution Phase
- Build command processing
- Artifact packaging (
build.deployFiles
)
-
Cache Preservation Phase
- Specific cache files movement outside
/build/source
/build/source
directory cleanup- Container termination
- Specific cache files movement outside
Cache Invalidation Reference​
The build cache invalidates under these conditions:
-
Manual Triggers
- API call:
DELETE /service-stack/{id}/build-cache
- GUI: Manual cache clear action
- API call:
-
Version Management
- Backup app version activation via
PUT /app-version/{id}/deploy
- Backup app version activation via
-
Configuration Changes Any modifications to:
Current Pitfalls​
The current implementation has some important characteristics:
-
Layer Coupling
Even with
cache: false
, Go modules outside/build/source
remain cached. -
Cascade Invalidation
Modifying
prepareCommands
invalidates both layers, including cachednode_modules
.
Real-World Implementation Examples​
Node.js Project with TypeScript​
Go Project with Multiple Dependencies​
PHP/Laravel Project​
Debugging and Monitoring​
- Build Logs
- Cache operations are detailed in build logs
- File conflicts during restoration are logged
- Cache preservation status is visible
Implementation Best Practices​
Cache Strategy Optimization​
-
Layer Management
- Maintain stable
prepareCommands
to prevent cache invalidation - Group related prepare commands logically
- Maintain stable
-
Performance Optimization:
- Cache package manager lock files alongside dependency directories
- Use system-wide caching (
cache: true
) for languages with global package managers
-
Performance Tuning
- Leverage system-wide caching for complex builds
- Monitor build logs for cache operations and potential conflicts
- Use explicit patterns for precise control
- Don't over-optimize – the system handles large caches efficiently
Future Development​
Planned system enhancements include:
- Layer independence implementation
- Granular cache control mechanisms
- Enhanced layer management capabilities
- Improved cache invalidation patterns