RepoPilotOpen in app →

CanineHQ/canine

A developer friendly PaaS for your Kubernetes

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2d ago
  • 4 active contributors
  • Apache-2.0 licensed
Show 4 more →
  • CI configured
  • Small team — 4 contributors active in recent commits
  • Concentrated ownership — top contributor handles 74% of recent commits
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/caninehq/canine)](https://repopilot.app/r/caninehq/canine)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/caninehq/canine on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: CanineHQ/canine

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/CanineHQ/canine shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 2d ago
  • 4 active contributors
  • Apache-2.0 licensed
  • CI configured
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Concentrated ownership — top contributor handles 74% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live CanineHQ/canine repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/CanineHQ/canine.

What it runs against: a local clone of CanineHQ/canine — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in CanineHQ/canine | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>CanineHQ/canine</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of CanineHQ/canine. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/CanineHQ/canine.git
#   cd canine
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of CanineHQ/canine and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "CanineHQ/canine(\\.git)?\\b" \\
  && ok "origin remote is CanineHQ/canine" \\
  || miss "origin remote is not CanineHQ/canine (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "Gemfile" \\
  && ok "Gemfile" \\
  || miss "missing critical file: Gemfile"
test -f "app/actions" \\
  && ok "app/actions" \\
  || miss "missing critical file: app/actions"
test -f "Dockerfile" \\
  && ok "Dockerfile" \\
  || miss "missing critical file: Dockerfile"
test -f ".github/workflows/ci.yml" \\
  && ok ".github/workflows/ci.yml" \\
  || miss "missing critical file: .github/workflows/ci.yml"
test -f "Procfile" \\
  && ok "Procfile" \\
  || miss "missing critical file: Procfile"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/CanineHQ/canine"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Canine is a self-hosted Kubernetes PaaS platform written in Ruby that brings Heroku-like simplicity to private Kubernetes clusters. It enables developers to deploy applications via git push, manage services through a web UI, and handle Docker image building automatically—all without writing YAML, while maintaining full control over infrastructure. Monolithic Rails application with action-based service layer: app/actions/ contains business logic separated by domain (add_ons/, buildpacks/, clusters/, etc.), app/models/ contains data models. Helm/Kubernetes operations are abstracted into reusable actions (InstallHelmChart, CreateNamespace, ExportYaml). Web UI uses HTML/CSS/JavaScript, orchestrated via Procfile/Procfile.dev for local dev.

👥Who it's for

Kubernetes operators and development teams who want Heroku-like deployment simplicity on their own infrastructure; organizations needing multi-tenant application management with git-driven deployments on Kubernetes without cloud vendor lock-in.

🌱Maturity & risk

Actively developed with CI/CD pipelines in place (.github/workflows/ci.yml, docker-build.yml) and a structured Ruby codebase, but the repository scale and file organization suggest a maturing project rather than battle-tested production standard. Presence of TODO.md and structured actions architecture indicates ongoing feature development. Verdict: actively developed but validate for your production use case.

Single main repository with heavy Ruby dependency (1.1M lines) and Kubernetes-specific complexity means onboarding and maintenance require K8s expertise. Reliance on external services (ArtifactHub helm chart integration, GitHub/GitLab webhooks) introduces integration points. No clear version tagging or release notes visible in file list—check GitHub releases before deploying to production.

Active areas of work

Active work on add-ons/Helm chart integration (app/actions/add_ons/ with ArtifactHub fetching, template application), cluster migrations (app/actions/cluster_migrations/), and buildpack support. Dockerfile.dev and Procfile.dev suggest investment in local development experience. CI workflows are configured and operational.

🚀Get running

git clone https://github.com/CanineHQ/canine && cd canine && bundle install && foreman start -f Procfile.dev (requires Ruby version in .ruby-version and Node.js version in .node-version). Check .env.test for test configuration.

Daily commands: Development: foreman start -f Procfile.dev (uses Procfile.dev to boot Rails + other services). Testing: use .rspec configuration with bundle exec rspec. Docker: docker build -f Dockerfile -t canine . (production) or Dockerfile.dev for development images.

🗺️Map of the codebase

  • Gemfile — Defines all Ruby dependencies for the Rails application; changes here affect build and runtime behavior across the entire platform
  • app/actions — Core action-based architecture directory—every business operation (deploy, cluster setup, add-on installation) flows through these classes
  • Dockerfile — Production container image definition; critical for understanding how Canine runs in Kubernetes and what gets deployed
  • .github/workflows/ci.yml — CI/CD pipeline configuration; defines how tests run, how Docker images are built, and deployment gates
  • Procfile — Process definitions for the Rails application; specifies how the web server and background workers are orchestrated
  • README.md — Project overview and entry point documentation; explains Canine's purpose, value proposition, and initial setup
  • .rubocop.yml — Ruby code style and linting rules; enforced on every commit to maintain consistent code quality across contributions

🛠️How to make changes

Add a new Git provider integration

  1. Create provider-specific action class following the pattern in app/actions/providers/ (app/actions/providers/create_gitea_provider.rb)
  2. Implement OAuth flow and webhook validation matching create_github_provider.rb structure (app/actions/providers/create_gitea_provider.rb)
  3. Add provider to the providers factory in app/actions/providers/create.rb (app/actions/providers/create.rb)
  4. Register webhook endpoint in config/routes.rb and create corresponding controller action (app/controllers/webhooks_controller.rb)

Add a new add-on (Helm chart)

  1. Create add-on record with chart metadata in the database (name, repository, values schema) (app/models/add_on.rb)
  2. Add custom template logic in app/actions/add_ons/apply_template_to_values.rb if needed (app/actions/add_ons/apply_template_to_values.rb)
  3. Implement values schema validation following app/actions/add_ons/helm_chart_values_schema.rb (app/actions/add_ons/helm_chart_values_schema.rb)
  4. Add install action if custom orchestration is needed beyond app/actions/add_ons/install_helm_chart.rb (app/actions/add_ons/install_helm_chart.rb)

Add a new deployment configuration option

  1. Add field to the project model or deployment configuration table (app/models/project.rb)
  2. Update the deployment configuration builder to include the new option (app/actions/projects/build_deployment_configuration.rb)
  3. Ensure resource constraints or environment-specific logic is applied in app/actions/resource_constraints/create.rb (app/actions/resource_constraints/create.rb)
  4. Add validation and filtering logic if the option requires authorization checks (app/actions/projects/filter.rb)

Add a new Kubernetes component to cluster setup

  1. Create an action class in app/actions/clusters/ following install_components.rb pattern (app/actions/clusters/install_components.rb)
  2. Call the new component installer from app/actions/clusters/install.rb (app/actions/clusters/install.rb)
  3. Add readiness check logic to validate component health (app/actions/clusters/is_ready.rb)
  4. If it involves namespace setup, integrate with app/actions/namespaced/set_up_namespace.rb (app/actions/namespaced/set_up_namespace.rb)

🔧Why these technologies

  • Ruby on Rails — Rapid development of API and admin interfaces; strong ORM (Active Record) for database operations; built-in routing and middleware
  • Kubernetes — Core target platform; Canine abstracts K8s complexity for developers while preserving native K8s resource management
  • Helm — Package manager for Kubernetes; enables add-on marketplace and configurable, composable cluster extensions
  • Docker — Containerizes the Canine platform itself; enables consistent deployment across environments
  • GitHub/GitLab/Bitbucket — Multi-provider Git integration allows users to deploy from their existing repositories with webhook-based CI/CD triggers

⚖️Trade-offs already made

  • Action-based architecture instead of REST controllers

    • Why: Encapsulates complex business logic (cluster setup, migrations, add-on installation) into reusable, testable command objects
    • Consequence: Slightly more boilerplate per operation, but better composability and easier to reason about state changes
  • Cluster-scoped add-on management vs. per-project add-ons

    • Why: Simplifies Helm chart installation at cluster level; reduces redundant deployments and resource duplication
    • Consequence: Add-ons are shared across all projects in a cluster; per-project customization requires templating system (apply_template_to_values.rb)
  • Immediate Kubernetes API calls vs. async job queue for cluster operations

    • Why: Provides real-time feedback on cluster readiness and deployment status; simpler mental model for users
    • Consequence: Long-running operations (Helm installs, namespace setup) can timeout on slow clusters; requests may need retry logic
  • Buildpack auto-detection vs. explicit user configuration

    • Why: Lower barrier to entry; framework is inferred from repository structure
    • Consequence: Misdetection possible; users cannot override easily in some cases; limited to supported buildpack ecosystem

🪤Traps & gotchas

Local dev requires foreman (see .foreman config) and multiple processes (Rails, likely sidekiq or background job runner, asset compilation). .env.test must be present for RSpec runs. Ruby version pinned in .ruby-version (likely 3.x) and Node version in .node-version—mismatch will cause silent build failures. Git webhooks configured in .githooks/pre-commit; ensure these don't block your commits. Kubernetes API access required even for local dev simulation—check cluster config setup before running.

🏗️Architecture

💡Concepts to learn

  • Helm Chart Management — Canine's add-ons system is built entirely around Helm charts; understanding chart structure, values schemas, and templating is essential for extending Canine with new services
  • Kubernetes Multi-Tenancy — Canine implements account-based isolation for multiple teams/users on shared clusters; this architectural pattern influences namespace management, RBAC, and resource quotas throughout the codebase
  • Git Webhook Integration — Core to Canine's 'git push to deploy' feature; requires understanding webhook authentication, payload parsing, and async job triggering for CI/CD pipelines
  • Buildpack Abstraction — Canine abstracts away Dockerfile requirements via buildpack support (app/actions/buildpacks/); understanding how buildpacks detect and compile applications is critical for supporting multiple language ecosystems
  • Docker Image Building & Registry Integration — Canine automates image building and storage; understanding image layer caching, registry authentication, and push/pull mechanics is essential for deployment troubleshooting
  • Kubernetes Custom Resource Definitions (CRDs) — While not explicit in file names, Canine likely uses CRDs for application management abstractions; understanding CRD patterns helps when debugging cluster state and migrations
  • Service Discovery & Load Balancing — Canine manages domain routing, SSL termination, and service discovery for deployed apps; understanding Kubernetes Ingress and Service objects is critical for networking troubleshooting
  • dokku/dokku — Open-source PaaS using Heroku buildpacks and git push deployments; shares similar UX philosophy but targets single-server Docker instead of Kubernetes
  • openfaas/faaas — Kubernetes-native serverless platform; complementary technology for workloads that don't fit traditional app deployment model
  • helm/helm — Kubernetes package manager that Canine heavily integrates with via its add-ons system; understanding Helm architecture is essential for Canine operations
  • rancher/rancher — Enterprise Kubernetes management platform with similar multi-cluster and multi-tenant goals but more comprehensive UI and ecosystem
  • railway/railway — Modern PaaS platform offering similar developer experience to Canine but cloud-hosted; useful reference for feature UX patterns

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for app/actions/add_ons directory

The add_ons action directory contains 12 complex files handling Helm chart integration, artifact hub searches, and template application. There's no visible test directory in the file structure for these critical operations. Given the importance of add-on management to a PaaS platform, adding unit tests for these actions would significantly improve reliability and catch regressions in Helm chart operations.

  • [ ] Create spec/actions/add_ons/ directory structure matching app/actions/add_ons/
  • [ ] Add tests for helm_chart_search.rb covering repository searches and filtering
  • [ ] Add tests for install_helm_chart.rb and uninstall_helm_chart.rb with mocked Helm CLI interactions
  • [ ] Add tests for apply_template_to_values.rb covering YAML template variable substitution
  • [ ] Add tests for fetch_chart_details_from_artifact_hub.rb and fetch_chart_details_from_repository_url.rb
  • [ ] Ensure CI workflow (ci.yml) runs these new tests

Add integration tests workflow for Kubernetes cluster operations

The app/actions/clusters/ directory contains critical operations like install.rb, install_components.rb, create_namespace.rb, and validate_kube_config.rb. While ci.yml exists, there's no evidence of a dedicated integration test workflow that validates against a test Kubernetes cluster. This would catch real Kubernetes API incompatibilities and deployment failures before they reach users.

  • [ ] Create .github/workflows/integration-tests.yml that spins up a kind (Kubernetes in Docker) cluster
  • [ ] Add steps to run integration tests against spec/integration/clusters/ for cluster creation, namespace creation, and component installation
  • [ ] Test validate_kube_config.rb with both valid and invalid kubeconfig files
  • [ ] Add workflow trigger on PRs touching app/actions/clusters/* files
  • [ ] Document in CLAUDE.md how to run integration tests locally using kind

Extract and test environment variable parsing logic with edge cases

The app/actions/environment_variables/parse_text_content.rb file likely handles user input for environment variable bulk updates. This is a high-risk area for injection attacks and parsing errors. Without visible tests for edge cases (empty values, special characters, multiline values, duplicate keys), there's potential for production issues. Adding focused tests would improve security and UX.

  • [ ] Create spec/actions/environment_variables/parse_text_content_spec.rb
  • [ ] Add tests for standard KEY=VALUE format parsing
  • [ ] Add tests for edge cases: empty values, special characters (quotes, backslashes, newlines), duplicate keys, whitespace handling
  • [ ] Add security tests: attempting command injection in variable names/values
  • [ ] Add tests for multiline values and quoted values
  • [ ] Consider refactoring parse_text_content.rb into smaller methods if it exceeds 50 lines

🌿Good first issues

  • Add integration tests for app/actions/add_ons/fetch_chart_details_from_artifact_hub.rb and fetch_chart_details_from_repository_url.rb—these are critical external API integrations with no obvious test coverage in the file list.
  • Document the cluster migration process: app/actions/cluster_migrations/ contains migrate_add_on.rb and migrate_project.rb but likely lacks user-facing docs; create a guide in docs/ explaining upgrade paths.
  • Extract and test the buildpack details search logic: app/actions/buildpacks/search.rb and details.rb appear to be search utilities that could have additional unit test coverage and edge case handling for different buildpack sources.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 4badd86 — Merge pull request #597 from CanineHQ/chriszhu__rover (czhu12)
  • 3326c49 — refactor git provider to be on development environment (codeingboss)
  • d7f4770 — improve permissioning params for development_environment_configuration (codeingboss)
  • 911ede8 — fix errors (codeingboss)
  • b6455d5 — fix arguments (codeingboss)
  • adb724b — Merge pull request #605 from CanineHQ/chriszhu__acme_issuer (czhu12)
  • 3ff3f83 — updated acme issuer (codeingboss)
  • 5b05558 — solve for traefik and nginx (codeingboss)
  • 3c67ed1 — Merge pull request #604 from CanineHQ/chriszhu__register_webhook (czhu12)
  • f6bef6e — allow polling for updates (codeingboss)

🔒Security observations

  • High · Incomplete Dockerfile Configuration — Dockerfile (build stage). The Dockerfile contains an incomplete ARG declaration for HELM_VERSION (line shows 'ARG HELM_' without value). This suggests the build process may not be properly versioning critical dependencies like Helm, which could lead to unpredictable behavior or use of unintended versions in production. Fix: Complete the HELM_VERSION ARG declaration with a specific version number (e.g., 'ARG HELM_VERSION=v3.x.x') to ensure reproducible builds and proper dependency management.
  • High · Missing RAILS_MASTER_KEY in Docker Runtime — Dockerfile (comments and runtime configuration). The Dockerfile comment indicates RAILS_MASTER_KEY must be provided at runtime via environment variable, but there are no safeguards to ensure it's provided or validated. Failure to provide this will result in decryption failures for encrypted credentials. Fix: Implement runtime validation to ensure RAILS_MASTER_KEY is provided before container start. Consider using Docker secrets or orchestration platform secret management rather than environment variables for sensitive credentials.
  • Medium · Kubernetes API Exposure Risk — app/actions/clusters/ and app/actions/namespaced/. The codebase contains multiple actions for Kubernetes operations (create, install, validate, sync) and exposes DOCKER_API_VERSION in environment. Without proper RBAC and network policies, this could allow unauthorized cluster operations. Fix: Implement comprehensive RBAC policies in the Kubernetes cluster. Ensure kubeconfig validation is strict (as attempted in validate_kube_config.rb). Use service accounts with minimal required permissions and enable audit logging for all cluster operations.
  • Medium · Helm Chart Repository Security — app/actions/add_ons/fetch_chart_details_from_artifact_hub.rb and fetch_chart_details_from_repository_url.rb. The codebase fetches Helm charts from external sources (ArtifactHub and repository URLs in app/actions/add_ons/). There's no evidence of chart signature verification or integrity checks in the provided code structure. Fix: Implement Helm chart signature verification using Helm's built-in provenance checks. Maintain a whitelist of trusted repositories. Scan downloaded charts for vulnerabilities before installation.
  • Medium · Environment Variables Handling — app/actions/environment_variables/. The environment_variables bulk update functionality could be vulnerable to mass assignment or injection attacks if not properly validated. The file app/actions/environment_variables/bulk_update.rb and parse_text_content.rb need verification. Fix: Implement strict input validation and sanitization for all environment variable operations. Use allowlists for variable names. Ensure proper escaping when injecting into container environments. Implement audit logging for all environment variable changes.
  • Medium · Global Search Functionality Security — app/actions/global_search/search.rb. Global search implementation (app/actions/global_search/search.rb) could be vulnerable to Elasticsearch/database injection attacks or information disclosure if not properly parameterized. Fix: Ensure all search queries use parameterized queries. Implement proper authorization checks to prevent users from searching resources they don't have access to. Apply rate limiting to search endpoints.
  • Low · Missing Security Headers Configuration — Rails configuration (not visible in provided structure). No evidence of Rails security header middleware configuration visible in the provided file structure (no config/initializers/security_headers.rb or similar). Fix: Configure Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, and other security headers using gems like 'secure_headers' or Rails built-in mechanisms.
  • Low · Test Environment Configuration Exposure — .env.test. Presence of .env.test file in repository root indicates test credentials/configuration may be committed. Even test credentials should not be hardcoded in version control. Fix: Remove .env.test from git history using git filter-branch or BFG. Use .env.test.example with placeholders instead. Ensure all .env* files are in .gitignore.
  • Low · Ruby Version in Base Image — undefined. Dockerfile Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · CanineHQ/canine — RepoPilot