Skip to content
Projects

anuragxxd/conops has 43 GitHub stars and 1 forks. GitHot measured 0 stars in 24 hours and 0 in 7 days. Last checked 2026-11-09 18:53 UTC. Last push 2026-09-22.

How these counts are measured

GitOps controller for Docker Compose - Self-healing, Git-driven deployments without Kubernetes

What you can do

  • Git-driven deployments — push to your branch, ConOps handles the rest
  • Continuous reconciliation — configurable loop that keeps desired state in sync
  • Self-healing — detects missing, exited, or unhealthy containers and recovers
  • Docker preflight + fallback toolchain — checks Docker API compatibility before sync

Measured star growth

in 24h
0
in 7 days
0
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

README.md

Original

ConOps Logo
ConOps

GitOps for Docker Compose. Like Argo CD, but without Kubernetes.

GitHub stars Docker Pulls License Release

Point ConOps at a Git repo containing a docker-compose.yaml.
It clones, pulls, deploys, watches for new commits, detects container drift, and self-heals.
One binary. No cluster required.

Quick Start · Features · Usage Guide · Configuration · API


ConOps Demo

Quick Start

Run ConOps with a single command:

docker run \
  --name conops \
  -p 127.0.0.1:8080:8080 \
  -e CONOPS_RUNTIME_DIR=/tmp/conops-runtime \
  -v /tmp/conops-runtime:/tmp/conops-runtime \
  -v conops_data:/data \
  -v /var/run/docker.sock:/var/run/docker.sock \
  anurag1201/conops:latest

Open http://localhost:8080 and click New App.

Note: For production use, we recommended using Docker Compose.

Security: The port is bound to 127.0.0.1 because ConOps has no built-in authentication and mounts the Docker socket. Reach it remotely over an SSH tunnel (ssh -L 8080:127.0.0.1:8080 host) or a private network, rather than publishing it.

Features

  • Git-driven deployments — push to your branch, ConOps handles the rest
  • Continuous reconciliation — configurable loop that keeps desired state in sync
  • Self-healing — detects missing, exited, or unhealthy containers and recovers
  • Docker preflight + fallback toolchain — checks Docker API compatibility before sync
  • Web UI — register apps, inspect status, view containers, trigger syncs, read logs
  • REST API + CLI — automate everything; nothing in the UI that the API can't do
  • Private repo support — GitHub deploy keys with AES-GCM encryption at rest
  • SQLite or PostgreSQL — SQLite for single-node, Postgres for production
  • Single binary — no runtime dependencies beyond Docker and Git

Usage Guide

ConOps can be managed in two ways: via the Web Dashboard or the REST API / CLI.

Method 1: Web Dashboard

The easiest way to get started. Navigate to http://localhost:8080.

  • Dashboard: View all registered applications and their current status (synced, syncing, pending, error).
  • New App: Click the button to register a repository. You'll need the Git URL, branch name, and path to the Compose file.
  • App Details: Click on any app to see its sync history, container health, and logs.
  • Actions: You can manually trigger a sync or delete an app directly from its card.

Method 2: REST API & CLI

ConOps is API-first. Every action available in the UI can be performed via the REST API.

CLI Tool (conops-ctl)

The conops-ctl CLI helps you manage applications from your terminal.

Installation:

# Install the latest version to /usr/local/bin
curl -sfL https://raw.githubusercontent.com/anuragxxd/conops/master/install.sh | sudo sh

Or download pre-built binaries from the Releases page.

Configuration: Set the controller URL if running remotely (defaults to http://localhost:8080):

export CONOPS_URL="http://conops.example.com:8080"

Commands:

# List all apps
./conops-ctl apps list

# Register an app (supports private repos via JSON)
./conops-ctl apps add app.json

# Get detailed status
./conops-ctl apps get <app-id>

# Update configuration (partial updates supported)
./conops-ctl apps update <app-id> --branch feature/login --poll-interval 1m

# Force immediate sync
./conops-ctl apps sync <app-id>

REST API

You can interact directly with the API using curl.

1. Register an App

curl -X POST http://localhost:8080/api/v1/apps/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example App",
    "repo_url": "https://github.com/docker/awesome-compose",
    "repo_auth_method": "public",
    "branch": "master",
    "compose_path": "fastapi/compose.yaml",
    "poll_interval": "30s"
  }'

2. List Apps

curl http://localhost:8080/api/v1/apps/

3. Get App Details

curl http://localhost:8080/api/v1/apps/{id}

4. Force Sync

curl -X POST http://localhost:8080/api/v1/apps/{id}/sync

5. Update App

curl -X PATCH http://localhost:8080/api/v1/apps/{id} \
  -H "Content-Type: application/json" \
  -d '{ "poll_interval": "1m" }'

6. Delete App

curl -X DELETE http://localhost:8080/api/v1/apps/{id}

Configuration

All configuration is via environment variables.

Variable Default Description
DB_TYPE sqlite Storage backend: sqlite or postgres
DB_CONNECTION_STRING — Required when using postgres
CONOPS_RECONCILE_INTERVAL 10s How often the reconciler runs
CONOPS_SYNC_TIMEOUT 5m Max duration for a single sync operation
CONOPS_RETRY_ERRORS false Auto-retry apps that entered error status
CONOPS_RUNTIME_DIR ./.conops-runtime Runtime checkout directory used for compose execution
CONOPS_TOOLS_DIR ./.conops-tools Cache directory for managed Docker CLI and Compose plugin downloads
CONOPS_ENCRYPTION_KEY — 32-byte key (raw or base64) for deploy key encryption
CONOPS_ENCRYPTION_KEY_FILE /data/conops-encryption.key Path to read/write the encryption key

Production Setup

For production, we recommend running ConOps with Docker Compose to handle persistence and networking cleanly.

services:
  conops:
    image: anurag1201/conops:latest
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      - CONOPS_RUNTIME_DIR=/tmp/conops-runtime
      - DB_TYPE=sqlite
    volumes:
      # Persist SQLite DB and encryption keys
      - conops_data:/data
      # Allow ConOps to manage sibling containers
      - /var/run/docker.sock:/var/run/docker.sock
      # Runtime directory for checkouts
      - /tmp/conops-runtime:/tmp/conops-runtime

volumes:
  conops_data:

Private Repositories

ConOps supports private GitHub/GitLab repositories via SSH deploy keys.

When registering an app via the API, set repo_auth_method to deploy_key and provide the private key:

curl -X POST http://localhost:8080/api/v1/apps/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Private App",
    "repo_url": "[email protected]:my-org/private-repo.git",
    "repo_auth_method": "deploy_key",
    "deploy_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----",
    "branch": "main",
    "compose_path": "docker-compose.yml"
  }'

Security: Deploy keys are encrypted at rest using AES-GCM. ConOps auto-generates an encryption key on first run, or you can provide your own via CONOPS_ENCRYPTION_KEY.

How It Works

                    ┌─────────────┐
                    │  Git Repo   │
                    └──────┬──────┘
                           │ poll
                    ┌──────▼──────┐
                    │ Git Watcher │──── new commit? ──→ mark pending
                    └─────────────┘
                           │
                    ┌──────▼──────┐
                    │ Reconciler  │──── clone/fetch → compose pull → compose up
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │Drift Checker│──── container missing/exited/unhealthy? → requeue
                    └─────────────┘

Status flow: registered → pending → syncing → synced.

ConOps separates change detection (Git watcher) from state application (reconciler). This keeps the control loop predictable and easy to reason about.

Development

# Run the controller locally
go run ./cmd/conops

# Build the CLI
go build -o bin/conops-ctl ./cmd/conops-ctl

# Run tests
go test ./...

License

MIT — see LICENSE.

Explore related projects