├── static.json ├── .buildpacks ├── Dockerfile ├── helm └── website │ ├── Chart.yaml │ ├── .helmignore │ ├── templates │ ├── tests │ │ └── test-connection.yaml │ ├── service.yaml │ ├── ingress.yaml │ ├── NOTES.txt │ ├── _helpers.tpl │ └── deployment.yaml │ └── values.yaml ├── README.md ├── kubernetes.yml └── public_html ├── index.html └── .well-known └── keybase.txt /static.json: -------------------------------------------------------------------------------- 1 | { 2 | "clean_urls": true 3 | } -------------------------------------------------------------------------------- /.buildpacks: -------------------------------------------------------------------------------- 1 | https://github.com/heroku/heroku-buildpack-static 2 | 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:alpine 2 | 3 | COPY public_html /usr/share/nginx/html 4 | -------------------------------------------------------------------------------- /helm/website/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: Ben Jeffrey's personal website 4 | name: website 5 | version: 0.1.0 6 | sources: 7 | - https://github.com/jeffbr13/website 8 | maintainers: 9 | - name: Ben Jeffrey 10 | email: website@jeffbr13.net 11 | url: http://jeffbr13.net 12 | -------------------------------------------------------------------------------- /helm/website/.helmignore: -------------------------------------------------------------------------------- 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 | .vscode/ 23 | -------------------------------------------------------------------------------- /helm/website/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "website.fullname" . }}-test-connection" 5 | labels: 6 | {{ include "website.labels" . | indent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "website.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /helm/website/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "website.fullname" . }} 5 | labels: 6 | {{ include "website.labels" . | indent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | app.kubernetes.io/name: {{ include "website.name" . }} 16 | app.kubernetes.io/instance: {{ .Release.Name }} 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | website 2 | ======= 3 | 4 | Deployment 5 | ---------- 6 | 7 | ### Kubernetes via Helm 8 | 9 | Check [values.yaml](./helm/website/values.yaml) for full list of settings: 10 | 11 | ```bash 12 | cd helm 13 | helm install website \ 14 | # use NodePort for minikube, ClusterIP for ingress-nginx, otherwise LoadBalancer 15 | --set service.type=NodePort 16 | ``` 17 | 18 | For production use with an existing `ingress-nginx` configuration: 19 | 20 | ```bash 21 | helm install website \ 22 | --set ingress.enabled=true \ 23 | --set ingress.hosts="{my.host.name,}" 24 | ``` 25 | -------------------------------------------------------------------------------- /helm/website/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "website.fullname" . -}} 3 | apiVersion: extensions/v1beta1 4 | kind: Ingress 5 | metadata: 6 | name: {{ $fullName }} 7 | labels: 8 | {{ include "website.labels" . | indent 4 }} 9 | {{- with .Values.ingress.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | spec: 14 | {{- if .Values.ingress.tls }} 15 | tls: 16 | {{- range .Values.ingress.tls }} 17 | - hosts: 18 | {{- range .hosts }} 19 | - {{ . | quote }} 20 | {{- end }} 21 | secretName: {{ .secretName }} 22 | {{- end }} 23 | {{- end }} 24 | rules: 25 | {{- range .Values.ingress.hosts }} 26 | - host: {{ .host | quote }} 27 | http: 28 | paths: 29 | {{- range .paths }} 30 | - path: {{ . }} 31 | backend: 32 | serviceName: {{ $fullName }} 33 | servicePort: http 34 | {{- end }} 35 | {{- end }} 36 | {{- end }} 37 | -------------------------------------------------------------------------------- /helm/website/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for website. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: jeffbr13/website 9 | tag: latest 10 | pullPolicy: Always 11 | 12 | imagePullSecrets: [] 13 | nameOverride: "" 14 | fullnameOverride: "" 15 | 16 | service: 17 | type: ClusterIP 18 | port: 80 19 | 20 | ingress: 21 | enabled: true 22 | annotations: {} 23 | # kubernetes.io/ingress.class: nginx 24 | # kubernetes.io/tls-acme: "true" 25 | hosts: 26 | - host: benjeffrey.net 27 | paths: ["/"] 28 | 29 | tls: [] 30 | # - secretName: chart-example-tls 31 | # hosts: 32 | # - chart-example.local 33 | 34 | resources: {} 35 | # We usually recommend not to specify default resources and to leave this as a conscious 36 | # choice for the user. This also increases chances charts run on environments with little 37 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 38 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 39 | # limits: 40 | # cpu: 100m 41 | # memory: 128Mi 42 | # requests: 43 | # cpu: 100m 44 | # memory: 128Mi 45 | 46 | nodeSelector: {} 47 | 48 | tolerations: [] 49 | 50 | affinity: {} 51 | -------------------------------------------------------------------------------- /kubernetes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 3 | kind: Deployment 4 | metadata: 5 | name: website-deployment 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: website 10 | replicas: 1 # tells deployment to run 1 pod matching the template 11 | template: # create pods using pod definition in this template 12 | metadata: 13 | # unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is 14 | # generated from the deployment name 15 | labels: 16 | app: website 17 | spec: 18 | containers: 19 | - name: website 20 | image: jeffbr13/website 21 | ports: 22 | - containerPort: 80 23 | 24 | --- 25 | kind: Service 26 | apiVersion: v1 27 | metadata: 28 | name: website-service 29 | spec: 30 | selector: 31 | app: website 32 | ports: 33 | - protocol: TCP 34 | port: 80 35 | targetPort: 80 # this doesn't really matter 36 | 37 | --- 38 | apiVersion: extensions/v1beta1 39 | kind: Ingress 40 | metadata: 41 | name: website-ingress 42 | annotations: 43 | kubernetes.io/ingress.class: "nginx" 44 | spec: 45 | rules: 46 | - host: jeffbr13.net 47 | http: 48 | paths: 49 | - path: 50 | backend: 51 | serviceName: website-service 52 | servicePort: 80 53 | tls: 54 | - secretName: website-tls-cert 55 | hosts: 56 | - jeffbr13.net 57 | -------------------------------------------------------------------------------- /helm/website/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "website.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "website.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "website.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "website.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /helm/website/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "website.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 "website.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 chart name and version as used by the chart label. 29 | */}} 30 | {{- define "website.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "website.labels" -}} 38 | app.kubernetes.io/name: {{ include "website.name" . }} 39 | helm.sh/chart: {{ include "website.chart" . }} 40 | app.kubernetes.io/instance: {{ .Release.Name }} 41 | {{- if .Chart.AppVersion }} 42 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 43 | {{- end }} 44 | app.kubernetes.io/managed-by: {{ .Release.Service }} 45 | {{- end -}} 46 | -------------------------------------------------------------------------------- /helm/website/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "website.fullname" . }} 5 | labels: 6 | {{ include "website.labels" . | indent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app.kubernetes.io/name: {{ include "website.name" . }} 12 | app.kubernetes.io/instance: {{ .Release.Name }} 13 | template: 14 | metadata: 15 | labels: 16 | app.kubernetes.io/name: {{ include "website.name" . }} 17 | app.kubernetes.io/instance: {{ .Release.Name }} 18 | spec: 19 | {{- with .Values.imagePullSecrets }} 20 | imagePullSecrets: 21 | {{- toYaml . | nindent 8 }} 22 | {{- end }} 23 | containers: 24 | - name: {{ .Chart.Name }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | ports: 28 | - name: http 29 | containerPort: 80 30 | protocol: TCP 31 | livenessProbe: 32 | httpGet: 33 | path: / 34 | port: http 35 | readinessProbe: 36 | httpGet: 37 | path: / 38 | port: http 39 | resources: 40 | {{- toYaml .Values.resources | nindent 12 }} 41 | {{- with .Values.nodeSelector }} 42 | nodeSelector: 43 | {{- toYaml . | nindent 8 }} 44 | {{- end }} 45 | {{- with .Values.affinity }} 46 | affinity: 47 | {{- toYaml . | nindent 8 }} 48 | {{- end }} 49 | {{- with .Values.tolerations }} 50 | tolerations: 51 | {{- toYaml . | nindent 8 }} 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /public_html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ben Jeffrey 6 | 7 | 8 | 24 | 25 | 26 | 34 | 35 | 42 | 43 | 44 |
45 |

46 | 47 | Ben Jeffrey 48 |

49 |

Also known as jeffbr13. Backend web developer. I like music.

50 | 51 |
52 | 67 |
68 |

Projects

69 | 75 |
76 | 77 | 78 | -------------------------------------------------------------------------------- /public_html/.well-known/keybase.txt: -------------------------------------------------------------------------------- 1 | ================================================================== 2 | https://keybase.io/jeffbr13 3 | -------------------------------------------------------------------- 4 | 5 | I hereby claim: 6 | 7 | * I am an admin of http://jeffbr13.net 8 | * I am jeffbr13 (https://keybase.io/jeffbr13) on keybase. 9 | * I have a public key with fingerprint 0669 41B3 7683 41FB 4120 7CEB 32DB C4B7 AEA7 3FB6 10 | 11 | To do so, I am signing this object: 12 | 13 | { 14 | "body": { 15 | "key": { 16 | "eldest_kid": "01014ba69f1d71795f10d35781b3372dbd01498b5a76c3cb18a67e88013b2726dc450a", 17 | "fingerprint": "066941b3768341fb41207ceb32dbc4b7aea73fb6", 18 | "host": "keybase.io", 19 | "key_id": "32dbc4b7aea73fb6", 20 | "kid": "01014ba69f1d71795f10d35781b3372dbd01498b5a76c3cb18a67e88013b2726dc450a", 21 | "uid": "606b9d77a6c230b0bbe4a737a41d7c00", 22 | "username": "jeffbr13" 23 | }, 24 | "service": { 25 | "hostname": "jeffbr13.net", 26 | "protocol": "http:" 27 | }, 28 | "type": "web_service_binding", 29 | "version": 1 30 | }, 31 | "ctime": 1509486578, 32 | "expire_in": 157680000, 33 | "prev": "06b37451851431af41b610f251dcf46c7905ff6176aeffb01c5124fe50f4edd1", 34 | "seqno": 20, 35 | "tag": "signature" 36 | } 37 | 38 | which yields the signature: 39 | 40 | -----BEGIN PGP MESSAGE----- 41 | Version: Keybase OpenPGP v2.0.76 42 | Comment: https://keybase.io/crypto 43 | 44 | yMM9AnicrZJtUFRVHMYXBGIXSN5U6IWBCxkIwj173/aukUOaVIhB4zRDAet9OReu 45 | C7vb7gVFBM3JccR4EWtihXRy2LEYEVJKmYyBgIGCRswaLNCYSWRtHDQKhV3SzmXq 46 | S9PHzpcz55zn+Z3//zlnIGSFRufTXneIuP5cSovPSN8HZZq8hbtzlRhvFSswYyVm 47 | hssTLBGhQzGZZREzYjjAAclzNCsBkQEMS0kAFwmKMQCeIBi9yIvonDXwFMfQAiHw 48 | wMDRDDQYcEDwekZPiwJJ4RyWgkmypQjabXbZoqhYmmZJhGBoA0ECiSeBHmcEyBOI 49 | KJA8w0GOISSeRsZiq0N1oOJ4zgFTZSvaQwvTcnn/of+f6y5bxtE4zbMiw3C0oCdw 50 | Hud5SKIbGY5EeAHHVaED2i1cKUTqnVCSeDsgsKoUDO2WywJUg1U7+Zci1QIV5LXZ 51 | rYpVsJagk2JFsRlVo1JhU5W7IG/6m2HiZYuIYkSGcmh3yFYLZgRIKSiyCgUUzpIG 52 | GvWYgsHdNtkOTbKqoFDIOBrqNbB8OXwUPEkBAwVIAnASegga4JKeAqIgkbTAsDgl 53 | STRgaE4tEwcCBfSkBClcIqEoAkzt6i2LFTPqEVThihDTIRdZOKXMDrGqr/ry/TQ+ 54 | Ok2Av6/6vzQ6beg/v25b28o/w/I3dc5FZT1/emxxf0PMs8SasKlr/QFNGdoVu7I6 55 | 60pDxpzOlzOX/tgTx2Y7b+N3osXJi71Ga/479cOfnc8pr+3gutjZ+KXzL+QNFZz5 56 | qOdSd33WTz86E6uTIoKmB7fPgfUlI2evXrjz25OfHN9d2LKY1Fg7lrZps+th3dod 57 | a26t2lLI4WyNX77Ru8fjOq7vHaBTi92K2ZwQP1F8096x6uSOczu3dXdND1EeQdku 58 | LkVv2fjU47rw4Rlv3oT2WzIunH7isaPfX36wOqh78IBf89758tHFs2/4tnk0vf37 59 | ergXucT5Y8kF3ivywahwc1r6qNdd+FLUoOfX9GJrepgdq7Z49yfrHfn+TRWvXGlK 60 | JqbHcxPubvBUrX4Uu9cVyXR6396XmXTbipnu50y13g+MZV8rmHbTrz7zuetjfVBt 61 | xY2FHtEZv+7gQfdagyc4sGaUKZyO69Ac7W3mUicOnOprz230nddpcwaMoQuRk+6c 62 | 6BnvteCG4ZFvKrUZ7rbSkdkj6x4+GP/C0rK1vXVG1xJxcmWzEjwe+t6JgK6tge9G 63 | HrOcCgjo/+73bENNTKJt6su6jnvO1F/ev3zoxtezJ8xHPs1ovnjhw4HUiMzqzY2j 64 | CblPu+6tr9BRyX0Nr7PaEBjbUB8mZf982L/zamnK5Jsbqn/YePqM7tL1gsNdMeda 65 | hx7dSouNdcXdbPgL0HK9Dg== 66 | =AgoT 67 | -----END PGP MESSAGE----- 68 | 69 | And finally, I am proving ownership of this host by posting or 70 | appending to this document. 71 | 72 | View my publicly-auditable identity here: https://keybase.io/jeffbr13 73 | 74 | ================================================================== 75 | --------------------------------------------------------------------------------