stack_car 0.6.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +64 -1
  3. data/lib/stack_car.rb +1 -0
  4. data/lib/stack_car/cli.rb +136 -38
  5. data/lib/stack_car/dot_rc.rb +25 -0
  6. data/lib/stack_car/version.rb +1 -1
  7. data/stack_car.gemspec +1 -0
  8. data/templates/.dockerignore.erb +2 -2
  9. data/templates/.env.development.erb +2 -0
  10. data/templates/.env.erb +15 -16
  11. data/templates/.gitlab-ci.yml.erb +94 -62
  12. data/templates/Dockerfile.base.erb +28 -19
  13. data/templates/Dockerfile.erb +26 -7
  14. data/templates/chart-fcrepo/fcrepo-deploy.yaml +63 -0
  15. data/templates/chart-fcrepo/fcrepo-env-cm.yaml +8 -0
  16. data/templates/chart-fcrepo/fcrepo-env-secret.yaml.tt +10 -0
  17. data/templates/chart-fcrepo/fcrepo-pvc.yaml +20 -0
  18. data/templates/chart-fcrepo/fcrepo-svc.yaml +19 -0
  19. data/templates/chart-sidekiq/sidekiq-deploy.yaml +80 -0
  20. data/templates/chart/.gitignore +3 -0
  21. data/templates/chart/.helmignore +23 -0
  22. data/templates/chart/Chart.yaml.tt +29 -0
  23. data/templates/chart/README.md +223 -0
  24. data/templates/chart/bin/check_sidekiq.rb +0 -0
  25. data/templates/chart/bin/decrypt +17 -0
  26. data/templates/chart/bin/deploy +14 -0
  27. data/templates/chart/bin/encrypt +15 -0
  28. data/templates/chart/bin/remove +15 -0
  29. data/templates/chart/sample-values.yaml.tt +138 -0
  30. data/templates/chart/templates/_helpers.tpl.tt +85 -0
  31. data/templates/chart/templates/rails-env-cm.yaml.tt +47 -0
  32. data/templates/chart/templates/rails-env-secret.yaml +10 -0
  33. data/templates/chart/templates/rails-pvc-shared.yml +20 -0
  34. data/templates/chart/templates/setup-job.yaml +73 -0
  35. data/templates/chart/templates/web-deploy.yaml +67 -0
  36. data/templates/chart/templates/web-ing-wildcard.yaml +20 -0
  37. data/templates/chart/templates/web-ing.yaml +20 -0
  38. data/templates/chart/templates/web-svc.yaml +20 -0
  39. data/templates/database.yml.erb +10 -10
  40. data/templates/docker-compose.yml.erb +53 -12
  41. data/templates/env.conf.erb +11 -9
  42. data/templates/nginx.sh.erb +17 -0
  43. metadata +47 -10
  44. data/templates/docker-compose.ci.yml.erb +0 -87
  45. data/templates/docker-compose.production.yml.erb +0 -26
@@ -0,0 +1,8 @@
1
+ ---
2
+ apiVersion: v1
3
+ kind: ConfigMap
4
+ metadata:
5
+ name: {{ template "app.fcrepo-env.name" . }}
6
+ data:
7
+ DATABASE_USER: {{ .Values.env.configmap.DATABASE_USER }}
8
+ DATABASE_NAME: {{ .Values.env.configmap.FC_DATABASE_NAME }}
@@ -0,0 +1,10 @@
1
+ ---
2
+ apiVersion: v1
3
+ kind: Secret
4
+ metadata:
5
+ name: {{ template "app.fcrepo-env.name" . }}
6
+ data:
7
+ DATABASE_PASSWORD: {{ .Values.env.secret.DATABASE_PASSWORD | b64enc }}
8
+ <% if options[:postgres] %>
9
+ JAVA_OPTS: {{ printf "-Dfcrepo.modeshape.configuration=\"classpath:/config/jdbc-postgresql/repository.json\" -Dfcrepo.postgresql.host=\"%s\" -Dfcrepo.postgresql.username=\"%s\" -Dfcrepo.postgresql.password=\"%s\" -Dfcrepo.object.directory=\"/data/objects\" -Dfcrepo.binary.directory=\"/data/binaries\"" ( include "app.postgres.name" . ) .Values.env.configmap.DATABASE_USER .Values.env.secret.DATABASE_PASSWORD | b64enc }}
10
+ <% end %>
@@ -0,0 +1,20 @@
1
+ ---
2
+ kind: PersistentVolumeClaim
3
+ apiVersion: v1
4
+ metadata:
5
+ name: {{ template "app.fcrepo.name" . }}
6
+ labels:
7
+ app: {{ template "app.name" . }}
8
+ chart: {{ template "app.chart" . }}
9
+ release: {{ .Release.Name }}
10
+ heritage: {{ .Release.Service }}
11
+ component: fcrepo
12
+ spec:
13
+ accessModes:
14
+ - ReadWriteOnce
15
+ resources:
16
+ requests:
17
+ storage: {{ .Values.fcrepo.storage.size }}
18
+ {{- if .Values.fcrepo.storage.className }}
19
+ storageClassName: "{{ .Values.fcrepo.storage.ClassName }}"
20
+ {{- end }}
@@ -0,0 +1,19 @@
1
+ ---
2
+ apiVersion: v1
3
+ kind: Service
4
+ metadata:
5
+ name: {{ template "app.fcrepo.name" . }}
6
+ labels:
7
+ app: {{ template "app.name" . }}
8
+ chart: {{ template "app.chart" . }}
9
+ release: {{ .Release.Name }}
10
+ heritage: {{ .Release.Service }}
11
+ component: fcrepo
12
+ spec:
13
+ ports:
14
+ - protocol: TCP
15
+ port: 8080
16
+ selector:
17
+ app: {{ template "app.name" . }}
18
+ release: {{ .Release.Name }}
19
+ component: fcrepo
@@ -0,0 +1,80 @@
1
+ ---
2
+ apiVersion: apps/v1
3
+ kind: Deployment
4
+ metadata:
5
+ name: {{ template "app.sidekiq.name" . }}
6
+ labels:
7
+ app: {{ template "app.name" . }}
8
+ chart: {{ template "app.chart" . }}
9
+ release: {{ .Release.Name }}
10
+ heritage: {{ .Release.Service }}
11
+ component: sidekiq
12
+ spec:
13
+ replicas: {{ .Values.sidekiq.replicas }}
14
+ selector:
15
+ matchLabels:
16
+ app: {{ template "app.name" . }}
17
+ release: {{ .Release.Name }}
18
+ component: sidekiq
19
+ template:
20
+ metadata:
21
+ labels:
22
+ app: {{ template "app.name" . }}
23
+ release: {{ .Release.Name }}
24
+ component: sidekiq
25
+ annotations:
26
+ checksum/rails-env-cm: {{ include (print $.Template.BasePath "/rails-env-cm.yaml") . | sha256sum }}
27
+ checksum/rails-env-secret: {{ include (print $.Template.BasePath "/rails-env-secret.yaml") . | sha256sum }}
28
+ spec:
29
+ restartPolicy: Always
30
+ terminationGracePeriodSeconds: {{ .Values.sidekiq.timeout | add 5 }}
31
+ {{- if .Values.rails.imagePullSecrets }}
32
+ imagePullSecrets:
33
+ {{ toYaml .Values.rails.imagePullSecrets }}
34
+ {{- end }}
35
+ volumes:
36
+ - name: shared
37
+ persistentVolumeClaim:
38
+ claimName: {{ template "app.rails-env.name" . }}-shared
39
+ containers:
40
+ - name: sidekiq
41
+ image: {{ .Values.rails.image.repository }}:{{ .Values.rails.image.tag }}
42
+ imagePullPolicy: Always
43
+ command: ["/bin/bash"]
44
+ args:
45
+ - "-l"
46
+ - "-c"
47
+ - "bundle exec sidekiq"
48
+ # livenessProbe:
49
+ # exec:
50
+ # command:
51
+ # - ./bin/rails runner ./chart/bin/check_sidekiq.rb
52
+ # initialDelaySeconds: 30
53
+ # Use sub-path for individual folders
54
+ volumeMounts:
55
+ - mountPath: /home/app/webapp/tmp/imports
56
+ name: shared
57
+ subPath: import_path
58
+ - mountPath: /home/app/webapp/tmp/exports
59
+ name: shared
60
+ subPath: export_path
61
+ - mountPath: /home/app/webapp/tmp/derivatives_path
62
+ name: shared
63
+ subPath: derivatives_path
64
+ - mountPath: /home/app/webapp/tmp/uploads
65
+ name: shared
66
+ subPath: upload_path
67
+ - mountPath: /home/app/webapp/public/uploads
68
+ name: shared
69
+ subPath: uploads
70
+ - mountPath: /home/app/webapp/public/assets
71
+ name: shared
72
+ subPath: assets
73
+ - mountPath: /home/app/webapp/public/branding
74
+ name: shared
75
+ subPath: branding
76
+ envFrom:
77
+ - configMapRef:
78
+ name: {{ template "app.rails-env.name" . }}
79
+ - secretRef:
80
+ name: {{ template "app.rails-env.name" . }}
@@ -0,0 +1,3 @@
1
+ server.pem
2
+ server.key
3
+ *values.yaml
@@ -0,0 +1,23 @@
1
+ # Patterns to ignore when building packages.
2
+ # This supports shell glob matching, relative path matching, and
3
+ # negation (prefixed with !). Only one pattern per line.
4
+ .DS_Store
5
+ # Common VCS dirs
6
+ .git/
7
+ .gitignore
8
+ .bzr/
9
+ .bzrignore
10
+ .hg/
11
+ .hgignore
12
+ .svn/
13
+ # Common backup files
14
+ *.swp
15
+ *.bak
16
+ *.tmp
17
+ *~
18
+ # Various IDEs
19
+ .project
20
+ .idea/
21
+ *.tmproj
22
+ server.pem
23
+ server.key
@@ -0,0 +1,29 @@
1
+ apiVersion: v1
2
+ appVersion: "0.0.1"
3
+ description: A Helm chart for <%= @project_name %>
4
+ name: <%= @project_name %>
5
+ version: 0.0.1
6
+ dependencies:
7
+ <%- if options[:solr] %>
8
+ - name: solr
9
+ version: 1.3.3
10
+ repository: https://storage.googleapis.com/kubernetes-charts-incubator
11
+ <%- end %>
12
+ <%- if options[:redis] %>
13
+ - name: redis
14
+ version: 10.3.1
15
+ repository: https://kubernetes-charts.storage.googleapis.com/
16
+ condition: redis.enabled
17
+ <%- end %>
18
+ <%- if options[:postgres] %>
19
+ - name: postgresql
20
+ version: 8.1.2
21
+ repository: https://kubernetes-charts.storage.googleapis.com/
22
+ condition: postgresql.enabled
23
+ <%- end %>
24
+ <%- if options[:mysql] %>
25
+ - name: mariadb
26
+ version: 5.x.x
27
+ repository: https://kubernetes-charts.storage.googleapis.com/
28
+ condition: mariadb.enabled
29
+ <%- end %>
@@ -0,0 +1,223 @@
1
+ Helm Chart
2
+ ==========
3
+
4
+ This is a Rails Helm Chart which can be used to deploy a Rails instance to a Kubernetes cluster.
5
+
6
+ # Requirements
7
+
8
+ * helm
9
+ ```
10
+ brew install helm
11
+ ```
12
+
13
+ * kubernetes
14
+ Kubectl is the command line tool for controlling Kubernetes clusters. It is available via (https://docs.docker.com/docker-for-mac/)[Docker for Mac]
15
+
16
+ Alternatively:
17
+ ```
18
+ brew install kubectl
19
+ ```
20
+
21
+ # Getting Started Locally using Docker for Mac
22
+
23
+ ## Setup
24
+
25
+ Install Docker for Mac (DfM)
26
+
27
+ Enable the Kubernetes Cluster in the DfM Settings
28
+
29
+ In the menu bar item for DfM you'll 'Kubernetes', this will list the available clusters. For local deployment make sure docker-desktop is selected.
30
+
31
+ ## KubeConfig
32
+
33
+ Kubernetetes creates a config file at `~/.kube/config`. When we come to setting up access to external clusters, we will be editing this file. That will add clusters to the DfM Kubernetes list. Remember that if you are running deployment actions using helm or kubectl they will use the cluster selected in that list, so if you were deploying to a production server yesterday, that will still be selected. It is a good practice to run `kubectl cluster-info` or `kubectl config current-context` before starting any deployment to make sure you are deploying to the right cluster.
34
+
35
+ ## GitLab Secret
36
+
37
+ To pull images from a private registry, you'll need a secret
38
+
39
+ For GitLab, create a Personal Access Token in GitLab with read access.
40
+
41
+ Create your secret (called gitlab) in kubectl, substituting the items in {} with your data:
42
+ ```
43
+ create secret docker-registry gitlab --docker-server=https://registry.gitlab.com --docker-username={YOUR USERNAME} --docker-password={PERSONAL ACCESS TOKEN} --docker-email={YOUR EMAIL} --namespace {NAMESPACE eg. hyku-staging}
44
+ ```
45
+
46
+ Reference the secret in `imagePullSecrets`, see the sample.yamnl file for an example.
47
+
48
+ For other private registries, please consult their documentation on access tokens.
49
+
50
+ ## TLS Secret
51
+
52
+ We also need to setup a secret for TLS certificates.
53
+
54
+ ```
55
+ # this command will generate self signed server certificate and key: server.pem, server.key
56
+ # key and cert are stored in Secret object named `demoapp-puma-tls`.
57
+ # you can confirm this object by `kubectl describe secret demoapp-puma-tls`
58
+ export COMMON_NAME=localhost
59
+ openssl req -new -x509 -nodes -keyout server.key -days 3650 \
60
+ -subj "/CN=${COMMON_NAME}" \
61
+ -extensions v3_req \
62
+ -config <(cat openssl.conf | sed s/\${COMMON_NAME}/$COMMON_NAME/) > server.pem
63
+ ```
64
+
65
+ NOTE: you may need change openssl.conf to point to your local path, eg. /System/Library/OpenSSL/openssl.cnf
66
+
67
+ ```
68
+ kubectl create secret tls demoapp-puma-tls --key server.key --cert server.pem
69
+ ```
70
+
71
+ ## Add Helm Chart Repository
72
+
73
+ We are going to need to install a couple of things on our local cluster. For this we need to install charts from the Helm stable chart repository.
74
+
75
+ One off installation of the repository:
76
+ ```
77
+ helm repo add stable https://kubernetes-charts.storage.googleapis.com
78
+ ```
79
+
80
+ ## Install NFS
81
+
82
+ To run locally and use NFS file mounts we'll need an NFS server:
83
+
84
+ Helm install to run the nfs server on kubernetes:
85
+ ```
86
+ helm install stable/nfs-server-provisioner --generate-name
87
+ ```
88
+
89
+ NOTE: you can substitute --generate-name with --name followed by your chosen name for the resource
90
+
91
+ NOTE: stop / remove it with helm uninstall {name} --namespace default
92
+
93
+ ### Ingress
94
+
95
+ To run locally we'll need an Ingress controller - this provides us with the ability to access the application on the web:
96
+
97
+ Helm install to run the ingress controller on kubernetes:
98
+ ```
99
+ helm install stable/nginx-ingress --generate-name
100
+ ```
101
+
102
+ NOTE: you can substitute --generate-name with --name followed by your chosen name for the resource
103
+
104
+ NOTE: stop / remove it with helm uninstall {name} --namespace default
105
+
106
+ ## Values
107
+
108
+ When deploying the Helm chart we will provide a yaml file containing various configurations choices.
109
+
110
+ A sample values file is provided to give defaults: `sample.yaml`. Copy this file (eg. to development-values.yamnl) and change values as appropriate.
111
+
112
+ **Handling values files**
113
+
114
+ Since values files are likely to contain sensitive information like API keys, they are included in `.gitignore` and MUST NOT be added to the repository. Encrypt the file before committing them to the repository, using the provided bin scripts in this directory.
115
+
116
+ Example workflow (given values file is already created):
117
+ - Edit values file
118
+ - `chart/bin/encrypt staging <keybase-team-name>`
119
+ - This command will create `staging-values.yaml.enc`
120
+ - `git add staging-values.yaml.enc`
121
+ - Commit and push
122
+
123
+ When pulling down a repo or branch, you will need to start by decrypting.
124
+
125
+ Example:
126
+ - `chart/bin/decrypt staging`
127
+
128
+ ## Deploy using Helm
129
+
130
+ From ./chart/
131
+
132
+ ```
133
+ ./bin/deploy development latest
134
+ ```
135
+
136
+ Open demoapp in browser
137
+ ```
138
+ open locaallhost
139
+ ```
140
+
141
+ ## Cleanup
142
+ helm uninstall development --namespace REPO_NAME
143
+
144
+ eg. `helm uninstall development --namespace project-env`
145
+
146
+ Tip: add the --dry-run to see what will be deleted
147
+
148
+ ## Kubernetes Dashboard
149
+
150
+ Kubernetes provides a web-based dashboard for viewing and managing the deployed resources.
151
+
152
+ # Install it:
153
+ ```
154
+ helm install stable/kubernetes-dashboard --generate-name
155
+ ```
156
+
157
+ Make a note of the start command printed on install. It includes the release name (eg. kubernetes-dashboard-1579333192).
158
+
159
+ Tip: You can replace --generate-name with --name and supply a name for the release to give you a stable name.
160
+
161
+ Start it:
162
+ ```
163
+ (RELEASE_NAME will be the value from your installation - find it with helm ls)
164
+
165
+ export POD_NAME=$(kubectl get pods -n default -l "app=kubernetes-dashboard,release=RELEASE_NAME" -o jsonpath="{.items[0].metadata.name}")
166
+ echo https://127.0.0.1:8443/
167
+ kubectl -n default port-forward $POD_NAME 8443:8443
168
+ ```
169
+
170
+ Open it:
171
+ ```
172
+ https://127.0.0.1:8443/
173
+ ```
174
+
175
+ It will ask you to login by one of two methods. Opt for 'access token'.
176
+
177
+ Print your access token in a console as follwos, and then copy paste it into the token box on the dashboard login:
178
+ ```
179
+ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | awk '/^deployment-controller-token-/{print $1}') | awk '$1=="token:"{print $2}'
180
+ ```
181
+
182
+ # Deploying to Staging and Production clusters
183
+
184
+ Staging and Production deployment require the following steps:
185
+
186
+ 1. Add the necessary kube config for your remote cluster
187
+
188
+ 2. Switch kubernetes context
189
+
190
+ Either using the list in DfM Kubernetes, or with the following:
191
+
192
+ ```
193
+ # check the current context
194
+ kubectl config current-context
195
+ # find the context you want in the list
196
+ kubectl config get-contexts
197
+ # switch
198
+ kubectl config use-context CONTEXT_NAME
199
+ ```
200
+
201
+ 3. Setup the *-values.yaml for staging or production
202
+
203
+ 4. Deploy
204
+
205
+ ```
206
+ # bin/deploy ENVIRONMENT TAG
207
+ bin/deploy staging latest
208
+ ```
209
+
210
+ NOTE: the TAG will be used to pull the latest image from the GitLab repository. If the code has changed, make sure it's been pushed and the tagged image in the repository updated.
211
+
212
+ The namespace will be set to the git repository name, eg. project-env. Make sure the namespace exists in your cluster. Create it with `kubectl create namespace project-env`
213
+
214
+ # Troubleshooting
215
+
216
+ The Kubernetes Dashboard (locally) allows you to view logs and access a shell session. If problems occur during deployment, there is an event history that can provide more information.
217
+
218
+ There are equivalent kubectl commands for logs and accessing a shell, eg.
219
+
220
+ ```
221
+ kubectl kubectl exec -it POD --namespace NAMESPACE -- /bin/bash
222
+ kubectl kubectl logs POD --namespace NAMESPACE
223
+ ```
File without changes
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
3
+ cd $DIR/../../chart
4
+
5
+ echo $DIR
6
+
7
+ REPO=$(basename $(git config --get remote.origin.url))
8
+ NAMESPACE=${REPO%.git}
9
+
10
+ if [ -z "$1" ]
11
+ then
12
+ echo './chart/bin/decrypt ENVIRONMENT'
13
+ exit 1
14
+ fi
15
+
16
+ keybase decrypt -i $1-values.yaml.enc -o $1-values.yaml
17
+