Documentation
¶
Overview ¶
Package bluegreen implements zero-downtime blue/green and canary deploys for the nSelf CLI (B47 + B48).
Architecture:
- Blue = currently live containers (docker compose project: nself-blue)
- Green = shadow / new containers (docker compose project: nself-green)
On fresh install only blue exists. On deploy, green comes up alongside blue. Traffic is shifted via Nginx upstream weight configuration. Rollback in under 5 seconds by resetting Nginx weights and stopping green.
Feature flag: blue_green_deploy (Y17). When OFF, callers should fall back to the existing rolling strategy. When ON, this package drives the deploy.
Index ¶
Constants ¶
const ( EnvBlue = "blue" EnvGreen = "green" )
Environment labels used for docker compose projects.
const DefaultBluePortOffset = 0
DefaultBluePortOffset is the port offset for blue containers (0 = base ports).
const DefaultGreenPortOffset = 100
DefaultGreenPortOffset is the port offset for green containers (+100).
const StateFile = ".nself/bluegreen/state.json"
StateFile is the path (relative to project root) where blue/green state is persisted.
Variables ¶
This section is empty.
Functions ¶
func GenerateNginxUpstream ¶
func GenerateNginxUpstream(cfg DeployConfig, canaryPercent int) string
GenerateNginxUpstream generates the nginx upstream block for blue/green traffic split. canaryPercent is the percentage of traffic to route to green (0-100). When canaryPercent is 0, all traffic goes to blue. When 100, all traffic goes to green.
Types ¶
type DeployConfig ¶
type DeployConfig struct {
// ProjectRoot is the nSelf project root (contains docker-compose.yml).
ProjectRoot string
// CanaryPercent is the initial canary traffic percentage (1-99).
// 0 means skip canary and go straight to full flip.
CanaryPercent int
// SoakMinutes is the canary soak period in minutes. Default: 5.
SoakMinutes int
// ErrorThresholdPct is the error rate percentage that triggers auto-rollback.
// Default: 1.0.
ErrorThresholdPct float64
// HealthTimeoutSec is the number of seconds to wait for green health.
// Default: 30.
HealthTimeoutSec int
// ForceMigration disables canary and performs a full downtime deploy.
// Required when a migration is not backward-compatible.
ForceMigration bool
// SkipCanary skips the canary phase and flips to 100% immediately.
SkipCanary bool
// DryRun prints steps without executing them.
DryRun bool
// BluePortOffset is the port offset for blue containers. Default: 0.
BluePortOffset int
// GreenPortOffset is the port offset for green containers. Default: 100.
GreenPortOffset int
}
DeployConfig holds all parameters for a blue/green or canary deploy.
type DeployResult ¶
type DeployResult struct {
// Success is true when the deploy completed without error.
Success bool
// Steps is the ordered list of deploy steps with their status.
Steps []DeployStep
// Duration is how long the deploy took.
Duration time.Duration
// CanaryPercent is the final canary percentage (100 if fully promoted).
CanaryPercent int
// RolledBack is true when an auto-rollback was triggered during the soak.
RolledBack bool
// Error is set on failure.
Error string
}
DeployResult is the outcome of a blue/green or canary deploy.
func Deploy ¶
func Deploy(ctx context.Context, cfg DeployConfig) DeployResult
Deploy performs a blue/green canary deploy:
- Pull new images (tagged as green).
- Start green containers (docker compose -p nself-green up -d).
- Health check green (30s timeout).
- Route canary % to green via Nginx weight update.
- Canary soak period with error-rate monitoring.
- Promote to 100% green (or auto-rollback on error threshold).
- Stop and remove blue containers.
- Rename green -> blue in state file.
func Promote ¶
func Promote(ctx context.Context, cfg DeployConfig) DeployResult
Promote flips Nginx to 100% green without a new deploy. Used by `nself deploy --promote` after a manual canary review.
type DeployState ¶
type DeployState struct {
// Active is the currently live environment ("blue" or "green").
Active string `json:"active"`
// BlueVersion is the image tag running in blue.
BlueVersion string `json:"blue_version,omitempty"`
// GreenVersion is the image tag running in green.
GreenVersion string `json:"green_version,omitempty"`
// CanaryPercent is the current canary traffic split (0 = not in canary).
CanaryPercent int `json:"canary_percent"`
// LastDeploy is the timestamp of the last successful deploy.
LastDeploy time.Time `json:"last_deploy"`
// LastRollback is the timestamp of the last rollback, if any.
LastRollback *time.Time `json:"last_rollback,omitempty"`
}
DeployState persists the current blue/green state to disk.
func Status ¶
func Status(projectRoot string) (DeployState, error)
Status returns the current blue/green state from the state file. Returns a zero-value DeployState when no state file exists (fresh install).
type DeployStep ¶
type DeployStep struct {
Name string `json:"name"`
Status string `json:"status"` // pending, running, done, failed, skipped
}
DeployStep is a single step in the deploy sequence.
type MigrationCheckResult ¶
type MigrationCheckResult struct {
// Compatible is true when all pending migrations are safe to run during canary.
Compatible bool
// IncompatibleFiles lists migration files that are NOT backward-compatible.
IncompatibleFiles []string
// Reason explains the incompatibility in human-readable terms.
Reason string
}
MigrationCheckResult describes whether a migration is backward-compatible.
func CheckMigrationCompatibility ¶
func CheckMigrationCompatibility(projectRoot string) MigrationCheckResult
CheckMigrationCompatibility checks whether pending migrations are safe to run during a canary deploy (i.e., backward-compatible with the blue version).
The check is heuristic-based: it scans migration filenames for destructive SQL patterns (DROP COLUMN, DROP TABLE, RENAME COLUMN, ALTER COLUMN TYPE, NOT NULL without DEFAULT). A migration that matches these patterns is flagged as incompatible.
For authoritative checks, users should run `nself migrate --check` which executes the full migration engine against a preview schema.
type RollbackResult ¶
type RollbackResult struct {
// Success is true when the rollback completed without error.
Success bool
// Duration is how long the rollback took.
Duration time.Duration
// Error is set on failure.
Error string
}
RollbackResult is the outcome of a manual rollback.
func Rollback ¶
func Rollback(ctx context.Context, cfg DeployConfig) RollbackResult
Rollback resets Nginx to 100% blue and stops green containers. Target rollback time: < 5 seconds.