🏗️ Multi-Build Architecture
The Docker Build Agent solution supports multiple independent builds within the same solution structure, enabling specialized build processes for different project types and use cases.
Build Types Available
- Docker Build (
forge/Docker/
) - Container builds and deployment - Node Build (
forge/Node/
) - Node.js applications and documentation - NodeInDocker Build (
forge/NodeInDocker/
) - Combined Node.js + Docker pipeline - NodeTemplate Build (
forge/NodeTemplate/
) - Template-based documentation sites - Forge Build (
forge/Forge/
) - Build orchestration and tooling
Build Architecture
Forge.sln
├── Common/ (shared utilities - referenced by all builds)
├── Docker/ (independent Docker build)
│ ├── Docker.cs (main build class)
│ ├── Docker.csproj (executable project)
│ └── Parameters/ (Docker-specific parameters)
├── Node/ (independent Node.js build)
│ ├── Node.cs (main build class)
│ ├── Node.csproj (executable project)
│ └── Parameters/ (Node-specific parameters)
├── NodeInDocker/ (combined Node.js + Docker build)
│ ├── NodeInDocker.cs (main build class)
│ ├── NodeInDocker.csproj (executable project)
│ └── Parameters/ (NodeInDocker-specific parameters)
├── NodeTemplate/ (template-based documentation build)
│ ├── NodeTemplate.cs (main build class)
│ ├── NodeTemplate.csproj (executable project)
│ └── Parameters/ (NodeTemplate-specific parameters)
├── Forge/ (independent orchestrator build)
│ ├── Forge.cs (main build class)
│ ├── Forge.csproj (executable project)
│ └── Parameters/ (Forge-specific parameters)
└── [Build Scripts at Root Level]
Usage Options
Option 1: Container-Based (Recommended)
Use the Docker Build Agent container to execute builds:
# Docker build
docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ./:/workspace \
-it ghcr.io/the-running-dev/build-agent:latest \
docker-build
# Node.js build
docker run \
-v ./:/workspace \
-it ghcr.io/the-running-dev/build-agent:latest \
node-build
# Combined Node.js + Docker build
docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ./:/workspace \
-it ghcr.io/the-running-dev/build-agent:latest \
node-in-docker-build
# Template-based documentation build
docker run \
-v ./:/workspace \
-it ghcr.io/the-running-dev/build-agent:latest \
node-template-build
# Changelog generation and build orchestration
docker run \
-v ./:/workspace \
-it ghcr.io/the-running-dev/build-agent:latest \
forge --target GenerateChangeLog
Option 2: Local PowerShell Scripts
Use the local build script for development:
# Basic usage
.\build.ps1 -type docker
.\build.ps1 -type node
.\build.ps1 -type node-in-docker
.\build.ps1 -type forge
# With additional parameters
.\build.ps1 -type docker -isProd --image-tag myapp:v1.0.0
.\build.ps1 -type node --artifacts-dir ./dist
.\build.ps1 -type forge --change-log-source all
Option 3: Direct NUKE Commands
Run builds directly with NUKE CLI (for development):
# Compile and run specific projects
dotnet run --project forge/Docker/Docker.csproj -- Build
dotnet run --project forge/Node/Node.csproj -- Build
dotnet run --project forge/Forge/Forge.csproj -- GenerateChangeLog
dotnet run --project forge/Node/Node.csproj -- Build
dotnet run --project forge/NodeInDocker/NodeInDocker.csproj -- Build
dotnet run --project forge/NodeTemplate/NodeTemplate.csproj -- Build
# Or use NUKE CLI after building
nuke --root forge/Docker Build
nuke --root forge/Node Build
Build Responsibilities
Docker Build (forge/Docker/
)
- Purpose: Container image creation, registry management, deployment
- Key Targets:
Setup
,Clean
,Build
,BuildDockerImage
,PushToRegistry
,PublishToGitHub
- Parameters: Registry URLs, image tags, Dockerfiles, authentication tokens
- Dependencies: Docker Engine, container registries
- Use Cases: Containerizing existing applications, infrastructure deployment
Node Build (forge/Node/
)
- Purpose: Node.js application builds, package management, artifact creation
- Key Targets:
Setup
,Clean
,InstallDependencies
,BuildApplication
,CopyToArtifacts
- Parameters: Package managers, build scripts, output directories
- Dependencies: Node.js, npm/yarn/pnpm
- Use Cases: Frontend applications, Node.js APIs, static site generation
NodeInDocker Build (forge/NodeInDocker/
)
- Purpose: Complete CI/CD pipeline combining Node.js build with Docker containerization
- Key Targets: 10-step pipeline from setup to GitHub release
- Parameters: Combines all Node and Docker parameters
- Dependencies: Node.js, Docker Engine, container registries
- Use Cases: Production deployments, microservices, containerized web applications
NodeTemplate Build (forge/NodeTemplate/
)
- Purpose: Documentation site generation using templates (Docusaurus, etc.)
- Key Targets:
Setup
,CloneTemplate
,CopyTemplateFiles
,BuildDocumentation
- Parameters: Template repositories, documentation directories, build configurations
- Dependencies: Node.js, Git, template repositories
- Use Cases: Project documentation, API documentation, static documentation sites
Forge Build (forge/Forge/
)
- Purpose: Build orchestration, changelog generation, release management
- Key Targets:
ChangeLog
,Build
,Setup
,Release
- Parameters: Git tags, changelog sources, release configurations
- Dependencies: Git, build tools, notification systems
- Use Cases: Release management, build coordination, changelog automation
Shared Components
Common Project (forge/Common/
)
All builds share utilities from the Common project:
- Services/: Git, GitHub, Docker, and Node.js service interfaces
- Utilities/: Helper classes and extension methods
- Extensions/: File system and process extensions
- Parameters/: Base parameter classes with inheritance hierarchy
- Notifications/: Discord and other notification systems
- DependencyInjection/: Service container and dependency management
Base Classes
All builds inherit from Base<TParams, TNotifications>
:
- Provides consistent logging with Serilog
- Standardized parameter handling with dependency injection
- Built-in notification support
- Common target patterns and error handling
- Service injection for Git, GitHub, Docker, and Node.js operations
Parameter Inheritance
The parameter system uses inheritance for shared functionality:
ForgeParams (base)
├── DockerParams (extends ForgeParams)
├── NodeParams (extends ForgeParams)
└── NodeInDockerParams (extends DockerParams)
This allows builds to share common parameters while maintaining their specific configurations.
Adding New Build Types
To add another build type (e.g., "Database", "Mobile", "API"):
1. Create Project Structure
forge/Database/
├── Database.cs (main build class)
├── Database.csproj (executable project)
├── Parameters/
│ └── DatabaseParams.cs (parameter class)
└── Services/
└── IDatabaseService.cs (service interface)
2. Implement Build Class
public class Database : Base<DatabaseParams, DiscordNotifications>
{
public Target Setup => _ => _
.Executes(() => {
// Build setup logic
});
public Target Build => _ => _
.DependsOn(Setup)
.Executes(() => {
// Main build logic
});
}
3. Add to Container
Add the new executable to the Docker Build Agent container in the Dockerfile.
4. Update Documentation
Add the new build type to the build-types.md documentation with usage examples and parameters.
Best Practices
1. Build Independence
- Each build should be runnable independently
- Minimize cross-dependencies between builds
- Use Common project for shared functionality only
- Implement proper error handling and cleanup
2. Consistent Patterns
- Follow the same
Base<TParams, TNotifications>
inheritance - Use consistent target naming conventions (Setup, Clean, Build)
- Implement dependency injection for services
- Use strongly-typed parameters with validation
3. Clear Responsibilities
- Keep each build focused on its specific domain
- Avoid feature overlap between builds
- Document build purposes and capabilities
- Provide clear usage examples and parameter documentation
4. Service Management
- Use dependency injection for all external dependencies
- Implement service interfaces for testability
- Register services in the Common project
- Follow SOLID principles for service design
Migration Strategy
From Single Build to Multi-Build
- Gradual Migration: Start with one specialized build type
- Maintain Compatibility: Keep existing scripts working during transition
- Test Independently: Each build can be developed and tested separately
- Documentation: Update docs as new build types are added
Legacy Support
- Original
build.ps1
continues to work for Docker builds - Container-based execution provides consistent environment
- PowerShell scripts offer local development experience
- Direct NUKE commands available for advanced users
Troubleshooting
Common Issues
Build Not Found
No build type specified or invalid build type
Solution: Use valid build types: docker, node, node-in-docker, node-template
Project Not Found
Could not find project 'forge/[BuildType]/[BuildType].csproj'
Solution: Ensure the project exists and is built (dotnet build
)
Parameter Issues
Unknown parameter '--some-param'
Solution: Check parameter documentation for the specific build type
Service Dependencies
Service not registered or dependency injection failure
Solution: Verify services are registered in ServiceCollectionExtensions
Debug Tips
- Use
--verbosity Verbose
for detailed logging - Use
--dry-run true
to test without side effects - Check container logs for Docker-related issues
- Verify environment variables and secrets are set correctly