# Workflow Build & Push ```mermaid sequenceDiagram participant Client as Client/API User participant APIHandler as API Handler (apps.go) participant BuildOrchestrationSvc as BuildOrchestrationService participant DB as Database (dbstore) participant BuildKitClientSvc as BuildKitClient (BuildMachineClient) participant GitRepo as Git Repository participant RegistryClientSvc as RegistryClient participant DockerRegistry as Docker Registry Client->>+APIHandler: POST /apps/{id}/build (Request Build) APIHandler->>+BuildOrchestrationSvc: RequestBuild(appId, buildConfig) BuildOrchestrationSvc->>+DB: CreateBuildJob(appId, status: PENDING) DB-->>-BuildOrchestrationSvc: buildJobId Note over BuildOrchestrationSvc: Enqueues buildJobId BuildOrchestrationSvc-->>-APIHandler: Ack (Build Queued, buildJobId) APIHandler-->>-Client: HTTP 202 Accepted (Build Queued) loop Process Build Queue BuildOrchestrationSvc->>BuildOrchestrationSvc: Dequeue buildJobId BuildOrchestrationSvc->>+DB: UpdateBuildJobStatus(buildJobId, FETCHING) DB-->>-BuildOrchestrationSvc: OK BuildOrchestrationSvc->>+BuildKitClientSvc: FetchSource(gitURL, commit, buildJobId) BuildKitClientSvc->>+GitRepo: Clone/Pull code GitRepo-->>-BuildKitClientSvc: Source code BuildKitClientSvc-->>-BuildOrchestrationSvc: Fetch Success / Logs BuildOrchestrationSvc->>+DB: UpdateBuildJobStatus(buildJobId, BUILDING) DB-->>-BuildOrchestrationSvc: OK BuildOrchestrationSvc->>+BuildKitClientSvc: BuildImage(sourcePath, dockerfile, buildArgs, imageName, buildJobId) Note over BuildKitClientSvc: Interacts with BuildKit daemon BuildKitClientSvc-->>-BuildOrchestrationSvc: Build Success / Logs / ImageID alt Build Successful BuildOrchestrationSvc->>+DB: UpdateBuildJobStatus(buildJobId, PUSHING) DB-->>-BuildOrchestrationSvc: OK BuildOrchestrationSvc->>+RegistryClientSvc: PushImage(imageID, imageNameWithTag, authConfig) Note over RegistryClientSvc: Delegates to BuildKitClient for actual push RegistryClientSvc->>+BuildKitClientSvc: PushImageInternal(imageID, imageNameWithTag, authConfig) BuildKitClientSvc->>+DockerRegistry: Push image layers DockerRegistry-->>-BuildKitClientSvc: Push Acknowledged BuildKitClientSvc-->>-RegistryClientSvc: Push Success / Logs RegistryClientSvc-->>-BuildOrchestrationSvc: Push Success / Logs BuildOrchestrationSvc->>+DB: UpdateBuildJobStatus(buildJobId, SUCCESS, imageTag) DB-->>-BuildOrchestrationSvc: OK BuildOrchestrationSvc->>+DB: UpdateAppCurrentImage(appId, imageTag, imageURI) DB-->>-BuildOrchestrationSvc: OK else Build or Push Failed BuildOrchestrationSvc->>+DB: UpdateBuildJobStatus(buildJobId, FAILED, errorMessage) DB-->>-BuildOrchestrationSvc: OK end end ``` ## Preview Service Workflow ```mermaid sequenceDiagram participant Client as Client/API User participant APIHandler as API Handler (preview.go) participant PreviewSvcManager as PreviewServiceManager participant DB as Database (dbstore) participant LocalPreviewSvc as LocalPreviewService participant RemotePreviewSvc as RemotePreviewService participant BuildKitClientSvc as BuildKitClient (via PreviewCommon) participant DockerDaemon as Local Docker Daemon participant CloudProvider as Cloud Provider (e.g., OVH) participant RemoteVPS as Remote VPS Client->>APIHandler: POST /previews (appId) APIHandler->>PreviewSvcManager: CreatePreview(appId) alt Use Local Preview (dev/testing) PreviewSvcManager->>LocalPreviewSvc: CreatePreview(appId) activate LocalPreviewSvc LocalPreviewSvc->>DB: GetAppByID(appId) DB-->>LocalPreviewSvc: AppDetails LocalPreviewSvc->>DB: CreatePreviewRecord(appId, status: BUILDING) DB-->>LocalPreviewSvc: previewId Note over LocalPreviewSvc: Async: buildAndDeployPreview(preview, app) LocalPreviewSvc-->>PreviewSvcManager: Preview (pending) deactivate LocalPreviewSvc PreviewSvcManager-->>APIHandler: Preview (pending) APIHandler-->>Client: HTTP 200 OK (Preview pending) LocalPreviewSvc->>LocalPreviewSvc: buildAndDeployPreview() activate LocalPreviewSvc LocalPreviewSvc->>DB: GetAppComponents(app) DB-->>LocalPreviewSvc: Components LocalPreviewSvc->>BuildKitClientSvc: BuildComponentImages(components) activate BuildKitClientSvc Note over BuildKitClientSvc: Interacts with BuildKit daemon BuildKitClientSvc-->>LocalPreviewSvc: ImageNames, BuildLogs deactivate BuildKitClientSvc LocalPreviewSvc->>DB: UpdatePreviewBuildLogs(previewId, buildLogs) DB-->>LocalPreviewSvc: OK LocalPreviewSvc->>DB: UpdatePreviewStatus(previewId, DEPLOYING) DB-->>LocalPreviewSvc: OK LocalPreviewSvc->>LocalPreviewSvc: GeneratePreviewURL(localTLD) LocalPreviewSvc->>DB: UpdatePreviewVPS(previewId, "byop.local", "127.0.0.1", previewURL) DB-->>LocalPreviewSvc: OK LocalPreviewSvc->>LocalPreviewSvc: GenerateDockerCompose(imageNames, app, previewURL) LocalPreviewSvc->>DockerDaemon: docker-compose up -d (Traefik for routing) activate DockerDaemon DockerDaemon-->>LocalPreviewSvc: Deployment Success/Logs deactivate DockerDaemon LocalPreviewSvc->>DB: UpdatePreviewDeployLogs(previewId, deployLogs) DB-->>LocalPreviewSvc: OK LocalPreviewSvc->>DB: UpdatePreviewStatus(previewId, RUNNING) DB-->>LocalPreviewSvc: OK LocalPreviewSvc->>DB: UpdateAppPreview(appId, previewId, previewURL) DB-->>LocalPreviewSvc: OK deactivate LocalPreviewSvc else Use Remote Preview (production) PreviewSvcManager->>RemotePreviewSvc: CreatePreview(appId) activate RemotePreviewSvc RemotePreviewSvc->>DB: GetAppByID(appId) DB-->>RemotePreviewSvc: AppDetails RemotePreviewSvc->>DB: CreatePreviewRecord(appId, status: BUILDING) DB-->>RemotePreviewSvc: previewId Note over RemotePreviewSvc: Async: buildAndDeployPreview(preview, app) RemotePreviewSvc-->>PreviewSvcManager: Preview (pending) deactivate RemotePreviewSvc PreviewSvcManager-->>APIHandler: Preview (pending) APIHandler-->>Client: HTTP 200 OK (Preview pending) RemotePreviewSvc->>RemotePreviewSvc: buildAndDeployPreview() activate RemotePreviewSvc RemotePreviewSvc->>DB: GetAppComponents(app) DB-->>RemotePreviewSvc: Components RemotePreviewSvc->>BuildKitClientSvc: BuildComponentImages(components) activate BuildKitClientSvc Note over BuildKitClientSvc: Interacts with BuildKit daemon BuildKitClientSvc-->>RemotePreviewSvc: ImageNames, BuildLogs deactivate BuildKitClientSvc RemotePreviewSvc->>DB: UpdatePreviewBuildLogs(previewId, buildLogs) DB-->>RemotePreviewSvc: OK RemotePreviewSvc->>DB: UpdatePreviewStatus(previewId, DEPLOYING) DB-->>RemotePreviewSvc: OK RemotePreviewSvc->>CloudProvider: FindAvailablePreviewVPS() / ProvisionVPS() activate CloudProvider CloudProvider-->>RemotePreviewSvc: VPSDetails (vpsId, ipAddress) deactivate CloudProvider RemotePreviewSvc->>RemotePreviewSvc: GeneratePreviewURL(remoteTLD) RemotePreviewSvc->>DB: UpdatePreviewVPS(previewId, vpsId, ipAddress, previewURL) DB-->>RemotePreviewSvc: OK RemotePreviewSvc->>RemotePreviewSvc: GenerateDockerCompose(imageNames, app, previewURL) loop For each Image RemotePreviewSvc->>DockerDaemon: docker save image (to .tar) activate DockerDaemon DockerDaemon-->>RemotePreviewSvc: image.tar deactivate DockerDaemon RemotePreviewSvc->>RemoteVPS: SCP image.tar to /tmp/ activate RemoteVPS RemoteVPS-->>RemotePreviewSvc: Transfer OK RemotePreviewSvc->>RemoteVPS: SSH: docker load -i /tmp/image.tar RemoteVPS-->>RemotePreviewSvc: Load OK deactivate RemoteVPS RemotePreviewSvc->>RemotePreviewSvc: rm /tmp/image.tar (local) end RemotePreviewSvc->>RemoteVPS: SCP docker-compose.yml to /home/debian/preview-{id}/ activate RemoteVPS RemoteVPS-->>RemotePreviewSvc: Transfer OK RemotePreviewSvc->>RemoteVPS: SSH: cd /home/debian/preview-{id}/ && docker-compose up -d RemoteVPS-->>RemotePreviewSvc: Deployment Success/Logs deactivate RemoteVPS RemotePreviewSvc->>DB: UpdatePreviewDeployLogs(previewId, deployLogs) DB-->>RemotePreviewSvc: OK RemotePreviewSvc->>DB: UpdatePreviewStatus(previewId, RUNNING) DB-->>RemotePreviewSvc: OK RemotePreviewSvc->>DB: UpdateAppPreview(appId, previewId, previewURL) DB-->>RemotePreviewSvc: OK deactivate RemotePreviewSvc end ```