Skip to content

CanaryCD

Continuous Deployment API for Container and Static Pages.

CanaryCD is a simple API to Deploy Projects and Pages utilizing GitOps and CIOps Principles for different Environments associated branches.

Source · Documentation

PyPI-Badge Python-Badge License-Badge

CanaryCD-Badge

Disclaimer

This is a WIP, it may not reflect recent changes and could include features not yet implemented.

Features

  • Projects


    Manage Projects based on Git Repositories authenticate with SSH Keys, Github PAT or Github App. Deploy with CLI, Webhook, API or by Cron.

  • Environments


    Multiple Environments per Project corresponding to a different git branch. Environment variables are AES-GCM Encrypted.

  • Pages


    Simple Push API for Static Page Hosting. Dump traefik dynamic configuration and provide a static hosting container.

  • Redirects


    Simple HTTP redirects

  • Notifications


    Receive Status Notifications to Slack and Discord

  • API and CLI


    API written in fastAPI and command line interface written in Typer.

Planned Features
  • cron gitpull (ascheduler)
  • cron docker image pull update (by docker label)
  • optional github app for repo authentication
  • health checks
  • metrics (prometheus)
  • snapshots/rollback (auto snapshots, cli rollback) service definitions
  • maintenance mode (turn off backend)
  • switch backends (blue/green and canary weighted)

How it Works

graph LR
  Webhook/CI & CLI --> API -->|Project Deployment| p[Git Pull] --> d[Docker Deploy] --> n[Notify] 
  API -->|Page Upload| f[Extract Payload] --> c[Config Update] --> n
  • create a project pointing to a git repository, authenticate by ssh key or PAT
  • a project can have several deployment environments pointing to different branches
  • deployments are triggered by cli/API or Webhook/CI
  • environment variables are available on runtime and can be referenced within compose.yml
  • environment determines additional files for merging, ie production corresponds to compose.production.yml:

deployment setup examples

  • deploy environment dev from project source repo branch develop immediately on webhook call
  • deploy environment staging from project source repo when latest docker image tag has been updated or webhook
  • deploy environment production on changes in infrastructure repo with fixed versions
  • deploy static content by pushing directly to API simply by curl
Project Database Relationship
graph LR
    p[Project]
    p --> g[Git-Key]
    p -->|branch| e[Environment] --> v[Variables] --> Key & Value
Repository Example Structure
compose.yml
compose.dev.yml
compose.staging.yml
compose.production.yml

deployment merges files matching the environment name, ie:

docker compose -f compose.yaml -f compose.production.yaml ..
$DATA_DIR/ structure
data
├── repositories
   └── my-project
       ├── environment-branch
       ├── default-dev
       ├── staging-main
       └── production-v1.2.3
└── pages
    └── example.dev

Introduction

Project Setup

Git-Key

Git-Keys are used to authenticate against the remote and can be reused for several projects.

$ ccd git-key create ssh-repo-key --type ssh > repo-key.pub
Optional: Import SSH Git-Key to Github as Deploy-Key
$ gh repo deploy-key add repo-key.pub
$ ccd git-key create imported-ssh-key --type ssh --import private-ssh.key
$ ccd git-key create repo-pat-key --type pat --key ghp_foobar
TODO: Github App Setup and CD Configuration Instructions

Project

# Create Project
$ ccd project create my-project \
  --remote git://git@github.com/user/repo.git \
  --key my-repo-key
use the current directory's name git remote as params
$ ccd project create . --remote . --key repo-ssh-key

Environment

$ ccd env my-project create default --branch main

Environment Variables

$ ccd env my-project set default FOO bar-baz
$ ccd env my-project import default .env 
importing .env to environment default for test
set IMPORTED_STRING: Value123! .. [OK]
set IMPORTED_BOOL: True .. [OK]

Deployment

Deploy with cli
$  ccd env my-project deploy default 
Deploy by Webhook
  • GET /deploy/project/${TOKEN} (fallback to default environment)
  • GET /deploy/project/${TOKEN}/${ENV}
# Create Webhook Token
$ ccd project refresh-token my-project
Deploy Token for my-project
rpO58I7odyQGsL0pzXPh1tIKyyMeKgD5CSC4WH63cTGgIV9plF6t6pC4x80DTc9Q

$ curl $HOST/deploy/project/rpO58I7odyQGsL0pz..

Page Setup

Create Page

$ ccd page create example.com
Creating page example.com

Deployment

Upload with cli
$ ccd page deploy example.com payload.tar
Deploying page example.com
Successfully Uploaded
Deployed  https://example.com/
Upload with Token
  • POST /deploy/page/${TOKEN}
$ ccd page refresh-token foobar.com
Deploy Token for example.com
BR6N23AZAPoLzpXm1CRP4CjjKwTtgBsaVhIc3jvkTUFjecAhumRXm3eDCBFK9IFX
$ curl -X POST -T payload.tar $HOST/deploy/page/BR6N23AZAPoLzpX..

Notification Setup

$ ccd config set DISCORD_WEBHOOK ..