{"id":17132204,"url":"https://github.com/bitsofinfo/appdeploy","last_synced_at":"2026-01-28T06:41:54.721Z","repository":{"id":36248955,"uuid":"191184002","full_name":"bitsofinfo/appdeploy","owner":"bitsofinfo","description":"Opinionated Helm chart for deploying applications to Kubernetes","archived":false,"fork":false,"pushed_at":"2023-02-23T17:06:31.000Z","size":4446,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-12T09:24:21.360Z","etag":null,"topics":["automation","ci-cd","continuous-integration","deployment","devops","helm","helm-charts","k8s","kubernetes"],"latest_commit_sha":null,"homepage":"https://bitsofinfo.wordpress.com/2019/07/12/appdeploy-helm-chart-for-consistency/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitsofinfo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-10T14:29:50.000Z","updated_at":"2022-11-03T03:10:38.000Z","dependencies_parsed_at":"2024-12-19T10:28:20.232Z","dependency_job_id":"a7731f75-0a17-49c2-b921-3a9d4146c666","html_url":"https://github.com/bitsofinfo/appdeploy","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fappdeploy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fappdeploy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fappdeploy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsofinfo%2Fappdeploy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitsofinfo","download_url":"https://codeload.github.com/bitsofinfo/appdeploy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427012,"owners_count":20937214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","ci-cd","continuous-integration","deployment","devops","helm","helm-charts","k8s","kubernetes"],"created_at":"2024-10-14T19:26:22.064Z","updated_at":"2026-01-28T06:41:54.696Z","avatar_url":"https://github.com/bitsofinfo.png","language":null,"readme":"# appdeploy\n\nThis is a fairly generic Helm chart that can deploy any Docker image to Kubernetes in an opinionated fashion.\n\nThe chart deploys a single app in an opinionated way that adheres to the conventions described below. Whereby an \"app\" is defined\nas a single Docker `image:tag/version` to be deployed to a Kubernetes cluster where the app container resides in a `Pod` by itself as part of a `Deployment` and *optionally* may require a single `bootstrapSecret` to bootstrap itself. The `Pods` are accessible via a `Service` as well as a dedicated `Ingress` bound to an auto-generated \"version specific\" hostname that is unique to the app's `image:tag`. The chart also optionally supports creating one or more Helm Hook `Jobs`.\n\n* [Conventions](#convention)\n* [What it does](#does)\n* [What its not intended for](#doesnot)\n* [Alerts](#alerts)\n* [Options](#options)\n* [tpl-variables](#metavar)\n* [Diagram](#diag)\n* [Examples](examples/)\n* [Custom Helm Hooks](#hooks)\n* [Using as a dependency](#dependency)\n* [Packaging/Using](#pack)\n* [Related projects](#related)\n\n# \u003ca id=\"convention\"\u003e\u003c/a\u003eConventions\n\nIn addition to whatever target k8s `namespace` the chart deploys into, all apps (single Docker `image:tag` artifacts) are labeled and categorized as follows with the following logical values. These values (*and any other chart value*) are made available to you to cross reference in other `values` via Helm's `tpl` evaluation function for your `Deployment`. *(see `tpl variable substitution` below)*\n\n### appname\nThe logical *name* for the application being deployed.\n\n### version\nThe the version of the app, i.e. its `image.tag`\n\n### environment\nAs one would expect, an *environment* is something like `dev`, `qa`, `prod` or `stage`.\n\n### context\nWithin an *environment*, one or more *contexts* can exist as a way to logically sub-divide applications within an *environment*. The loose rule is that all applications sharing the same *context* talk to one another or similar configuration sources/databases etc. *Contexts* permit a level of classification that applications can use to alter how they bootup, configs they load etc. within an *environment*. The name of a *context* generally includes the *environment* implicit in its name (i.e. `qa-silo1`)\n\n### classifier\nSometimes an application artifact may operate in different *modes*, these different modes may enable or disable certain aspects of standard functionality provided by the artifact; such as the availability or lack thereof certain exposed APIs or ports. In these cases the *classifier* can simply act as a naming decoration to help identify this.\n\n---\n\nAgain all of the above is simple a convention of this chart but does not physically *impose anything* on the artifacts you choose to deploy with this chart. These attributes (and anything else in `values.yaml`) are however made available to you as as variables in the chart itself that you can leverage to route into a Pod's `spec.template` commands, args and env variables; which can then subsequently be consumed to drive an app to make decisions on how to bootstrap itself, what configs to load etc. *(see `tpl variable substitution` below)*\n\nIn short, the above concepts may or may not work for you, but have proved to be a useful set of conventions used in the real world and has worked pretty well.\n\n## Important!\n\nIn an of itself, this chart deploy's nothing as its default [values.yaml](values.yaml) is sparse on\nactual configuration that would actually instantiate anything. For example its `image.repository`, `image.tag`, `env` and `command` are empty and up to you to provide the values for those items.\n\n## \u003ca id=\"does\"\u003e\u003c/a\u003eWhat it does\n\nThis chart produces the following \"version specific\" Kubernetes YAML objects that adhere to a general convention described above.\n\n*\"Version specific\"*, meaning all artifacts produced with this chart will be appropriately named according with the following convention: `[appname]-[context]-[image.tag][-[classifier]]` naming conventions.\n\nDepending on your `values` customizations, this Chart can produce the following version specific artifacts:\n\n* **RBAC**: an optional RBAC `ServiceAccount`, `[Cluster]Role`, `[Cluster]RoleBinding`\n* **Secret**: for the app's `bootstrapSecret`\n* **Deployment**: for the app's `Pod` specification, optionally mounting the `bootstrapSecret` and presenting as the K8s generated `ServiceAccount` above within the cluster.\n* **Service**: to access all the app's `containerPorts`\n* **Ingress**: one or more, depending on the apps `containerPorts` configuration with hostname naming convention `[appname]-[context]-[image.tag][-[classifier]][-[port]]` at the configured `ingress.dns.fqdnSuffix`\n* **Helm Hooks**: Post deploy/delete health checks (`Jobs`) and alerts to Slack as well as additional/optional arbitrary `Jobs` for doing things like migrations etc (i.e `hooks.custom.[hookname]` in `values.yaml`)\n* **Horizontal pod autoscaler**: OPTIONAL, scale number of replicas in a deployment based on CPU or memory usage metrics\n* **Pod Disruption Budget**: OPTIONAL, configure tolerance for unavailable replicas during planned upgrades/outages\n\n## \u003ca id=\"doesnot\"\u003e\u003c/a\u003eWhat its not intended for\n\nThis chart is NOT intended to wire your app up to one or more custom \"live user facing\" hostnames (i.e. www.myProdUserFacingWebsite.com) or do canary releases etc; if you are interested in that you should look at the [appconduits Helm chart](https://github.com/bitsofinfo/appconduits). The primary intent of the `appdeploy` chart is simple to deploy a new version of an app; validate it, notify the team, and provide a **version specific** `Ingress` `host` binding to access it via an Ingress Controller. If you want to route traffic to your app via other `hosts:` or sophisticated routing rules, you should be creating separate/custom `Service` and `Ingress` combinations; again see [appconduits](https://github.com/bitsofinfo/appconduits).\n\n---\n\nWhen using all available options, each invocation of `appdeploy` can produce a single point of management Helm `release` that is comprised all of the components described above. No matter how many different applications your team manages, if you follow some simple conventions as well externalizing the bulk of application specific configuration, secured via a unique (and limited life) `bootstrapSecret`; you can really begin to see the economies of scale for a unified DevOps deployment approach no matter what the artifact.\n\n\u003ca id=\"diag\"\u003e\u003c/a\u003e![Diagram of appdeploy](/docs/diag.png \"Diagram1\")\n\n\n## \u003ca id=\"alerts\"\u003e\u003c/a\u003ePost install/upgrade/delete checks and alerts\n\nThe checking and alerting engine leverages: https://github.com/bitsofinfo/kubernetes-helm-healthcheck-hook\n\n## \u003ca id=\"options\"\u003e\u003c/a\u003eConfigurable options\n\nAll configurable options are documented in [values.yaml](values.yaml)\n\nSee the [helm docs for setting values](https://github.com/helm/helm/blob/master/docs/chart_best_practices/values.md)\non how to customize/change these values when doing a `helm ...` invocation.\n\n## \u003ca id=\"metavar\"\u003e\u003c/a\u003etpl variable substitution\n\nCertain chart `values` can themselves be mini `templates` i.e. (`chartValue: \"{{ .Values.someOtherValueRef }}`) (parsed via [Helm's tpl function](https://github.com/helm/helm/blob/master/docs/charts_tips_and_tricks.md) function). This can be useful when specifying `env` vars or `command.args` values and most labels etc. See [values.yaml](values.yaml) for full details on what values are parsed by `tpl`.\n\nCurrently the following are parsed:\n\n* Any `.Values.env.[name].value`\n* Any `.Values.command.args`\n* Any `service.labels.[name].value`\n* The `extraService.name`\n* Any `extraService.labels.[name|value]`\n* Any `extraService.selectors.[name|value]`\n* Any `extraService.annotations.[name|value]`\n* Any `image.[repository|tag]`\n* Any `pod.labels.[name].value`\n* The `pod.hostname`\n* The `pod.subdomain`\n* Any `ingress.metadata.labels.[name].value`\n* Any `ingress.metadata.annotations.[name].value`\n* Any `hooks.custom.[hookname].pod.labels.[name].value`\n* Any `hooks.custom.[hookname].env.[name].value`\n* Any `hooks.custom.[hookname].command.args`\n\nYou can reference any valid path relative from `.` (i.e. `$`). Some custom generated\nvariables that are composed and not literally in `values.yaml`:\n* `.fullAppIdentifier_full` = `[app.shortName]-[app.context]-[image.tag][-[app.classifier]]`\n* `.fullAppIdentifier_short` = a shorter version of `.fullAppIdentifier_full` if \u003e 63 chars\n* `.fullAppIdentifier_hash` = hash of `.fullAppIdentifier_full`\n* `.fullAppIdentifier` = one of the latter values, whichever is \u003c 63 chars in decending order\n* `.bootstrapSecretFilePath` = `.Values.bootstrapSecret.mount.path/.Values.bootstrapSecret.mount.fileName`\n* `.serviceAccountName` = `.Values.serviceAccount.name` (which is a `tpl` parsed value)\n\nBasic example of what you can declare in your `values`:\n```\n...\nenv:\n  MY_VAR_NAME:\n    value: \"{{ .Values.app.name | replace 'dog' 'cat' }}\"\n```\n\n## Examples\n\nFor examples see the [examples/ folder](examples/)\n\n## \u003ca id=\"hooks\"\u003e\u003c/a\u003eCustom Helm Hooks\n\nThe chart also permits declaring a variable number of custom [Helm Hooks](https://github.com/helm/helm/blob/master/docs/charts_hooks.md) within your `values` by declaring them under `hooks.custom.[yourhookname]`. This functionality\nis intended to be used for doing custom things w/ your deployment such as running migrations. All created\nobjects are labeled and named like any of the other objects created by this chart.\n\nFor further information see `hooks` in [values.yaml](values.yaml)\n\nThere is also a working example in the [examples/ folder](examples/)\n\n## \u003ca id=\"dependency\"\u003e\u003c/a\u003eAs a dependency in another chart\n\nBuild it: `helm package appdeploy`\n\nThen copy the resulting `tgz` into your dependant chart's `charts/` folder\n\nFrom there you can customize your chart's `values.yaml` to further refine the\ndefaults provided by `appdeploy/values.yaml`\n\nFor example, lets say you create a deriviative chart based on `appdeploy`.\nYour derivative chart's `values.yaml` could further provide defaults on top\nof `appdeploy` as follows:\n\n**my-custom-chart/values.yaml**\n```\nmy-own-chart-property1: \"some value\"\n\n# Specify value customizations for the 'appdeploy' dependency\n# To override the values of \"sub-charts\" you have to scope them\n# as follows:\n# https://github.com/helm/helm/blob/master/docs/chart_template_guide/subcharts_and_globals.md\n\nappdeploy:\n  replicaCount: 20\n\n  containerPorts:\n    - port: \"3333\"\n      name: \"my-https\"\n      ingress: true\n      service: true\n      tls: true\n\n  healthcheck:\n    liveness:\n      containerPort: 3333\n    readiness:\n      containerPort: 3333\n```\n\n## \u003ca id=\"pack\"\u003e\u003c/a\u003eHelm package/update\n\n```\nhelm package . -d repo/charts/\nhelm repo index repo/\n```\n\n## Using!\n\n```\nhelm repo add bitsofinfo-appdeploy https://raw.githubusercontent.com/bitsofinfo/appdeploy/master/repo\nhelm repo update\n```\n\n```\n# requirements.yaml\ndependencies:\n- name: appdeploy\n  version: \"\u003cTAG_VERSION\u003e\"\n  repository: \"https://raw.githubusercontent.com/bitsofinfo/appdeploy/master/repo\"\n```\n\n# \u003ca id=\"related\"\u003e\u003c/a\u003eRelated Projects\n\n* [appconduits](https://github.com/bitsofinfo/appconduits)\n* [helmfile-deploy](https://github.com/bitsofinfo/helmfile-deploy)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsofinfo%2Fappdeploy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitsofinfo%2Fappdeploy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsofinfo%2Fappdeploy/lists"}