├── .circleci
└── config.yml
├── LICENSE
├── README.md
├── charts
└── ghost
│ ├── .helmignore
│ ├── Chart.yaml
│ ├── OWNERS
│ ├── README.md
│ ├── requirements.lock
│ ├── requirements.yaml
│ ├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── ingress.yaml
│ ├── pvc.yaml
│ ├── secrets.yaml
│ └── svc.yaml
│ ├── values.schema.json
│ └── values.yaml
├── namespaces
└── demo.yaml
├── releases
├── ghost.yaml
├── mongodb.yaml
├── redis-auth.yaml
└── redis.yaml
└── workloads
├── podinfo-dep.yaml
├── podinfo-hpa.yaml
└── podinfo-svc.yaml
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 | jobs:
3 | validate-yamls:
4 | docker:
5 | - image: stefanprodan/hrval:v2.9.0
6 | steps:
7 | - checkout
8 | - run:
9 | name: Validate workloads
10 | environment:
11 | KUBE_VER: "1.16.0"
12 | command: |
13 | kubeval --strict --ignore-missing-schemas --kubernetes-version ${KUBE_VER} -d namespaces,workloads,releases
14 | - run:
15 | name: Validate releases
16 | environment:
17 | IGNORE_VALUES: "false"
18 | KUBE_VER: "1.16.0"
19 | HELM_VER: "v2"
20 | command: |
21 | hrval releases/ $IGNORE_VALUES $KUBE_VER $HELM_VER
22 |
23 | workflows:
24 | version: 2
25 | validate:
26 | jobs:
27 | - validate-yamls:
28 | filters:
29 | branches:
30 | ignore:
31 | - gh-pages
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flux-get-started
2 |
3 | ## We are moving to Flux v2
4 |
5 | > ⚠️ Please note: In preparation of [Flux v2](https://toolkit.fluxcd.io/) GA this repository with Flux v1 examples has been archived. The Flux v2 equivalent of what is shown here can be found at [flux2-kustomize-helm-example](https://github.com/fluxcd/flux2-kustomize-helm-example).
6 | >
7 | > Thanks a lot for your interest.
8 |
9 | ## For posterity
10 |
11 | We published a step-by-step run-through on how to use Flux and Helm Operator [over
12 | here](https://github.com/fluxcd/flux/blob/master/docs/tutorials/get-started-helm.md).
13 |
14 | ## Workloads
15 |
16 | [podinfo](https://github.com/stefanprodan/podinfo)
17 | * Kubernetes deployment, ClusterIP service and Horizontal Pod Autoscaler
18 | * init container automated image updates (regular expression filter)
19 | * container automated image updates (semantic versioning filter)
20 |
21 | ## Helm Releases
22 |
23 | Mongodb
24 | * Source: Helm repository (stable)
25 | * Kubernetes deployment
26 | * automated image updates (semantic versioning filter)
27 |
28 | Redis
29 | * Source: Helm repository (stable)
30 | * Kubernetes stateful set
31 | * locked automated image updates (semantic versioning filter)
32 |
33 | Ghost
34 | * Source: Git repository
35 | * disabled automated image updates (glob filter)
36 | * has external dependency - mariadb (stable)
37 |
38 | ## Manifests Validation
39 |
40 | CircleCI [jobs](./.circleci/config.yml):
41 | * validate Kubernetes manifests with [kubeval](https://github.com/instrumenta/kubeval)
42 | * validate Flux Helm Releases with [hrval](https://github.com/stefanprodan/hrval-action)
43 |
44 | ### Getting Help
45 |
46 | If you have any questions about, feedback for or problems with `flux-get-started`:
47 |
48 |
49 | - Invite yourself to the CNCF community
50 | slack and ask a question on the [#flux](https://cloud-native.slack.com/messages/flux/)
51 | channel.
52 | - To be part of the conversation about Flux's development, join the
53 | [flux-dev mailing list](https://lists.cncf.io/g/cncf-flux-dev).
54 | - [File an issue.](https://github.com/fluxcd/flux/issues/new)
55 |
56 | Your feedback is always welcome!
57 |
--------------------------------------------------------------------------------
/charts/ghost/.helmignore:
--------------------------------------------------------------------------------
1 | .git
2 |
--------------------------------------------------------------------------------
/charts/ghost/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | name: ghost
3 | version: 9.0.4
4 | appVersion: 3.1.1
5 | description: A simple, powerful publishing platform that allows you to share your stories with the world
6 | keywords:
7 | - ghost
8 | - blog
9 | - http
10 | - web
11 | - application
12 | - nodejs
13 | - javascript
14 | home: http://www.ghost.org/
15 | icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png
16 | sources:
17 | - https://github.com/bitnami/bitnami-docker-ghost
18 | maintainers:
19 | - name: Bitnami
20 | email: containers@bitnami.com
21 | engine: gotpl
22 |
--------------------------------------------------------------------------------
/charts/ghost/OWNERS:
--------------------------------------------------------------------------------
1 | approvers:
2 | - prydonius
3 | - tompizmor
4 | - sameersbn
5 | - carrodher
6 | - javsalgar
7 | - juan131
8 | - miguelaeh
9 | reviewers:
10 | - prydonius
11 | - tompizmor
12 | - sameersbn
13 | - carrodher
14 | - javsalgar
15 | - juan131
16 | - miguelaeh
17 |
--------------------------------------------------------------------------------
/charts/ghost/README.md:
--------------------------------------------------------------------------------
1 | # Ghost
2 |
3 | [Ghost](https://ghost.org/) is one of the most versatile open source content management systems on the market.
4 |
5 | ## TL;DR;
6 |
7 | ```console
8 | $ helm install stable/ghost
9 | ```
10 |
11 | ## Introduction
12 |
13 | This chart bootstraps a [Ghost](https://github.com/bitnami/bitnami-docker-ghost) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
14 |
15 | It also packages the [Bitnami MariaDB chart](https://github.com/kubernetes/charts/tree/master/stable/mariadb) which is required for bootstrapping a MariaDB deployment for the database requirements of the Ghost application.
16 |
17 | Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/).
18 |
19 | ## Prerequisites
20 |
21 | - Kubernetes 1.12+
22 | - Helm 2.11+ or Helm 3.0-beta3+
23 | - PV provisioner support in the underlying infrastructure
24 | - ReadWriteMany volumes for deployment scaling
25 |
26 | ## Installing the Chart
27 |
28 | To install the chart with the release name `my-release`:
29 |
30 | ```console
31 | $ helm install --name my-release stable/ghost
32 | ```
33 |
34 | The command deploys Ghost on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation.
35 |
36 | > **Tip**: List all releases using `helm list`
37 |
38 | ## Uninstalling the Chart
39 |
40 | To uninstall/delete the `my-release` deployment:
41 |
42 | ```console
43 | $ helm delete my-release
44 | ```
45 |
46 | The command removes all the Kubernetes components associated with the chart and deletes the release.
47 |
48 | ## Parameters
49 |
50 | The following table lists the configurable parameters of the Ghost chart and their default values.
51 |
52 | | Parameter | Description | Default |
53 | |-------------------------------------|---------------------------------------------------------------|----------------------------------------------------------|
54 | | `global.imageRegistry` | Global Docker image registry | `nil` |
55 | | `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) |
56 | | `global.storageClass` | Global storage class for dynamic provisioning | `nil` |
57 | | `image.registry` | Ghost image registry | `docker.io` |
58 | | `image.repository` | Ghost Image name | `bitnami/ghost` |
59 | | `image.tag` | Ghost Image tag | `{TAG_NAME}` |
60 | | `image.pullPolicy` | Image pull policy | `IfNotPresent` |
61 | | `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) |
62 | | `nameOverride` | String to partially override ghost.fullname template with a string (will prepend the release name) | `nil` |
63 | | `fullnameOverride` | String to fully override ghost.fullname template with a string | `nil` |
64 | | `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` |
65 | | `volumePermissions.image.repository`| Init container volume-permissions image name | `bitnami/minideb` |
66 | | `volumePermissions.image.tag` | Init container volume-permissions image tag | `stretch` |
67 | | `volumePermissions.image.pullPolicy`| Init container volume-permissions image pull policy | `Always` |
68 | | `ghostHost` | Ghost host to create application URLs | `nil` |
69 | | `ghostPort` | Ghost port to use in application URLs (defaults to `service.port` if `nil`) | `nil` |
70 | | `ghostProtocol` | Protocol (http or https) to use in the application URLs | `http` |
71 | | `ghostPath` | Ghost path to create application URLs | `nil` |
72 | | `ghostUsername` | User of the application | `user@example.com` |
73 | | `ghostPassword` | Application password | Randomly generated |
74 | | `ghostEmail` | Admin email | `user@example.com` |
75 | | `ghostBlogTitle` | Ghost Blog name | `User's Blog` |
76 | | `smtpHost` | SMTP host | `nil` |
77 | | `smtpPort` | SMTP port | `nil` |
78 | | `smtpUser` | SMTP user | `nil` |
79 | | `smtpPassword` | SMTP password | `nil` |
80 | | `smtpFromAddress` | SMTP from address | `nil` |
81 | | `smtpService` | SMTP service | `nil` |
82 | | `allowEmptyPassword` | Allow DB blank passwords | `yes` |
83 | | `securityContext.enabled` | Enable security context | `true` |
84 | | `securityContext.fsGroup` | Group ID for the container | `1001` |
85 | | `securityContext.runAsUser` | User ID for the container | `1001` |
86 | | `service.type` | Kubernetes Service type | `LoadBalancer` |
87 | | `service.port` | Service HTTP port | `80` |
88 | | `service.nodePorts.http` | Kubernetes http node port | `""` |
89 | | `service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` |
90 | | `service.loadBalancerIP` | LoadBalancerIP for the Ghost service | `` |
91 | | `service.annotations` | Service annotations | `` |
92 | | `ingress.enabled` | Enable ingress controller resource | `false` |
93 | | `ingress.annotations` | Ingress annotations | `[]` |
94 | | `ingress.certManager` | Add annotations for cert-manager | `false` |
95 | | `ingress.hosts[0].name` | Hostname to your Ghost installation | `ghost.local` |
96 | | `ingress.hosts[0].path` | Path within the url structure | `/` |
97 | | `ingress.hosts[0].tls` | Utilize TLS backend in ingress | `false` |
98 | | `ingress.hosts[0].tlsHosts` | Array of TLS hosts for ingress record (defaults to `ingress.hosts[0].name` if `nil`) | `nil` |
99 | | `ingress.hosts[0].tlsSecret` | TLS Secret (certificates) | `ghost.local-tls-secret` |
100 | | `ingress.secrets[0].name` | TLS Secret Name | `nil` |
101 | | `ingress.secrets[0].certificate` | TLS Secret Certificate | `nil` |
102 | | `ingress.secrets[0].key` | TLS Secret Key | `nil` |
103 | | `externalDatabase.host` | Host of the external database | `localhost` |
104 | | `externalDatabase.port` | Port of the external database | `3306` |
105 | | `externalDatabase.user` | Existing username in the external db | `bn_ghost` |
106 | | `externalDatabase.password` | Password for the above username | `""` |
107 | | `externalDatabase.database` | Name of the existing database | `bitnami_ghost` |
108 | | `mariadb.enabled` | Whether or not to install MariaDB (disable if using external) | `true` |
109 | | `mariadb.rootUser.password` | MariaDB admin password | `nil` |
110 | | `mariadb.db.name` | MariaDB Database name to create | `bitnami_ghost` |
111 | | `mariadb.db.user` | MariaDB Database user to create | `bn_ghost` |
112 | | `mariadb.db.password` | MariaDB Password for user | _random 10 character long alphanumeric string_ |
113 | | `persistence.enabled` | Enable persistence using PVC | `true` |
114 | | `persistence.storageClass` | PVC Storage Class for Ghost volume | `nil` (uses alpha storage annotation) |
115 | | `persistence.accessMode` | PVC Access Mode for Ghost volume | `ReadWriteOnce` |
116 | | `persistence.size` | PVC Storage Request for Ghost volume | `8Gi` |
117 | | `persistence.path` | Path to mount the volume at, to use other images | `/bitnami` |
118 | | `resources` | CPU/Memory resource requests/limits | Memory: `512Mi`, CPU: `300m` |
119 | | `nodeSelector` | Node selector for pod assignment | `{}` |
120 | | `affinity` | Map of node/pod affinities | `{}` |
121 |
122 | The above parameters map to the env variables defined in [bitnami/ghost](http://github.com/bitnami/bitnami-docker-ghost). For more information please refer to the [bitnami/ghost](http://github.com/bitnami/bitnami-docker-ghost) image documentation.
123 |
124 | > **Note**:
125 | >
126 | > For the Ghost application function correctly, you should specify the `ghostHost` parameter to specify the FQDN (recommended) or the public IP address of the Ghost service.
127 | >
128 | > Optionally, you can specify the `ghostLoadBalancerIP` parameter to assign a reserved IP address to the Ghost service of the chart. However please note that this feature is only available on a few cloud providers (f.e. GKE).
129 | >
130 | > To reserve a public IP address on GKE:
131 | >
132 | > ```bash
133 | > $ gcloud compute addresses create ghost-public-ip
134 | > ```
135 | >
136 | > The reserved IP address can be assigned to the Ghost service by specifying it as the value of the `ghostLoadBalancerIP` parameter while installing the chart.
137 |
138 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
139 |
140 | ```console
141 | $ helm install --name my-release \
142 | --set ghostUsername=admin,ghostPassword=password,mariadb.mariadbRootPassword=secretpassword \
143 | stable/ghost
144 | ```
145 |
146 | The above command sets the Ghost administrator account username and password to `admin` and `password` respectively. Additionally, it sets the MariaDB `root` user password to `secretpassword`.
147 |
148 | Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,
149 |
150 | ```console
151 | $ helm install --name my-release -f values.yaml stable/ghost
152 | ```
153 |
154 | > **Tip**: You can use the default [values.yaml](values.yaml)
155 |
156 | ## Configuration and installation details
157 |
158 | ### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/)
159 |
160 | It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image.
161 |
162 | Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist.
163 |
164 | ### Using an existing database
165 |
166 | Sometimes you may want to have Ghost connect to an external database rather than installing one inside your cluster, e.g. to use a managed database service, or use run a single database server for all your applications. To do this, the chart allows you to specify credentials for an external database under the [`externalDatabase` parameter](#parameters). You should also disable the MariaDB installation with the `mariadb.enabled` option. For example using the following parameters:
167 |
168 | ```console
169 | mariadb.enabled=false
170 | externalDatabase.host=myexternalhost
171 | externalDatabase.user=myuser
172 | externalDatabase.password=mypassword
173 | externalDatabase.database=mydatabase
174 | ```
175 |
176 | ## Persistence
177 |
178 | The [Bitnami Ghost](https://github.com/bitnami/bitnami-docker-ghost) image stores the Ghost data and configurations at the `/bitnami/ghost` and `/bitnami/apache` paths of the container.
179 |
180 | Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube.
181 | See the [Parameters](#parameters) section to configure the PVC or to disable persistence.
182 |
183 | ## Upgrading
184 |
185 | ### To 9.0.0
186 |
187 | Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec.
188 |
189 | In https://github.com/helm/charts/pulls/17297 the `apiVersion` of the deployment resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage.
190 |
191 | This major version signifies this change.
192 |
193 | ### To 5.0.0
194 |
195 | Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments.
196 | Use the workaround below to upgrade from versions previous to 5.0.0. The following example assumes that the release name is ghost:
197 |
198 | ```console
199 | $ kubectl patch deployment ghost-ghost --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]'
200 | $ kubectl delete statefulset ghost-mariadb --cascade=false
201 | ```
202 |
--------------------------------------------------------------------------------
/charts/ghost/requirements.lock:
--------------------------------------------------------------------------------
1 | dependencies:
2 | - name: mariadb
3 | repository: https://charts.helm.sh/stable
4 | version: 7.3.14
5 | digest: sha256:44ec62c7893a6de23b0121d2a6e4d9aae63b4dd5399367847a56b4714ffb71f4
6 | generated: "2021-01-14T21:40:03.752300326+01:00"
7 |
--------------------------------------------------------------------------------
/charts/ghost/requirements.yaml:
--------------------------------------------------------------------------------
1 | dependencies:
2 | - name: mariadb
3 | version: 7.x.x
4 | repository: https://charts.helm.sh/stable
5 | condition: mariadb.enabled
6 | tags:
7 | - ghost-database
8 |
--------------------------------------------------------------------------------
/charts/ghost/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | {{- if empty (include "ghost.host" .) -}}
2 | ###############################################################################
3 | ### ERROR: You did not provide an external host in your 'helm install' call ###
4 | ###############################################################################
5 |
6 | This deployment will be incomplete until you configure Ghost with a resolvable
7 | host. To configure Ghost with the URL of your service:
8 |
9 | 1. Get the Ghost URL by running:
10 |
11 | {{- if contains "NodePort" .Values.service.type }}
12 |
13 | export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
14 |
15 | {{- else if contains "LoadBalancer" .Values.service.type }}
16 |
17 | NOTE: It may take a few minutes for the LoadBalancer IP to be available.
18 | Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "ghost.fullname" . }}'
19 |
20 | export APP_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "ghost.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}")
21 | export APP_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "ghost.fullname" . }} -o jsonpath="{.data.ghost-password}" | base64 --decode)
22 | {{- if .Values.mariadb.mariadbRootPassword }}
23 | export DATABASE_ROOT_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "ghost.mariadb.fullname" . }} -o jsonpath="{.data.mariadb-root-password}" | base64 --decode)
24 | {{- end }}
25 | {{- end }}
26 | export APP_DATABASE_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "ghost.mariadb.fullname" . }} -o jsonpath="{.data.mariadb-password}" | base64 --decode)
27 |
28 | 2. Complete your Ghost deployment by running:
29 |
30 | helm upgrade {{ .Release.Name }} stable/{{ .Chart.Name }} \
31 | --set service.type={{ .Values.service.type }},ghostHost=$APP_HOST,ghostPassword=$APP_PASSWORD,{{ if .Values.mariadb.mariadbRootPassword }},mariadb.mariadbRootPassword=$DATABASE_ROOT_PASSWORD{{ end }}mariadb.db.password=$APP_DATABASE_PASSWORD{{- if .Values.global }}{{- if .Values.global.imagePullSecrets }},global.imagePullSecrets={{ .Values.global.imagePullSecrets }}{{- end }}{{- end }}
32 | {{- else -}}
33 | 1. Get the Ghost URL by running:
34 |
35 | {{- if eq .Values.service.type "ClusterIP" }}
36 |
37 | echo Blog URL : http://127.0.0.1:{{ default "80" .Values.service.port }}{{ .Values.ghostPath }}
38 | echo Admin URL : http://127.0.0.1:{{ default "80" .Values.service.port }}{{ .Values.ghostPath }}ghost
39 | kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "ghost.fullname" . }} {{ default "80" .Values.service.port }}:2368
40 |
41 | {{- else if eq .Values.service.type "NodePort" }}
42 | export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
43 | export APP_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "ghost.fullname" . }})
44 |
45 | echo Blog URL : http://$APP_HOST:$APP_PORT{{ .Values.ghostPath }}
46 | echo Admin URL : http://$APP_HOST:$APP_PORT{{ .Values.ghostPath }}ghost
47 |
48 | {{- else }}
49 |
50 | echo Blog URL : http://{{ include "ghost.host" . }}
51 | echo Admin URL : http://{{ include "ghost.host" . }}ghost
52 | {{- end }}
53 |
54 | 2. Get your Ghost login credentials by running:
55 |
56 | echo Email: {{ .Values.ghostEmail }}
57 | echo Password: $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "ghost.fullname" . }} -o jsonpath="{.data.ghost-password}" | base64 --decode)
58 | {{- end }}
59 |
60 | {{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }}
61 |
62 | WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment.
63 | +info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/
64 |
65 | {{- end }}
66 |
--------------------------------------------------------------------------------
/charts/ghost/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/* vim: set filetype=mustache: */}}
2 | {{/*
3 | Expand the name of the chart.
4 | */}}
5 | {{- define "ghost.name" -}}
6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7 | {{- end -}}
8 |
9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | If release name contains chart name it will be used as a full name.
13 | */}}
14 | {{- define "ghost.fullname" -}}
15 | {{- if .Values.fullnameOverride -}}
16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
17 | {{- else -}}
18 | {{- $name := default .Chart.Name .Values.nameOverride -}}
19 | {{- if contains $name .Release.Name -}}
20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}}
21 | {{- else -}}
22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
23 | {{- end -}}
24 | {{- end -}}
25 | {{- end -}}
26 |
27 | {{/*
28 | Create a default fully qualified app name.
29 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
30 | */}}
31 | {{- define "ghost.mariadb.fullname" -}}
32 | {{- printf "%s-%s" .Release.Name "mariadb" | trunc 63 | trimSuffix "-" -}}
33 | {{- end -}}
34 |
35 | {{/*
36 | Get the user defined LoadBalancerIP for this release.
37 | Note, returns 127.0.0.1 if using ClusterIP.
38 | */}}
39 | {{- define "ghost.serviceIP" -}}
40 | {{- if eq .Values.service.type "ClusterIP" -}}
41 | 127.0.0.1
42 | {{- else -}}
43 | {{- .Values.service.loadBalancerIP | default "" -}}
44 | {{- end -}}
45 | {{- end -}}
46 |
47 | {{/*
48 | Gets the host to be used for this application.
49 | If not using ClusterIP, or if a host or LoadBalancerIP is not defined, the value will be empty.
50 | */}}
51 | {{- define "ghost.host" -}}
52 | {{- if .Values.ghostHost -}}
53 | {{- $host := printf "%s%s" .Values.ghostHost .Values.ghostPath -}}
54 | {{- default (include "ghost.serviceIP" .) $host -}}
55 | {{- else -}}
56 | {{- default (include "ghost.serviceIP" .) "" -}}
57 | {{- end -}}
58 | {{- end -}}
59 |
60 | {{/*
61 | Create chart name and version as used by the chart label.
62 | */}}
63 | {{- define "ghost.chart" -}}
64 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
65 | {{- end -}}
66 |
67 | {{/*
68 | Return the proper Ghost image name
69 | */}}
70 | {{- define "ghost.image" -}}
71 | {{- $registryName := .Values.image.registry -}}
72 | {{- $repositoryName := .Values.image.repository -}}
73 | {{- $tag := .Values.image.tag | toString -}}
74 | {{/*
75 | Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
76 | but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
77 | Also, we can't use a single if because lazy evaluation is not an option
78 | */}}
79 | {{- if .Values.global }}
80 | {{- if .Values.global.imageRegistry }}
81 | {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
82 | {{- else -}}
83 | {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
84 | {{- end -}}
85 | {{- else -}}
86 | {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
87 | {{- end -}}
88 | {{- end -}}
89 |
90 | {{/*
91 | Return the proper image name to change the volume permissions
92 | */}}
93 | {{- define "ghost.volumePermissions.image" -}}
94 | {{- $registryName := .Values.volumePermissions.image.registry -}}
95 | {{- $repositoryName := .Values.volumePermissions.image.repository -}}
96 | {{- $tag := .Values.volumePermissions.image.tag | toString -}}
97 | {{/*
98 | Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
99 | but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
100 | Also, we can't use a single if because lazy evaluation is not an option
101 | */}}
102 | {{- if .Values.global }}
103 | {{- if .Values.global.imageRegistry }}
104 | {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
105 | {{- else -}}
106 | {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
107 | {{- end -}}
108 | {{- else -}}
109 | {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
110 | {{- end -}}
111 | {{- end -}}
112 |
113 | {{/*
114 | Return the proper Docker Image Registry Secret Names
115 | */}}
116 | {{- define "ghost.imagePullSecrets" -}}
117 | {{/*
118 | Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
119 | but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
120 | Also, we can not use a single if because lazy evaluation is not an option
121 | */}}
122 | {{- if .Values.global }}
123 | {{- if .Values.global.imagePullSecrets }}
124 | imagePullSecrets:
125 | {{- range .Values.global.imagePullSecrets }}
126 | - name: {{ . }}
127 | {{- end }}
128 | {{- else if or .Values.image.pullSecrets .Values.volumePermissions.image.pullSecrets }}
129 | imagePullSecrets:
130 | {{- range .Values.image.pullSecrets }}
131 | - name: {{ . }}
132 | {{- end }}
133 | {{- range .Values.volumePermissions.image.pullSecrets }}
134 | - name: {{ . }}
135 | {{- end }}
136 | {{- end -}}
137 | {{- else if or .Values.image.pullSecrets .Values.volumePermissions.image.pullSecrets }}
138 | imagePullSecrets:
139 | {{- range .Values.image.pullSecrets }}
140 | - name: {{ . }}
141 | {{- end }}
142 | {{- range .Values.volumePermissions.image.pullSecrets }}
143 | - name: {{ . }}
144 | {{- end }}
145 | {{- end -}}
146 | {{- end -}}
147 |
148 | {{/*
149 | Return the proper Storage Class
150 | */}}
151 | {{- define "ghost.storageClass" -}}
152 | {{/*
153 | Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
154 | but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
155 | */}}
156 | {{- if .Values.global -}}
157 | {{- if .Values.global.storageClass -}}
158 | {{- if (eq "-" .Values.global.storageClass) -}}
159 | {{- printf "storageClassName: \"\"" -}}
160 | {{- else }}
161 | {{- printf "storageClassName: %s" .Values.global.storageClass -}}
162 | {{- end -}}
163 | {{- else -}}
164 | {{- if .Values.persistence.storageClass -}}
165 | {{- if (eq "-" .Values.persistence.storageClass) -}}
166 | {{- printf "storageClassName: \"\"" -}}
167 | {{- else }}
168 | {{- printf "storageClassName: %s" .Values.persistence.storageClass -}}
169 | {{- end -}}
170 | {{- end -}}
171 | {{- end -}}
172 | {{- else -}}
173 | {{- if .Values.persistence.storageClass -}}
174 | {{- if (eq "-" .Values.persistence.storageClass) -}}
175 | {{- printf "storageClassName: \"\"" -}}
176 | {{- else }}
177 | {{- printf "storageClassName: %s" .Values.persistence.storageClass -}}
178 | {{- end -}}
179 | {{- end -}}
180 | {{- end -}}
181 | {{- end -}}
182 |
183 | {{/*
184 | Return the appropriate apiVersion for deployment.
185 | */}}
186 | {{- define "ghost.deployment.apiVersion" -}}
187 | {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
188 | {{- print "extensions/v1beta1" -}}
189 | {{- else -}}
190 | {{- print "apps/v1" -}}
191 | {{- end -}}
192 | {{- end -}}
193 |
--------------------------------------------------------------------------------
/charts/ghost/templates/deployment.yaml:
--------------------------------------------------------------------------------
1 | {{- if include "ghost.host" . -}}
2 | apiVersion: {{ template "ghost.deployment.apiVersion" . }}
3 | kind: Deployment
4 | metadata:
5 | name: {{ template "ghost.fullname" . }}
6 | labels:
7 | app: "{{ template "ghost.fullname" . }}"
8 | chart: "{{ template "ghost.chart" . }}"
9 | release: {{ .Release.Name | quote }}
10 | heritage: {{ .Release.Service | quote }}
11 | spec:
12 | selector:
13 | matchLabels:
14 | app: "{{ template "ghost.fullname" . }}"
15 | release: {{ .Release.Name | quote }}
16 | replicas: 1
17 | template:
18 | metadata:
19 | labels:
20 | app: "{{ template "ghost.fullname" . }}"
21 | chart: "{{ template "ghost.chart" . }}"
22 | release: {{ .Release.Name | quote }}
23 | spec:
24 | {{- if .Values.securityContext.enabled }}
25 | securityContext:
26 | fsGroup: {{ .Values.securityContext.fsGroup }}
27 | runAsUser: {{ .Values.securityContext.runAsUser }}
28 | {{- else }}
29 | initContainers:
30 | - name: volume-permissions
31 | image: {{ template "ghost.volumePermissions.image" . }}
32 | imagePullPolicy: "{{ .Values.volumePermissions.image.pullPolicy }}"
33 | command: ['sh', '-c', 'chmod -R g+rwX {{ .Values.persistence.path }}']
34 | volumeMounts:
35 | - mountPath: {{ .Values.persistence.path }}
36 | name: ghost-data
37 | {{- end }}
38 | {{- include "ghost.imagePullSecrets" . | indent 6 }}
39 | containers:
40 | - name: {{ template "ghost.fullname" . }}
41 | image: {{ template "ghost.image" . }}
42 | imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
43 | env:
44 | - name: ALLOW_EMPTY_PASSWORD
45 | {{- if .Values.allowEmptyPassword }}
46 | value: "yes"
47 | {{- else }}
48 | value: "no"
49 | {{- end }}
50 | - name: MARIADB_HOST
51 | {{- if .Values.mariadb.enabled }}
52 | value: {{ template "ghost.mariadb.fullname" . }}
53 | {{- else }}
54 | value: {{ .Values.externalDatabase.host | quote }}
55 | {{- end }}
56 | - name: MARIADB_PORT_NUMBER
57 | {{- if .Values.mariadb.enabled }}
58 | value: "3306"
59 | {{- else }}
60 | value: {{ .Values.externalDatabase.port | quote }}
61 | {{- end }}
62 | - name: GHOST_DATABASE_NAME
63 | {{- if .Values.mariadb.enabled }}
64 | value: {{ .Values.mariadb.db.name | quote }}
65 | {{- else }}
66 | value: {{ .Values.externalDatabase.database | quote }}
67 | {{- end }}
68 | - name: GHOST_DATABASE_USER
69 | {{- if .Values.mariadb.enabled }}
70 | value: {{ .Values.mariadb.db.user | quote }}
71 | {{- else }}
72 | value: {{ .Values.externalDatabase.user | quote }}
73 | {{- end }}
74 | - name: GHOST_DATABASE_PASSWORD
75 | {{- if .Values.mariadb.enabled }}
76 | valueFrom:
77 | secretKeyRef:
78 | name: {{ template "ghost.mariadb.fullname" . }}
79 | key: mariadb-password
80 | {{- else }}
81 | value: {{ .Values.externalDatabase.password | quote }}
82 | {{- end }}
83 | - name: GHOST_HOST
84 | value: {{ include "ghost.host" . | quote }}
85 | - name: GHOST_PROTOCOL
86 | value: {{ .Values.ghostProtocol | quote }}
87 | - name: GHOST_PORT_NUMBER
88 | {{- if .Values.ghostPort }}
89 | value: {{ .Values.ghostPort | quote }}
90 | {{- else }}
91 | value: {{ .Values.service.port | quote }}
92 | {{- end }}
93 | - name: GHOST_USERNAME
94 | value: {{ .Values.ghostUsername | quote }}
95 | - name: GHOST_PASSWORD
96 | valueFrom:
97 | secretKeyRef:
98 | name: {{ template "ghost.fullname" . }}
99 | key: ghost-password
100 | - name: GHOST_EMAIL
101 | value: {{ .Values.ghostEmail | quote }}
102 | - name: BLOG_TITLE
103 | value: {{ .Values.ghostBlogTitle | quote }}
104 | {{- if .Values.smtpHost }}
105 | - name: SMTP_HOST
106 | value: {{ .Values.smtpHost | quote }}
107 | {{- end }}
108 | {{- if .Values.smtpPort }}
109 | - name: SMTP_PORT
110 | value: {{ .Values.smtpPort | quote }}
111 | {{- end }}
112 | {{- if .Values.smtpUser }}
113 | - name: SMTP_USER
114 | value: {{ .Values.smtpUser | quote }}
115 | {{- end }}
116 | {{- if .Values.smtpPassword }}
117 | - name: SMTP_PASSWORD
118 | valueFrom:
119 | secretKeyRef:
120 | name: {{ template "ghost.fullname" . }}
121 | key: smtp-password
122 | {{- end }}
123 | {{- if .Values.smtpFromAddress }}
124 | - name: SMTP_FROM_ADDRESS
125 | value: {{ .Values.smtpFromAddress | quote }}
126 | {{- end }}
127 | {{- if .Values.smtpService }}
128 | - name: SMTP_SERVICE
129 | value: {{ .Values.smtpService | quote }}
130 | {{- end }}
131 | ports:
132 | - name: http
133 | containerPort: 2368
134 | livenessProbe:
135 | httpGet:
136 | path: {{ .Values.ghostPath }}
137 | port: http
138 | httpHeaders:
139 | - name: Host
140 | value: {{ include "ghost.host" . | quote }}
141 | {{- if eq .Values.ghostProtocol "https" }}
142 | - name: X-Forwarded-Proto
143 | value: https
144 | {{- end }}
145 | initialDelaySeconds: 120
146 | timeoutSeconds: 5
147 | failureThreshold: 6
148 | readinessProbe:
149 | httpGet:
150 | path: {{ .Values.ghostPath }}
151 | port: http
152 | httpHeaders:
153 | - name: Host
154 | value: {{ include "ghost.host" . | quote }}
155 | {{- if eq .Values.ghostProtocol "https" }}
156 | - name: X-Forwarded-Proto
157 | value: https
158 | {{- end }}
159 | initialDelaySeconds: 30
160 | timeoutSeconds: 3
161 | periodSeconds: 5
162 | resources:
163 | {{ toYaml .Values.resources | indent 10 }}
164 | volumeMounts:
165 | - name: ghost-data
166 | mountPath: /bitnami/ghost
167 | volumes:
168 | - name: ghost-data
169 | {{- if .Values.persistence.enabled }}
170 | persistentVolumeClaim:
171 | claimName: {{ template "ghost.fullname" . }}
172 | {{- else }}
173 | emptyDir: {}
174 | {{- end }}
175 | {{- with .Values.nodeSelector }}
176 | nodeSelector:
177 | {{- toYaml . | nindent 8 }}
178 | {{- end }}
179 | {{- with .Values.affinity }}
180 | affinity:
181 | {{- toYaml . | nindent 8 }}
182 | {{- end }}
183 | {{- end -}}
184 |
--------------------------------------------------------------------------------
/charts/ghost/templates/ingress.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.ingress.enabled }}
2 | apiVersion: extensions/v1beta1
3 | kind: Ingress
4 | metadata:
5 | name: {{ template "ghost.fullname" . }}
6 | labels:
7 | app: "{{ template "ghost.fullname" . }}"
8 | chart: "{{ template "ghost.chart" . }}"
9 | release: {{ .Release.Name | quote }}
10 | heritage: {{ .Release.Service | quote }}
11 | annotations:
12 | {{- if .Values.ingress.certManager }}
13 | kubernetes.io/tls-acme: "true"
14 | {{- end }}
15 | {{- range $key, $value := .Values.ingress.annotations }}
16 | {{ $key }}: {{ $value | quote }}
17 | {{- end }}
18 | spec:
19 | rules:
20 | {{- range .Values.ingress.hosts }}
21 | - host: {{ .name }}
22 | http:
23 | paths:
24 | - path: {{ default "/" .path }}
25 | backend:
26 | serviceName: {{ template "ghost.fullname" $ }}
27 | servicePort: http
28 | {{- end }}
29 | tls:
30 | {{- range .Values.ingress.hosts }}
31 | {{- if .tls }}
32 | - hosts:
33 | {{- if .tlsHosts }}
34 | {{- range $host := .tlsHosts }}
35 | - {{ $host }}
36 | {{- end }}
37 | {{- else }}
38 | - {{ .name }}
39 | {{- end }}
40 | secretName: {{ .tlsSecret }}
41 | {{- end }}
42 | {{- end }}
43 | {{- end }}
44 |
--------------------------------------------------------------------------------
/charts/ghost/templates/pvc.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.persistence.enabled -}}
2 | kind: PersistentVolumeClaim
3 | apiVersion: v1
4 | metadata:
5 | name: {{ template "ghost.fullname" . }}
6 | labels:
7 | app: "{{ template "ghost.fullname" . }}"
8 | chart: "{{ template "ghost.chart" . }}"
9 | release: {{ .Release.Name | quote }}
10 | heritage: {{ .Release.Service | quote }}
11 | spec:
12 | accessModes:
13 | - {{ .Values.persistence.accessMode | quote }}
14 | resources:
15 | requests:
16 | storage: {{ .Values.persistence.size | quote }}
17 | {{ include "ghost.storageClass" . }}
18 | {{- end -}}
19 |
--------------------------------------------------------------------------------
/charts/ghost/templates/secrets.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | name: {{ template "ghost.fullname" . }}
5 | labels:
6 | app: "{{ template "ghost.fullname" . }}"
7 | chart: "{{ template "ghost.chart" . }}"
8 | release: {{ .Release.Name | quote }}
9 | heritage: {{ .Release.Service | quote }}
10 | type: Opaque
11 | data:
12 | {{- if .Values.ghostPassword }}
13 | ghost-password: {{ .Values.ghostPassword | b64enc | quote }}
14 | {{- else }}
15 | ghost-password: {{ randAlphaNum 10 | b64enc | quote }}
16 | {{- end }}
17 | {{- if .Values.smtpPassword }}
18 | smtp-password: {{ default "" .Values.smtpPassword | b64enc | quote }}
19 | {{- end }}
20 |
--------------------------------------------------------------------------------
/charts/ghost/templates/svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ template "ghost.fullname" . }}
5 | labels:
6 | app: "{{ template "ghost.fullname" . }}"
7 | chart: "{{ template "ghost.chart" . }}"
8 | release: {{ .Release.Name | quote }}
9 | heritage: {{ .Release.Service | quote }}
10 | annotations:
11 | {{- range $key, $value := .Values.service.annotations }}
12 | {{ $key }}: {{ $value | quote }}
13 | {{- end }}
14 |
15 | spec:
16 | type: {{ .Values.service.type }}
17 | {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }}
18 | externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }}
19 | {{- end }}
20 | {{- if eq .Values.service.type "LoadBalancer" }}
21 | loadBalancerIP: {{ default "" .Values.service.loadBalancerIP | quote }}
22 | {{- end }}
23 | ports:
24 | - name: http
25 | port: {{ .Values.service.port }}
26 | targetPort: http
27 | {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePorts.http)))}}
28 | nodePort: {{ .Values.service.nodePorts.http }}
29 | {{- end }}
30 | selector:
31 | app: "{{ template "ghost.fullname" . }}"
32 |
--------------------------------------------------------------------------------
/charts/ghost/values.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema#",
3 | "type": "object",
4 | "properties": {
5 | "ghostUsername": {
6 | "type": "string",
7 | "title": "User",
8 | "form": true
9 | },
10 | "ghostPassword": {
11 | "type": "string",
12 | "title": "Password",
13 | "form": true,
14 | "description": "Defaults to a random 10-character alphanumeric string if not set"
15 | },
16 | "ghostEmail": {
17 | "type": "string",
18 | "title": "Admin email",
19 | "form": true
20 | },
21 | "ghostBlogTitle": {
22 | "type": "string",
23 | "title": "Blog Name",
24 | "form": true
25 | },
26 | "ghostHost": {
27 | "type": "string",
28 | "title": "Host",
29 | "form": true,
30 | "description": "Hostname used to generate application URLs"
31 | },
32 | "persistence": {
33 | "type": "object",
34 | "properties": {
35 | "size": {
36 | "type": "string",
37 | "title": "Persistent Volume Size",
38 | "form": true,
39 | "render": "slider",
40 | "sliderMin": 1,
41 | "sliderMax": 100,
42 | "sliderUnit": "Gi"
43 | }
44 | }
45 | },
46 | "mariadb": {
47 | "type": "object",
48 | "form": true,
49 | "title": "MariaDB Details",
50 | "properties": {
51 | "enabled": {
52 | "type": "boolean",
53 | "title": "Use a new MariaDB database hosted in the cluster",
54 | "form": true,
55 | "description": "Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database switch this off and configure the external database parameters"
56 | },
57 | "master": {
58 | "type": "object",
59 | "properties": {
60 | "persistence": {
61 | "type": "object",
62 | "properties": {
63 | "size": {
64 | "type": "string",
65 | "title": "Volume Size",
66 | "form": true,
67 | "hidden": {
68 | "condition": false,
69 | "value": "mariadb.enabled"
70 | },
71 | "render": "slider",
72 | "sliderMin": 1,
73 | "sliderMax": 100,
74 | "sliderUnit": "Gi"
75 | }
76 | }
77 | }
78 | }
79 | }
80 | }
81 | },
82 | "externalDatabase": {
83 | "type": "object",
84 | "title": "External Database Details",
85 | "description": "If MariaDB is disabled. Use this section to specify the external database details",
86 | "form": true,
87 | "properties": {
88 | "host": {
89 | "type": "string",
90 | "form": true,
91 | "title": "Database Host",
92 | "hidden": "mariadb.enabled"
93 | },
94 | "user": {
95 | "type": "string",
96 | "form": true,
97 | "title": "Database Username",
98 | "hidden": "mariadb.enabled"
99 | },
100 | "password": {
101 | "type": "string",
102 | "form": true,
103 | "title": "Database Password",
104 | "hidden": "mariadb.enabled"
105 | },
106 | "database": {
107 | "type": "string",
108 | "form": true,
109 | "title": "Database Name",
110 | "hidden": "mariadb.enabled"
111 | },
112 | "port": {
113 | "type": "integer",
114 | "form": true,
115 | "title": "Database Port",
116 | "hidden": "mariadb.enabled"
117 | }
118 | }
119 | },
120 | "resources": {
121 | "type": "object",
122 | "title": "Required Resources",
123 | "description": "Configure resource requests",
124 | "form": true,
125 | "properties": {
126 | "requests": {
127 | "type": "object",
128 | "properties": {
129 | "memory": {
130 | "type": "string",
131 | "form": true,
132 | "render": "slider",
133 | "title": "Memory Request",
134 | "sliderMin": 10,
135 | "sliderMax": 2048,
136 | "sliderUnit": "Mi"
137 | },
138 | "cpu": {
139 | "type": "string",
140 | "form": true,
141 | "render": "slider",
142 | "title": "CPU Request",
143 | "sliderMin": 10,
144 | "sliderMax": 2000,
145 | "sliderUnit": "m"
146 | }
147 | }
148 | }
149 | }
150 | },
151 | "securityContext": {
152 | "type": "object",
153 | "properties": {
154 | "enabled": {
155 | "type": "boolean",
156 | "title": "Enable Pod Security Context",
157 | "description": "When disabled, an initContainer will be used to set required folder permissions",
158 | "form": true
159 | }
160 | }
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/charts/ghost/values.yaml:
--------------------------------------------------------------------------------
1 | ## Global Docker image parameters
2 | ## Please, note that this will override the image parameters, including dependencies, configured to use the global value
3 | ## Current available global Docker image parameters: imageRegistry and imagePullSecrets
4 | ##
5 | # global:
6 | # imageRegistry: myRegistryName
7 | # imagePullSecrets:
8 | # - myRegistryKeySecretName
9 | # storageClass: myStorageClass
10 |
11 | ## Bitnami Ghost image version
12 | ## ref: https://hub.docker.com/r/bitnami/ghost/tags/
13 | ##
14 | image:
15 | registry: docker.io
16 | repository: bitnami/ghost
17 | tag: 3.1.1-debian-9-r0
18 | ## Specify a imagePullPolicy
19 | ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
20 | ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
21 | ##
22 | pullPolicy: IfNotPresent
23 | ## Optionally specify an array of imagePullSecrets.
24 | ## Secrets must be manually created in the namespace.
25 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
26 | ##
27 | # pullSecrets:
28 | # - myRegistryKeySecretName
29 |
30 | ## String to partially override ghost.fullname template (will maintain the release name)
31 | ##
32 | # nameOverride:
33 |
34 | ## String to fully override ghost.fullname template
35 | ##
36 | # fullnameOverride:
37 |
38 | ## Init containers parameters:
39 | ## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup
40 | ##
41 | volumePermissions:
42 | image:
43 | registry: docker.io
44 | repository: bitnami/minideb
45 | tag: stretch
46 | pullPolicy: Always
47 | ## Optionally specify an array of imagePullSecrets.
48 | ## Secrets must be manually created in the namespace.
49 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
50 | ##
51 | # pullSecrets:
52 | # - myRegistryKeySecretName
53 |
54 | ## Ghost protocol, host, port and path to create application URLs
55 | ## ref: https://github.com/bitnami/bitnami-docker-ghost#configuration
56 | ##
57 | ghostProtocol: http
58 | # ghostHost:
59 | # ghostPort:
60 | ghostPath: /
61 |
62 | ## User of the application
63 | ## ref: https://github.com/bitnami/bitnami-docker-ghost#configuration
64 | ##
65 | ghostUsername: user@example.com
66 |
67 | ## Application password
68 | ## Defaults to a random 10-character alphanumeric string if not set
69 | ## ref: https://github.com/bitnami/bitnami-docker-ghost#configuration
70 | ##
71 | # ghostPassword:
72 |
73 | ## Admin email
74 | ## ref: https://github.com/bitnami/bitnami-docker-ghost#configuration
75 | ##
76 | ghostEmail: user@example.com
77 |
78 | ## Ghost Blog name
79 | ## ref: https://github.com/bitnami/bitnami-docker-ghost#environment-variables
80 | ##
81 | ghostBlogTitle: User's Blog
82 |
83 | ## Set to `yes` to allow the container to be started with blank passwords
84 | ## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables
85 | allowEmptyPassword: "yes"
86 |
87 | ## SMTP mail delivery configuration
88 | ## ref: https://github.com/bitnami/bitnami-docker-redmine/#smtp-configuration
89 | ##
90 | # smtpHost:
91 | # smtpPort:
92 | # smtpUser:
93 | # smtpPassword:
94 | # smtpFromAddress
95 | # smtpService:
96 |
97 | ##
98 | ## External database configuration
99 | ##
100 | externalDatabase:
101 | ## All of these values are only used when mariadb.enabled is set to false
102 | ## Database host
103 | host: localhost
104 |
105 | ## non-root Username for Wordpress Database
106 | user: bn_ghost
107 |
108 | ## Database password
109 | password: ""
110 |
111 | ## Database name
112 | database: bitnami_ghost
113 |
114 | ## Database port number
115 | port: 3306
116 |
117 | ##
118 | ## MariaDB chart configuration
119 | ##
120 | ## https://github.com/helm/charts/blob/master/stable/mariadb/values.yaml
121 | ##
122 | mariadb:
123 | ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters
124 | enabled: true
125 | ## Disable MariaDB replication
126 | replication:
127 | enabled: false
128 |
129 | ## Create a database and a database user
130 | ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run
131 | ##
132 | db:
133 | name: bitnami_ghost
134 | user: bn_ghost
135 | ## If the password is not specified, mariadb will generates a random password
136 | ##
137 | # password:
138 |
139 | ## MariaDB admin password
140 | ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run
141 | ##
142 | # rootUser:
143 | # password:
144 |
145 | ## Enable persistence using Persistent Volume Claims
146 | ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
147 | ##
148 | master:
149 | persistence:
150 | enabled: true
151 | ## mariadb data Persistent Volume Storage Class
152 | ## If defined, storageClassName:
153 | ## If set to "-", storageClassName: "", which disables dynamic provisioning
154 | ## If undefined (the default) or set to null, no storageClassName spec is
155 | ## set, choosing the default provisioner. (gp2 on AWS, standard on
156 | ## GKE, AWS & OpenStack)
157 | ##
158 | # storageClass: "-"
159 | accessMode: ReadWriteOnce
160 | size: 8Gi
161 |
162 | ## Kubernetes configuration
163 | ## For minikube, set this to NodePort, elsewhere use LoadBalancer
164 | ##
165 | service:
166 | type: LoadBalancer
167 | # HTTP Port
168 | port: 80
169 | ## loadBalancerIP:
170 | ##
171 | ## nodePorts:
172 | ## http:
173 | nodePorts:
174 | http: ""
175 | ## Enable client source IP preservation
176 | ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
177 | ##
178 | externalTrafficPolicy: Cluster
179 | ## Service annotations done as key:value pairs
180 | annotations:
181 |
182 | ## Pod Security Context
183 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
184 | ##
185 | securityContext:
186 | enabled: true
187 | fsGroup: 1001
188 | runAsUser: 1001
189 |
190 | ## Enable persistence using Persistent Volume Claims
191 | ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
192 | ##
193 | persistence:
194 | enabled: true
195 | ## ghost data Persistent Volume Storage Class
196 | ## If defined, storageClassName:
197 | ## If set to "-", storageClassName: "", which disables dynamic provisioning
198 | ## If undefined (the default) or set to null, no storageClassName spec is
199 | ## set, choosing the default provisioner. (gp2 on AWS, standard on
200 | ## GKE, AWS & OpenStack)
201 | ##
202 | # storageClass: "-"
203 | accessMode: ReadWriteOnce
204 | size: 8Gi
205 | path: /bitnami
206 |
207 | ## Configure resource requests and limits
208 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/
209 | ##
210 | resources:
211 | requests:
212 | memory: 512Mi
213 | cpu: 300m
214 |
215 | ## Configure the ingress resource that allows you to access the
216 | ## Ghost installation. Set up the URL
217 | ## ref: http://kubernetes.io/docs/user-guide/ingress/
218 | ##
219 | ingress:
220 | ## Set to true to enable ingress record generation
221 | enabled: false
222 |
223 | ## Set this to true in order to add the corresponding annotations for cert-manager
224 | certManager: false
225 |
226 | ## Ingress annotations done as key:value pairs
227 | ## For a full list of possible ingress annotations, please see
228 | ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md
229 | ##
230 | ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set
231 | ## If certManager is set to true, annotation kubernetes.io/tls-acme: "true" will automatically be set
232 | annotations:
233 | # kubernetes.io/ingress.class: nginx
234 |
235 | ## The list of hostnames to be covered with this ingress record.
236 | ## Most likely this will be just one host, but in the event more hosts are needed, this is an array
237 | hosts:
238 | - name: ghost.local
239 | path: /
240 |
241 | ## Set this to true in order to enable TLS on the ingress record
242 | tls: false
243 |
244 | ## Optionally specify the TLS hosts for the ingress record
245 | ## Useful when the Ingress controller supports www-redirection
246 | ## If not specified, the above host name will be used
247 | # tlsHosts:
248 | # - www.ghost.local
249 | # - ghost.local
250 |
251 | ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS
252 | tlsSecret: ghost.local-tls
253 |
254 | secrets:
255 | ## If you're providing your own certificates, please use this to add the certificates as secrets
256 | ## key and certificate should start with -----BEGIN CERTIFICATE----- or
257 | ## -----BEGIN RSA PRIVATE KEY-----
258 | ##
259 | ## name should line up with a tlsSecret set further up
260 | ## If you're using cert-manager, this is unneeded, as it will create the secret for you if it is not set
261 | ##
262 | ## It is also possible to create and manage the certificates outside of this helm chart
263 | ## Please see README.md for more information
264 | # - name: ghost.local-tls
265 | # key:
266 | # certificate:
267 |
268 | ## Node selector for pod assignment
269 | ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
270 | ##
271 | nodeSelector: {}
272 |
273 | ## Affinity for pod assignment
274 | ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
275 | ##
276 | affinity: {}
277 |
--------------------------------------------------------------------------------
/namespaces/demo.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | labels:
5 | name: demo
6 | name: demo
7 |
--------------------------------------------------------------------------------
/releases/ghost.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: helm.fluxcd.io/v1
3 | kind: HelmRelease
4 | metadata:
5 | name: ghost
6 | namespace: demo
7 | annotations:
8 | fluxcd.io/automated: "false"
9 | fluxcd.io/tag.chart-image: glob:3.1.1-debian-9-*
10 | spec:
11 | releaseName: ghost
12 | chart:
13 | git: ssh://git@github.com/fluxcd/flux-get-started
14 | ref: master
15 | path: charts/ghost
16 | values:
17 | image:
18 | repository: bitnami/ghost
19 | tag: 3.1.1-debian-9-r0
20 | persistence:
21 | enabled: false
22 | resources:
23 | requests:
24 | memory: 32Mi
25 | cpu: 10m
26 | service:
27 | type: ClusterIP
28 | mariadb:
29 | master:
30 | persistence:
31 | enabled: false
32 |
--------------------------------------------------------------------------------
/releases/mongodb.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: helm.fluxcd.io/v1
3 | kind: HelmRelease
4 | metadata:
5 | name: mongodb
6 | namespace: demo
7 | annotations:
8 | fluxcd.io/automated: "false"
9 | fluxcd.io/tag.chart-image: semver:~4.0
10 | spec:
11 | releaseName: mongodb
12 | chart:
13 | repository: https://kubernetes-charts.storage.googleapis.com/
14 | name: mongodb
15 | version: 7.6.3
16 | values:
17 | image:
18 | repository: bitnami/mongodb
19 | tag: 4.0.13
20 | usePassword: false
21 | persistence:
22 | enabled: false
23 | securityContext:
24 | enabled: true
25 | fsGroup: 0
26 | runAsUser: 0
27 |
--------------------------------------------------------------------------------
/releases/redis-auth.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # This secret should be stored in Git encrypted
3 | # Sealed Secrets example: https://github.com/stefanprodan/gitops-helm#managing-kubernetes-secrets
4 | apiVersion: v1
5 | kind: Secret
6 | metadata:
7 | name: redis-auth
8 | namespace: demo
9 | data:
10 | values.yaml: cGFzc3dvcmQ6IGFkbWlu
11 |
--------------------------------------------------------------------------------
/releases/redis.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: helm.fluxcd.io/v1
3 | kind: HelmRelease
4 | metadata:
5 | name: redis
6 | namespace: demo
7 | annotations:
8 | fluxcd.io/automated: "true"
9 | fluxcd.io/tag.chart-image: semver:~5.0
10 | fluxcd.io/locked: "true"
11 | fluxcd.io/locked_msg: "Halt updates for now"
12 | fluxcd.io/locked_user: "Stefan Prodan "
13 | spec:
14 | releaseName: redis
15 | chart:
16 | repository: https://kubernetes-charts.storage.googleapis.com/
17 | name: redis
18 | version: 10.3.1
19 | valueFileSecrets:
20 | # the redis-auth secret contains the password value
21 | - name: redis-auth
22 | values:
23 | usePassword: true
24 | image:
25 | repository: bitnami/redis
26 | tag: 5.0.7
27 | service:
28 | type: ClusterIP
29 | port: 6379
30 | cluster:
31 | enabled: false
32 | master:
33 | securityContext:
34 | enabled: false
35 | fsGroup: 0
36 | runAsUser: 0
37 | persistence:
38 | enabled: false
39 |
--------------------------------------------------------------------------------
/workloads/podinfo-dep.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: apps/v1
3 | kind: Deployment
4 | metadata:
5 | name: podinfo
6 | namespace: demo
7 | labels:
8 | app: podinfo
9 | annotations:
10 | fluxcd.io/automated: "true"
11 | fluxcd.io/tag.init: regex:^3.10.*
12 | fluxcd.io/tag.podinfod: semver:~3.1
13 | spec:
14 | strategy:
15 | rollingUpdate:
16 | maxUnavailable: 0
17 | type: RollingUpdate
18 | selector:
19 | matchLabels:
20 | app: podinfo
21 | template:
22 | metadata:
23 | annotations:
24 | prometheus.io/scrape: "true"
25 | prometheus.io/port: "9797"
26 | labels:
27 | app: podinfo
28 | spec:
29 | initContainers:
30 | - name: init
31 | image: alpine:3.10.1
32 | command:
33 | - sleep
34 | - "1"
35 | containers:
36 | - name: podinfod
37 | image: stefanprodan/podinfo:3.1.0
38 | imagePullPolicy: IfNotPresent
39 | ports:
40 | - name: http
41 | containerPort: 9898
42 | protocol: TCP
43 | - name: http-metrics
44 | containerPort: 9797
45 | protocol: TCP
46 | - name: grpc
47 | containerPort: 9999
48 | protocol: TCP
49 | command:
50 | - ./podinfo
51 | - --port=9898
52 | - --port-metrics=9797
53 | - --grpc-port=9999
54 | - --grpc-service-name=podinfo
55 | - --level=info
56 | - --random-delay=false
57 | - --random-error=false
58 | env:
59 | - name: PODINFO_UI_COLOR
60 | value: "#34577c"
61 | livenessProbe:
62 | httpGet:
63 | path: /healthz
64 | port: 9898
65 | readinessProbe:
66 | httpGet:
67 | path: /readyz
68 | port: 9898
69 | resources:
70 | limits:
71 | cpu: 1000m
72 | memory: 128Mi
73 | requests:
74 | cpu: 10m
75 | memory: 64Mi
76 |
--------------------------------------------------------------------------------
/workloads/podinfo-hpa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: autoscaling/v2beta1
2 | kind: HorizontalPodAutoscaler
3 | metadata:
4 | name: podinfo
5 | namespace: demo
6 | spec:
7 | scaleTargetRef:
8 | apiVersion: apps/v1
9 | kind: Deployment
10 | name: podinfo
11 | minReplicas: 2
12 | maxReplicas: 4
13 | metrics:
14 | - type: Resource
15 | resource:
16 | name: cpu
17 | # scale up if usage is above
18 | # 99% of the requested CPU (10m)
19 | targetAverageUtilization: 99
20 |
--------------------------------------------------------------------------------
/workloads/podinfo-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: podinfo
5 | namespace: demo
6 | labels:
7 | app: podinfo
8 | spec:
9 | type: ClusterIP
10 | selector:
11 | app: podinfo
12 | ports:
13 | - name: http
14 | port: 9898
15 | protocol: TCP
16 | targetPort: http
17 |
--------------------------------------------------------------------------------