GitOps Deployment & Infrastructure

Infrastructure Loop

Deploying software is simple when you have one client and one server. But when Saffira scaled to multiple enterprise tenants, each residing behind private corporate VPNs and complex security firewalls, doing updates manually became a bottleneck.

Here is how we architected a declaratively orchestrated, GitOps-driven delivery pipeline that handles multi-stage container builds, automated client provisioning, dynamic staging, and air-gapped offline installations.

Saffira GitOps Infrastructure Map

Figure 1.1: Saffira GitOps Delivery and Deployment Infrastructure Map.

The GitOps Release Workflow

Features are integrated from local developers' machines to the central registry. Tag generation triggers a CI/CD runner to compile multi-stage Docker images and push them to the secure container registry.

Interactive Architecture Loop
Git SaaS & Dev loopRunner Build Executor
Code Commit
✓ tested locallydevelop / master
CI/CD Pipeline
semantic-releasetag vX.Y.Z auto
Runner Agent
Company's Serverpull job data
SonarQube Gate
✓ PASS (SAST scan)rules compliance
Docker Compiler
Multi-stage buildscaching optimized
Registry
saffira-websaffira-core

Figure 1.2: Interactive GitOps delivery and deployment orchestration workflow map.

Orchestration Details

1. Isolated Runner Profiles & SSH Security

To maintain strict security boundaries, the CI/CD Runner Agent operates in two isolated roles:

  • Build & Quality Profile: Runs static analysis (SAST) via SonarQube. If vulnerabilities or exposed credentials are found, it immediately aborts (`abort pipeline`). Compiles production images using optimized multi-stage Dockerfiles and pushes them via TLS/HTTPS to the Container Registry.
  • Deploy & Orchestration Profile: Pulls encrypted credentials from the remote Git SaaS platform directly into system RAM. It writes an ephemeral private SSH key at /tmp/id_rsa applying strict chmod 500 permissions (owner read/execute only), destroying the key from disk immediately post-job. Configuration variables are compiled from templates (.env.j2) and written to target nodes with restricted read/write permissions (chmod 0600).

2. Ephemeral Multi-Tenancy for Testing

Homologating features for distinct clients on dedicated production-like clusters was cost-prohibitive. To solve this, we built an Ephemeral Multi-Tenancy staging server designed specifically as a testing sandbox. Here, a single staging machine dynamically provisions isolated, client-specific docker namespaces, allowing developers and QA teams to validate configurations and test client setups under simulated conditions before pushing changes to production.

Ephemeral multi-tenancy testing stacks on the staging server.

Figure 2.1: Ephemeral Multi-Tenancy staging server routing and port-conflict switching workflow.

3. Automated Customer Factory

Admin users register client parameters on Saffira Admin. The backend dynamically writes masked, protected variables straight into the Git provider's project configuration using the platform's REST API. No secrets are stored locally, avoiding local database vulnerabilities.

Authentication is completed via a remote Git **Project Access Token** with write_repository / api scopes. The backend issues a synchronous POST /projects/:id/variables request specifying "masked": true and "protected": true to mask credentials in logs. When an operator triggers a deployment, a REST call to the pipeline trigger endpoint (POST /projects/:id/trigger/pipeline) dispatches the job with the specified environment target variables and version pins.

Customer Factory sequence flow showing secrets injection and deployment orchestration steps.

Figure 2.2: Git Secrets Injection and Orchestration Sequence Diagram.

4. Server Federation: Online vs Air-Gapped

Workloads are split across a distributed cluster matching the target node profiles:

  • Data Server (server_data): Dedicated host for persistence and cache services (MongoDB clusters & Redis caches).
  • Application Server (server_app): Handles Nginx frontend interfaces and backend APIs.
  • AI Inference Server (server_ai): High-performance GPU node running real-time YOLOv5 incident classification.

Online Deployment: The CI/CD Runner acts as the Ansible control node, opening concurrent SSH channels via VPN to deploy updates.

Air-Gapped Deployment (Offline): For remote sites without internet, the Saffira Admin panel triggers the runner to build a local bundle. The runner pulls the 6 Docker images, exports them to a consolidated tarball (saffira-prod-bundle.tar), packages config assets, and bundles them into a single zip archive downloadable from the browser. The field operator carries this secure ZIP on a USB drive and runs a local install script on-site with make prod, ensuring 100% environment parity.

Wrap up

Designing this infrastructure was less about stitching scripts together and more about eliminating the stress of environment parity. Moving from a manual, error-prone checklist to a single declarative loop completely shifted our team's daily momentum. We no longer had to double-check if SSH keys were left on disk or worry about version configurations drifting between online servers and remote nodes.

Instead, we gained the peace of mind to spin up secure, client-specific sandboxes on demand, trust automated validation gates, and package air-gapped updates in a few clicks. What used to be a stressful two-hour deployment process became a quiet, five-minute task.