[skip-ci] WIP Add docker image

Add website-build-deployment and cron skeleton.
Add shadow-cljs.edn - needs config for cljs.
This commit is contained in:
erik 2022-09-23 15:39:17 +02:00
parent a21c2a4957
commit 76f5b87ec9
14 changed files with 274 additions and 38 deletions

View file

@ -2,10 +2,6 @@
## Requirements ## Requirements
Unsere Website soll mit k8s laufen.
Unsere erzeugten images incl. Web-Inhalt sollen nicht öffentlich zugänglich sein.
A.C.: A.C.:
wir haben ein konzept erstellt, wie wir statische Inhalte ausliefern (git-pull & cron // cicid // manueller pybuilder-run). wir haben ein konzept erstellt, wie wir statische Inhalte ausliefern (git-pull & cron // cicid // manueller pybuilder-run).
@ -15,33 +11,18 @@ A.C.:
c4k holt sich stets die neuesten website-container unterbrechungsfrei. c4k holt sich stets die neuesten website-container unterbrechungsfrei.
unsere website läuft mit dem neuen setup und ist unter ipv4 und ipv6 erreichbar. Unsere website läuft mit dem neuen Setup, ist unter ipv4/v6 und unter 1 oder 2 FQDNs erreichbar.
website ist unter 1 oder 2 fqdns erreichbar.
## Was passiert? ## Was passiert?
_Frage_ Sollen später Webserver auf den gleichen, laufenden Cluster hinzugefügt werden können? Webserver sollen auf den gleichen, laufenden Cluster hinzugefügt werden können.
**Ja:** **c4k**
Pro Website je: Ingress -> Service -> Webserver Pod -> Volume Mount -> PVC.
Ein Cluster, 1 Pod für eine Website (WS) Ingress muss die angefragten FQDNS auflösen und weiterleiten.
-> mehrere FQDNs müssen auf einen Cluster Zeigen
-> viele Pods für viele WS
-> Package einen Webserver mit einer Website
-> DNS Routen so einrichten, dass verschiedene FQDNs auf selbe cluster-id zeigen
-> Ingress muss die angefragten FQDNS auflösen und weiterleiten
Anforderungen an Website-Container:
nginx-deployment
nginx-config -> wie
serviceType: LoadBalancer
PVC + volume-mount zeigt auf website-data-vol
**Terraform:** **Terraform:**
FQDNs für verschiedene Websites hinzufügen? Mehrere DNS Einträge auf Terraform Seite für einen Cluster.
Verbindung mit c4k?
c4k-Modulname als Teil des FQDNs wird später noch problematisch.
### Reading: ### Reading:
@ -54,20 +35,14 @@ Deploying Nginx:
https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/ https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/
https://www.tecmint.com/deploy-nginx-on-a-kubernetes-cluster/ https://www.tecmint.com/deploy-nginx-on-a-kubernetes-cluster/
##
Definition von Env-Vars im Deployment:
AUTHTOKEN - muss konfigurierbar sein
REPOZIPURL - muss konfigurierbar sein
TARGETDIR - wird aus dem FQDN zusammengesetzt
## Struktur Ingress, Service, Certificate, Deployment, Configmap und Volume Mount sollen durch eindeutige, auf FQDN basierenden Namen verbunden sein.
1. Baue die statische website
2. Schieb die Website auf den Server
3. Liefere die Website mit einem Webserver aus
## Fragen
Soll Cryogen auch in einem container laufen?
## Getting started ## Getting started

View file

@ -0,0 +1,51 @@
from os import environ
from pybuilder.core import task, init
from ddadevops import *
import logging
name = 'c4k-website-build'
MODULE = 'docker'
PROJECT_ROOT_PATH = '../..'
class MyBuild(DevopsDockerBuild):
pass
@init
def initialize(project):
project.build_depends_on('ddadevops>=0.12.4')
stage = 'prod'
dockerhub_user = environ.get('DOCKERHUB_USER')
if not dockerhub_user:
dockerhub_user = gopass_field_from_path('meissa/web/docker.com', 'login')
dockerhub_password = environ.get('DOCKERHUB_PASSWORD')
if not dockerhub_password:
dockerhub_password = gopass_password_from_path('meissa/web/docker.com')
tag = environ.get('CI_COMMIT_TAG')
if not tag:
tag = get_tag_from_latest_commit()
config = create_devops_docker_build_config(
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password, docker_publish_tag=tag)
build = MyBuild(project, config)
build.initialize_build_dir()
@task
def image(project):
build = get_devops_build(project)
build.image()
@task
def drun(project):
build = get_devops_build(project)
build.drun()
@task
def publish(project):
build = get_devops_build(project)
build.dockerhub_login()
build.dockerhub_publish()
@task
def test(project):
build = get_devops_build(project)
build.test()

View file

@ -0,0 +1,9 @@
FROM clojure:temurin-18-jammy
# Prepare Entrypoint Script
ADD resources /tmp
ENV BUILDDIR="website"
RUN /tmp/install.sh
RUN /tmp/entrypoint.sh

View file

@ -0,0 +1,15 @@
#!/bin/bash
source /usr/local/bin/functions.sh
function main() {
get-and-unzip-website-data
build-and-extract-website
move-website-files-to-target
}
main
while true; do
sleep 1m
done

View file

@ -0,0 +1,2 @@
.git
.gitignore

View file

@ -0,0 +1,18 @@
#!/bin/bash
# "Authorization: token YOURAUTHTOKEN"
function get-and-unzip-website-data() {
curl -H "$AUTHTOKEN" -O $REPOZIPURL # REPOZIPURL = https://your.gitea.host/api/v1/repos/<owner>/<repo>/archive/main.zip
mkdir $BUILDDIR
unzip main.zip -D $BUILDDIR
}
function build-and-extract-website() {
(cd $BUILDDIR; lein ring war; websiteartifactname=$(ls | grep -o *.war); unzip target/$websiteartifactname "WEB-INF/classes/public/*")
}
# set variables from environment
# read write zugriff sicherstellen
function move-website-files-to-target() {
rsync -ru --exclude-from "/home/$USER/exclude.pattern" --delete WEB-INF/classes/public/* $TARGETDIR # TARGETDIR = mount/path/to/website-content-vol with write permission
}

View file

@ -0,0 +1,10 @@
#!/bin/bash
apt update > /dev/null;
install -m 0700 /tmp/entrypoint.sh /
install -m 0700 /tmp/functions.sh /usr/local/bin/
install -m 0700 /tmp/exclude.pattern /home/$USER
install -m 0700 /tmp/project.clj /home/$USER/.lein/
(cd /home/$USER/.lein; lein deps)

View file

@ -0,0 +1,2 @@
{:user
{:plugins [[lein-ring "0.12.5"]]}}

View file

@ -0,0 +1,11 @@
FROM c4k-jira-backup
RUN apt update
RUN apt -yqq --no-install-recommends --yes install curl default-jre-headless
RUN curl -L -o /tmp/serverspec.jar \
https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar
COPY serverspec.edn /tmp/serverspec.edn
RUN java -jar /tmp/serverspec.jar /tmp/serverspec.edn -v

View file

@ -0,0 +1,5 @@
{:file [{:path "/usr/local/bin/install.sh" :mod "700"}
{:path "/usr/local/bin/functions.sh" :mod "700"}
{:path "/usr/local/bin/exclude.pattern" :mod "700"}
{:path "/usr/local/bin/project.clj" :mod "700"}
{:path "/entrypoint.sh" :mod "700"}]}

16
shadow-cljs.edn Normal file
View file

@ -0,0 +1,16 @@
{:source-paths ["src/main/cljc"
"src/main/cljs"
"src/main/resources"
"src/test/cljc"
"src/test/cljs"
"src/test/resources"]
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "3.0.1"]
[hickory "0.7.1"]
[org.clojure/math.numeric-tower "0.0.5"]]
:builds {:frontend {:target :browser
:modules {:main {:init-fn dda.c4k-website.browser/init}}
:release {}
:compiler-options {:optimizations :advanced}}
:test {:target :node-test
:output-to "target/node-tests.js"
:repl-pprint true}}}

View file

@ -95,5 +95,7 @@ data:
root /var/www/html/website/; root /var/www/html/website/;
# root /usr/share/nginx/html/; # testing purposes # root /usr/share/nginx/html/; # testing purposes
index index.html; index index.html;
try_files $uri /index.html; location / {
try_files $uri $uri/ /index.html =404;
}
} }

View file

@ -0,0 +1,47 @@
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: website-builder
labels:
app.kubernetes.part-of: website # correct name?
spec:
schedule: "10 23 * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: backup-app
image: domaindrivenarchitecture/c4k-gitea-backup
imagePullPolicy: IfNotPresent
command: ["/entrypoint.sh"]
env:
- name: AWS_DEFAULT_REGION
value: eu-central-1
- name: AWS_ACCESS_KEY_ID_FILE
value: /var/run/secrets/backup-secrets/aws-access-key-id
- name: AWS_SECRET_ACCESS_KEY_FILE
value: /var/run/secrets/backup-secrets/aws-secret-access-key
- name: RESTIC_REPOSITORY
valueFrom:
configMapKeyRef:
name: backup-config
key: restic-repository
- name: RESTIC_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-password
volumeMounts:
- name: gitea-data-volume
mountPath: /var/backups
- name: backup-secret-volume
mountPath: /var/run/secrets/backup-secrets
readOnly: true
volumes:
- name: gitea-data-volume
persistentVolumeClaim:
claimName: gitea-data-pvc
- name: backup-secret-volume
secret:
secretName: backup-secret
restartPolicy: OnFailure

View file

@ -0,0 +1,73 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backup-restore
spec:
replicas: 0
selector:
matchLabels:
app: backup-restore
strategy:
type: Recreate
template:
metadata:
labels:
app: backup-restore
app.kubernetes.io/name: backup-restore
app.kubernetes.io/part-of: gitea
spec:
containers:
- image: domaindrivenarchitecture/c4k-gitea-backup
name: backup-app
imagePullPolicy: IfNotPresent
command: ["/entrypoint-start-and-wait.sh"]
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: postgres-user
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: postgres-password
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: postgres-config
key: postgres-db
- name: POSTGRES_HOST
value: "postgresql-service:5432"
- name: POSTGRES_SERVICE
value: "postgresql-service"
- name: POSTGRES_PORT
value: "5432"
- name: AWS_DEFAULT_REGION
value: eu-central-1
- name: AWS_ACCESS_KEY_ID_FILE
value: /var/run/secrets/backup-secrets/aws-access-key-id
- name: AWS_SECRET_ACCESS_KEY_FILE
value: /var/run/secrets/backup-secrets/aws-secret-access-key
- name: RESTIC_REPOSITORY
valueFrom:
configMapKeyRef:
name: backup-config
key: restic-repository
- name: RESTIC_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-password
- name: CERTIFICATE_FILE
value: ""
volumeMounts:
- name: gitea-data-volume
mountPath: /var/backups
- name: backup-secret-volume
mountPath: /var/run/secrets/backup-secrets
readOnly: true
volumes:
- name: gitea-data-volume
persistentVolumeClaim:
claimName: gitea-data-pvc
- name: backup-secret-volume
secret:
secretName: backup-secret