-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🧁feat: added the static site chart 🧁 (#24)
🧁 Created a deploy engine for deploying static site onto a Kubernetes cluster with auto-updating capabilities 🧁
- Loading branch information
Showing
10 changed files
with
563 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
apiVersion: v2 | ||
name: static-site | ||
description: A Helm chart for deploying a static-site with auto-updating | ||
type: application | ||
version: 0.0.3 | ||
appVersion: 1.17.9-alpine | ||
home: https://github.com/rht-labs/helm-charts | ||
maintainers: | ||
- name: jijiechen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
## 在 Kubernetes 上部署的可自动更新的静态网站 | ||
|
||
此项目包含一个 helm chart,它支持向 Kubernetes 部署一个静态网站,并根据 Git 仓库中的最新变更,自动更新网站。 | ||
|
||
### 用法 | ||
|
||
```sh | ||
helm install my-cool-site ./ --set "repo.location=https://git-location-of-your-static-site" | ||
``` | ||
|
||
### 支持的 Helm 设置项 | ||
|
||
下表列出了这个 Helm Chart 所支持的各项设置及其默认值: | ||
|
||
| 参数 | 描述 | 默认值 | 是否必填 | | ||
| -------------------- | ------------------------------------------------- | --------------- | ----------------- | | ||
| `repo.location` | 存储静态网站源代码的 Git 仓库地址的 HTTP(s) 地址 | | 是 | | ||
| `repo.branch` | 要部署的分支名称 | `master` | 否 | | ||
| `repo.credential.username` | Git 仓库的用户名 | | 否 | | ||
| `repo.credential.password` | Git 仓库的密码 | | 否 | | ||
| `site.enableDirectoryListing` | 是否启用目录浏览功能 | `false` | 否 | | ||
| `replicas` | 部署时,要生成的副本数目 | `2` | 否 | | ||
| `autoUpdateCron` | 用以设定检测自动更新频率的 CRON 表达式 | `* * * * *`, 即每分钟检查 | 否 | | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
[查看中文说明文档](README-zh.md) | ||
|
||
## Static Site Deployment with Automatic Updating on Kubernetes | ||
|
||
This is a helm chart supporting deploying a static website onto Kubernetes and enable auto-polling to its Git repository. | ||
|
||
### Usage | ||
|
||
```sh | ||
helm install my-cool-site ./ --set "repo.location=https://git-location-of-your-static-site" | ||
``` | ||
|
||
### Supported Helm Settings | ||
|
||
The following table lists the settings of the chart and their default values. | ||
|
||
| Parameter | Description | Default | Required | | ||
| -------------------- | ---------------------------------------------------------- | --------------- | ----------------- | | ||
| `repo.location` | HTTP(s) based URL of your git repository that stores source of the site | | Y | | ||
| `repo.branch` | Name of git branch you want to deploy | `master` | N | | ||
| `repo.credential.username` | Username to of the git repository | | N | | ||
| `repo.credential.password` | Password to of the git repository | | N | | ||
| `site.enableDirectoryListing` | Whether enable directory listing for the site | `false` | N | | ||
| `replicas` | Number of replicas of the deployment | `2` | N | | ||
| `autoUpdateCron` | The CRON expression scheduling the auto update polling job | `* * * * *`, which means every minute | N | | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM alpine/git:v2.24.1 | ||
RUN apk add --no-cache curl | ||
|
||
ENTRYPOINT ["/bin/sh"] | ||
|
||
# docker build . -f ./alpine-curl-git.Dockerfile -t jijiechen/alpine-curl-git:v2.24.1 | ||
# https://hub.docker.com/r/jijiechen/alpine-curl-git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
|
||
{{/* | ||
Return the proper Storage Class | ||
*/}} | ||
{{- define "tmpl.storageClass" -}} | ||
{{- if .Values.persistence.storage.storageClass -}} | ||
{{- if (eq "-" .Values.persistence.storage.storageClass) -}} | ||
{{- printf "storageClassName: \"\"" -}} | ||
{{- else }} | ||
{{- printf "storageClassName: %s" .Values.persistence.storage.storageClass -}} | ||
{{- end -}} | ||
{{- end -}} | ||
{{- end -}} | ||
|
||
|
||
{{/* | ||
Return the template of poller/updater pod | ||
*/}} | ||
{{- define "tmpl.pollerPodSpec" -}} | ||
restartPolicy: Never | ||
serviceAccountName: {{ .Release.Name }}-redeployer | ||
volumes: | ||
- name: poller-script | ||
configMap: | ||
name: static-site-{{ .Release.Name }}-poller-script | ||
defaultMode: 0777 | ||
containers: | ||
- name: poller | ||
image: jijiechen/alpine-curl-git:v2.24.1 | ||
imagePullPolicy: IfNotPresent | ||
volumeMounts: | ||
- mountPath: /var/poller/ | ||
name: poller-script | ||
command: ["/bin/sh"] | ||
args: | ||
- /var/poller/poll.sh | ||
env: | ||
- name: REPO_URL | ||
value: {{ .Values.repo.location }} | ||
- name: BRANCH | ||
value: {{ .Values.repo.branch }} | ||
resources: | ||
limits: | ||
cpu: 200m | ||
memory: "200Mi" | ||
requests: | ||
cpu: 50m | ||
memory: "100Mi" | ||
{{- end -}} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: static-site-{{ .Release.Name }}-config | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
data: | ||
nginx.conf: | | ||
user nginx; | ||
worker_processes auto; | ||
error_log /tmp/log/nginx/error.log warn; | ||
pid /tmp/nginx.pid; | ||
events { | ||
worker_connections 1024; | ||
} | ||
http { | ||
include /etc/nginx/mime.types; | ||
default_type application/octet-stream; | ||
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' | ||
'$status $body_bytes_sent "$http_referer" ' | ||
'"$http_user_agent" "$http_x_forwarded_for"'; | ||
access_log /tmp/log/nginx/access.log main; | ||
client_body_temp_path /tmp/client_temp; | ||
proxy_temp_path /tmp/proxy_temp_path; | ||
fastcgi_temp_path /tmp/fastcgi_temp; | ||
uwsgi_temp_path /tmp/uwsgi_temp; | ||
scgi_temp_path /tmp/scgi_temp; | ||
sendfile on; | ||
#tcp_nopush on; | ||
keepalive_timeout 65; | ||
gzip on; | ||
include /etc/nginx/conf.d/*.conf; | ||
} | ||
default.conf: | | ||
server { | ||
listen 8080; | ||
server_name localhost; | ||
#charset koi8-r; | ||
#access_log /var/log/nginx/host.access.log main; | ||
location / { | ||
absolute_redirect off; | ||
{{- if .Values.site.enableDirectoryListing }} | ||
autoindex on; | ||
{{- end }} | ||
root /usr/share/nginx/html; | ||
index index.html index.htm; | ||
} | ||
#error_page 404 /404.html; | ||
# redirect server error pages to the static page /50x.html | ||
# | ||
error_page 500 502 503 504 /50x.html; | ||
location = /50x.html { | ||
root /usr/share/nginx/html; | ||
} | ||
# proxy the PHP scripts to Apache listening on 127.0.0.1:80 | ||
# | ||
#location ~ \.php$ { | ||
# proxy_pass http://127.0.0.1; | ||
#} | ||
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 | ||
# | ||
#location ~ \.php$ { | ||
# root html; | ||
# fastcgi_pass 127.0.0.1:9000; | ||
# fastcgi_index index.php; | ||
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; | ||
# include fastcgi_params; | ||
#} | ||
# deny access to .htaccess files, if Apache's document root | ||
# concurs with nginx's one | ||
# | ||
#location ~ /\.ht { | ||
# deny all; | ||
#} | ||
} | ||
clone.sh: | | ||
#!/bin/sh | ||
set -e | ||
REPO_URL='{{ .Values.repo.location }}' | ||
{{- if and .Values.repo.credential.username .Values.repo.credential.password }} | ||
echo 'exec echo $GIT_PASSWORD' > /tmp/git-askpass.sh | ||
chmod +x /tmp/git-askpass.sh | ||
export GIT_ASKPASS=/tmp/git-askpass.sh | ||
if [ ! -z "${REPO_URL##*@*}" ] ; then | ||
REPO_URL=$(echo $REPO_URL | sed 's;//;//{{ .Values.repo.credential.username }}@;') | ||
fi | ||
{{- end }} | ||
INSIDE_TREE=$(git rev-parse --is-inside-work-tree 2>/dev/null || true) | ||
if [ -z "$INSIDE_TREE" ]; then | ||
git init . | ||
fi | ||
git config remote.origin.url $REPO_URL | ||
BRANCH={{ .Values.repo.branch }} | ||
CURRENT=$(git rev-parse --verify HEAD 2>/dev/null || true) | ||
if [ "$CURRENT" != "$GIT_REVISION" ]; then | ||
git fetch --no-tags --progress -- $REPO_URL +refs/heads/$BRANCH:refs/remotes/origin/$BRANCH | ||
git config advice.detachedHead false | ||
git checkout -f $GIT_REVISION | ||
git branch -D $BRANCH 2>/dev/null || true | ||
git checkout -b $BRANCH $GIT_REVISION | ||
fi | ||
git reset --hard | ||
git clean -fdx | ||
# Running at /source | ||
cp -R ./ /website | ||
rm -rf /website/.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
{{- if .Values.autoUpdateCron }} | ||
|
||
apiVersion: batch/v1beta1 | ||
kind: CronJob | ||
metadata: | ||
name: static-site-{{ .Release.Name }}-poller | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
spec: | ||
schedule: "{{ .Values.autoUpdateCron }}" | ||
concurrencyPolicy: Forbid | ||
successfulJobsHistoryLimit: 1 | ||
failedJobsHistoryLimit: 1 | ||
jobTemplate: | ||
spec: | ||
backoffLimit: 0 | ||
template: | ||
spec: | ||
{{ include "tmpl.pollerPodSpec" . | indent 10 }} | ||
|
||
--- | ||
{{- end }} | ||
|
||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: static-site-{{ .Release.Name }}-poller-script | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
data: | ||
poll.sh: |- | ||
#!/bin/sh | ||
set -e | ||
if [ -z "$REPO_URL" ]; then | ||
exit 0 | ||
fi | ||
K8S_URL=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS | ||
NAMESPACE=$(cat /run/secrets/kubernetes.io/serviceaccount/namespace) | ||
TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token) | ||
CACERT=/run/secrets/kubernetes.io/serviceaccount/ca.crt | ||
{{- if .Values.persistence.enabled }} | ||
RES_TYPE=statefulset | ||
{{- else }} | ||
RES_TYPE=deployment | ||
{{- end }} | ||
CURRENT=$(curl --cacert $CACERT -H "Authorization: Bearer $TOKEN" $K8S_URL/apis/apps/v1/namespaces/$NAMESPACE/${RES_TYPE}s/static-site-{{ .Release.Name }} 2>/dev/null | grep '"git_revision"' | tail -n 1 | cut -f 4 -d '"') | ||
LATEST=$(git ls-remote $REPO_URL | grep refs/heads/$BRANCH | awk '{print $1}') | ||
if [ "$LATEST" != "$CURRENT" ] ; then | ||
echo "Redeploying static-site-{{ .Release.Name }}: the current ${RES_TYPE} $CURRENT has expired, as the latest revision is $LATEST" | ||
PATCH_REPLICA= | ||
if [ "$CURRENT" = "pending-init" ]; then | ||
PATCH_REPLICA='"replicas": {{ .Values.replicas }},' | ||
fi | ||
PATCH="{\"spec\": { $PATCH_REPLICA \"template\": {\"metadata\": { \"labels\": { \"git_revision\": \"$LATEST\"}}}}}" | ||
curl --cacert $CACERT -X PATCH -H "Authorization: Bearer $TOKEN" \ | ||
-H 'Content-Type: application/strategic-merge-patch+json' --data "$PATCH" \ | ||
$K8S_URL/apis/apps/v1/namespaces/$NAMESPACE/${RES_TYPE}s/static-site-{{ .Release.Name }} | ||
else | ||
echo "No change: static-site-{{ .Release.Name }} stayed the same as current ${RES_TYPE} $CURRENT" | ||
fi | ||
--- | ||
|
||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: {{ .Release.Name }}-redeployer | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
|
||
--- | ||
|
||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: Role | ||
metadata: | ||
name: {{ .Release.Name }}-static-site-updater | ||
rules: | ||
- apiGroups: ["extensions", "apps"] | ||
resources: ["deployments", "statefulsets"] | ||
verbs: ["get", "patch"] | ||
|
||
--- | ||
|
||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: RoleBinding | ||
metadata: | ||
name: {{ .Release.Name }}_redeployer | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: Role | ||
name: {{ .Release.Name }}-static-site-updater | ||
subjects: | ||
- kind: ServiceAccount | ||
name: {{ .Release.Name }}-redeployer | ||
|
||
|
||
--- | ||
|
||
apiVersion: batch/v1 | ||
kind: Job | ||
metadata: | ||
name: static-site-{{ .Release.Name }}-first-poller | ||
labels: | ||
app: static-site | ||
site: {{ .Release.Name }} | ||
annotations: | ||
helm.sh/hook: post-install | ||
helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" | ||
spec: | ||
activeDeadlineSeconds: 600 | ||
completions: 1 | ||
parallelism: 1 | ||
template: | ||
spec: | ||
{{ include "tmpl.pollerPodSpec" . | indent 6 }} |
Oops, something went wrong.