diff --git a/README.md b/README.md index 7989063..507d4d7 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,11 @@ ## Purpose -c4k-gitea provides a k8s deployment for gitea containing: +c4k-gitea provides a k8s deployment file for Gitea containing: * gitea * ingress having a letsencrypt managed certificate * postgres database -## Status - -Stable - we use this setup on production. ## Try out @@ -28,9 +25,14 @@ target/graalvm/c4k-gitea src/test/resources/valid-config.edn src/test/resources/ target/graalvm/c4k-gitea src/test/resources/valid-config.edn src/test/resources/valid-auth.edn | kubectl apply -f - ``` -## Documentation -* [Example Setup on Hetzner](doc/SetupOnHetzner.md) -* [Development](doc/Development.md) +## Gitea setup + +After having deployed the yaml-file generated by the c4k-gitea module you need to complete the setup for gitea: + +* Open the URL of your just deployed gitea-server and you will be shown a configuration page. +* Add the administrator's data and submit the page. +* The required database will be created and the Gitea setup will be completed. + ## License diff --git a/doc/Development.md b/doc/Development.md deleted file mode 100644 index 1740e9a..0000000 --- a/doc/Development.md +++ /dev/null @@ -1,110 +0,0 @@ -# Project Setup - -## clj setup - -### install leiningen -``` -sudo apt install leiningen -``` -or manually using Instructions on https://leiningen.org/#install - -### install vscode + extensions -``` -sudo snap install code -``` -or with packages from https://code.visualstudio.com/Download - -install extension "Calva: Clojure & ClojureScript Interactive Programming" - -## cljs / js-dev setup - -``` -sudo apt install npm -sudo npm install -g npx - -# maybe -sudo npm install -g shadow-cljs - -# in project root to retrieve all dependencies -npm install --ignore-scripts -npx shadow-cljs compile test -``` - -### create frontend script - -``` -npx shadow-cljs release frontend -``` - -## graalvm-setup - -``` -curl -LO https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz - -# unpack -tar -xzf graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz - -sudo mv graalvm-ce-java11-21.0.0.2 /usr/lib/jvm/ -sudo ln -s /usr/lib/jvm/graalvm-ce-java11-21.0.0.2 /usr/lib/jvm/graalvm -sudo ln -s /usr/lib/jvm/graalvm/bin/gu /usr/local/bin -sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm/bin/java 2 -sudo update-alternatives --config java - -# install native-image in graalvm-ce-java11-linux-amd64-21.0.0.2/bin -sudo gu install native-image -sudo ln -s /usr/lib/jvm/graalvm/bin/native-image /usr/local/bin - -# deps -sudo apt-get install build-essential libz-dev zlib1g-dev - -# build -cd ~/repo/dda/c4k-shynet -lein uberjar -mkdir -p target/graalvm -lein native - -# execute -./target/graalvm/c4k-shynet -h -./target/graalvm/c4k-shynet src/test/resources/valid-config.edn src/test/resources/valid-auth.edn -./target/graalvm/c4k-shynet src/test/resources/invalid-config.edn src/test/resources/invalid-auth.edn -``` - -## c4k-setup -### install kubectl - -``` -sudo -i -curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - -echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" \ - | tee -a /etc/apt/sources.list.d/kubernetes.list -apt update && apt install kubectl -kubectl completion bash >> /etc/bash_completion.d/kubernetes -``` - -### install kubeconform - -``` -curl -Lo /tmp/kubeconform.tar.gz https://github.com/yannh/kubeconform/releases/download/v0.4.7/kubeconform-linux-amd64.tar.gz -tar -xf /tmp/kubeconform.tar.gz -sudo cp kubeconform /usr/local/bin -``` - -### remote access to c4k - -``` -scp -r root@devops.test.meissa-gmbh.de:/home/c4k/.kube ~/ -ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@devops.test.meissa-gmbh.de -L 8002:localhost:8002 -L 6443:192.168.5.1:6443 - -# add in /etc/hosts "127.0.0.1 kubernetes" - -# change in ~/.kube/config 192.168.5.1 -> kubernetes - -kubectl get pods -``` - -### deploy shynet - -``` -java -jar target/uberjar/c4k-shynet-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip Certificate - -java -jar target/uberjar/c4k-shynet-standalone.jar valid-config.edn my-auth.edn | kubectl apply -f - -``` diff --git a/doc/SetupOnHetzner.md b/doc/SetupOnHetzner.md deleted file mode 100644 index aac2369..0000000 --- a/doc/SetupOnHetzner.md +++ /dev/null @@ -1,73 +0,0 @@ -# Setup -## Infrastructure on Hetzner / Aws - -For a setup on hetzner / aws we use terraform. - -``` -resource "aws_s3_bucket" "backup" { - bucket = "backup" - acl = "private" - - versioning { - enabled = false - } - tags = { - name = "backup" - Description = "bucket for backups in stage: ${var.stage}" - } -} - -resource "hcloud_server" "shynet_09_2021" { - name = "the name" - image = "ubuntu-20.04" - server_type = "cx31" - location = "fsn1" - ssh_keys = ... - - lifecycle { - ignore_changes = [ssh_keys] - } -} - -resource "aws_route53_record" "v4_neu" { - zone_id = the_dns_zone - name = "shynet-neu" - type = "A" - ttl = "300" - records = [hcloud_server.shynet_09_2021.ipv4_address] -} - -output "ipv4" { - value = hcloud_server.shynet_09_2021.ipv4_address -} - -``` - -## k8s minicluster - -For k8s installation we use our [dda-k8s-crate](https://github.com/DomainDrivenArchitecture/dda-k8s-crate) with the following configuation: - - -``` -{:user :k8s - :k8s {:external-ip "ip-from-above"} - :cert-manager :letsencrypt-prod-issuer - :persistent-dirs ["postgres"] - } -``` - -## kubectl apply c4k-shynet - -The last step for applying the shynet deployment is - -``` -c4k-shynet config.edn auth.edn | kubectl apply -f - -``` - -with the following config.edn: - -``` -{:fqdn "the-fqdn-from aws_route53_record.v4_neu" - :postgres-data-volume-path "/var/postgres" ;; Volume was configured at dda-k8s-crate, results in a PersistentVolume definition. - :issuer "prod" } -``` diff --git a/src/main/cljc/dda/c4k_gitea/core.cljc b/src/main/cljc/dda/c4k_gitea/core.cljc index a0dc2d3..b87a663 100644 --- a/src/main/cljc/dda/c4k_gitea/core.cljc +++ b/src/main/cljc/dda/c4k_gitea/core.cljc @@ -17,8 +17,10 @@ (let [storage-class (if (contains? config :postgres-data-volume-path) :manual :local-path)] (cm/concat-vec [(yaml/load-resource "gitea/volumes.yaml") - (yaml/load-resource "gitea/services.yaml") - (yaml/load-resource "gitea/appini-configmap.yaml")] + (yaml/load-resource "gitea/appini-configmap.yaml") + (yaml/load-resource "gitea/deployment.yaml") + (yaml/load-resource "gitea/services.yaml")] + (map yaml/to-string [(postgres/generate-config {:postgres-size :2gb :db-name "gitea"}) (postgres/generate-secret config) @@ -29,5 +31,5 @@ (postgres/generate-deployment {:postgres-image "postgres:14" :postgres-size :2gb}) (postgres/generate-service) - (gitea/generate-deployment config) + (gitea/generate-appini-env config) (gitea/generate-ingress config)])))) diff --git a/src/main/cljc/dda/c4k_gitea/gitea.cljc b/src/main/cljc/dda/c4k_gitea/gitea.cljc index 56b432a..428844a 100644 --- a/src/main/cljc/dda/c4k_gitea/gitea.cljc +++ b/src/main/cljc/dda/c4k_gitea/gitea.cljc @@ -25,12 +25,14 @@ (defmethod yaml/load-as-edn :gitea [resource-name] (yaml/from-string (yaml/load-resource resource-name)))) -(defn generate-deployment [config] - (let [{:keys [postgres-db-user postgres-db-password]} config] +(defn generate-appini-env [config] + (let [{:keys [postgres-db-user postgres-db-password fqdn]} config] (-> - (yaml/load-as-edn "gitea/deployment.yaml") - (cm/replace-named-value "GITEA__database__USER" postgres-db-user) - (cm/replace-named-value "GITEA__database__PASSWD" postgres-db-password)))) + (yaml/load-as-edn "gitea/appini-env-configmap.yaml") + (cm/replace-all-matching-values-by-new-value "FQDN" fqdn) + (cm/replace-all-matching-values-by-new-value "URL" (str "https://" fqdn)) + (cm/replace-all-matching-values-by-new-value "DBUSER" postgres-db-user) + (cm/replace-all-matching-values-by-new-value "DBPW" postgres-db-password)))) (defn generate-ingress [config] (let [{:keys [fqdn issuer] @@ -40,3 +42,4 @@ (yaml/load-as-edn "gitea/ingress.yaml") (assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer) (cm/replace-all-matching-values-by-new-value "FQDN" fqdn)))) + diff --git a/src/main/resources/gitea/appini-configmap.yaml b/src/main/resources/gitea/appini-configmap.yaml index ad2029e..e044c86 100644 --- a/src/main/resources/gitea/appini-configmap.yaml +++ b/src/main/resources/gitea/appini-configmap.yaml @@ -6,11 +6,12 @@ metadata: data: app.ini: | APP_NAME = Gitea meissa - RUN_MODE = prod + RUN_MODE = prod # affects performance and debugging. Either “dev”, “prod” or “test”. Default: prod RUN_USER = git [repository] ROOT = /data/git/repositories + DEFAULT_PRIVATE = private [repository.local] LOCAL_COPY_PATH = /data/gitea/tmp/local-repo @@ -27,7 +28,7 @@ data: DISABLE_SSH = false SSH_PORT = 22 SSH_LISTEN_PORT = 22 - LFS_START_SERVER = true + LFS_START_SERVER = false LFS_CONTENT_PATH = /data/git/lfs ;LFS_JWT_SECRET = OFFLINE_MODE = false diff --git a/src/main/resources/gitea/appini-env-configmap.yaml b/src/main/resources/gitea/appini-env-configmap.yaml new file mode 100644 index 0000000..c92adaa --- /dev/null +++ b/src/main/resources/gitea/appini-env-configmap.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gitea-env + namespace: default +data: + GITEA__database__DB_TYPE: "postgres" + GITEA__database__HOST: "postgresql-service.default.svc.cluster.local:5432" # Service.Namespace.svc.cluster.local + GITEA__database__NAME: gitea + GITEA__database__USER: DBUSER + GITEA__database__PASSWD: DBPW + + GITEA__server__DOMAIN: FQDN + GITEA__server__ROOT_URL: URL diff --git a/src/main/resources/gitea/deployment.yaml b/src/main/resources/gitea/deployment.yaml index 3933729..e3e3127 100644 --- a/src/main/resources/gitea/deployment.yaml +++ b/src/main/resources/gitea/deployment.yaml @@ -21,23 +21,9 @@ spec: image: gitea/gitea:1.16.8 imagePullPolicy: Always # config settings - env: - - name: GITEA__service__DISABLE_REGISTRATION - value: "true" - - name: GITEA__repository__DEFAULT_PRIVATE - value: private - - name: GITEA__service__ENABLE_CAPTCHA - value: "true" - - name: GITEA__database__DB_TYPE - value: "postgres" - - name: GITEA__database__HOST - value: "postgresql-service.default.svc.cluster.local:5432" # Service.Namespace.svc.cluster.local - - name: GITEA__database__NAME - value: postgres - - name: GITEA__database__USER - value: gitea - - name: GITEA__database__PASSWD - value: gitea-db-user + envFrom: + - configMapRef: + name: gitea-env volumeMounts: - name: app-ini-config-volume mountPath: "/tmp/app.ini" diff --git a/src/test/cljc/dda/c4k_gitea/gitea_test.cljc b/src/test/cljc/dda/c4k_gitea/gitea_test.cljc index f35565d..3d4a8e8 100644 --- a/src/test/cljc/dda/c4k_gitea/gitea_test.cljc +++ b/src/test/cljc/dda/c4k_gitea/gitea_test.cljc @@ -5,48 +5,20 @@ [dda.c4k-gitea.gitea :as cut])) -(deftest should-generate-webserver-deployment - (is (= {:apiVersion "apps/v1", - :kind "Deployment", - :metadata - {:name "gitea", :namespace "default", :labels {:app "gitea"}}, - :spec - {:replicas 1, - :selector {:matchLabels {:app "gitea"}}, - :template - {:metadata {:name "gitea", :labels {:app "gitea"}}, - :spec - {:containers - [{:name "gitea", - :image "gitea/gitea:1.16.8", - :imagePullPolicy "Always", - :env - [{:name "GITEA__service__DISABLE_REGISTRATION", :value "true"} - {:name "GITEA__repository__DEFAULT_PRIVATE", :value "private"} - {:name "GITEA__service__ENABLE_CAPTCHA", :value "true"} - {:name "GITEA__database__DB_TYPE", :value "postgres"} - {:name "GITEA__database__HOST", - :value "postgresql-service.default.svc.cluster.local:5432"} - {:name "GITEA__database__NAME", :value "postgres"} - {:name "GITEA__database__USER", :value "pg-user"} - {:name "GITEA__database__PASSWD", :value "pg-pw"}], - :volumeMounts - [{:name "app-ini-config-volume", - :mountPath "/tmp/app.ini", - :subPath "app.ini"} - {:name "gitea-root-volume", :mountPath "/var/lib/gitea"} - {:name "gitea-data-volume", :mountPath "/data"}], - :ports - [{:containerPort 22, :name "git-ssh"} - {:containerPort 3000, :name "gitea"}]}], - :volumes - [{:name "app-ini-config-volume", - :configMap {:name "gitea-app-ini-config"}} - {:name "gitea-root-volume", - :persistentVolumeClaim {:claimName "gitea-root-pvc"}} - {:name "gitea-data-volume", - :persistentVolumeClaim {:claimName "gitea-data-pvc"}}]}}}} - (cut/generate-deployment {:fqdn "test.com" :issuer "staging" :postgres-db-user "pg-user" :postgres-db-password "pg-pw"})))) +(deftest should-generate-appini-env + (is (= {:apiVersion "v1", + :kind "ConfigMap", + :metadata {:name "gitea-env", :namespace "default"}, + :data + {:GITEA__database__DB_TYPE "postgres", + :GITEA__database__HOST + "postgresql-service.default.svc.cluster.local:5432", + :GITEA__database__NAME "gitea", + :GITEA__database__USER "pg-user", + :GITEA__database__PASSWD "pg-pw", + :GITEA__server__DOMAIN "test.com", + :GITEA__server__ROOT_URL "https://test.com"}} + (cut/generate-appini-env {:fqdn "test.com" :issuer "staging" :postgres-db-user "pg-user" :postgres-db-password "pg-pw"})))) (deftest should-generate-ingress