Compare commits

..

33 Commits

Author SHA1 Message Date
17b4417a0a . 2022-10-09 18:12:20 +01:00
5edf0b7cb2 . 2022-10-09 18:11:35 +01:00
7088008535 . 2022-10-09 14:16:34 +01:00
5785571f48 . 2022-10-09 13:51:12 +01:00
fec022f1be . 2022-10-09 13:37:00 +01:00
74b13252fe . 2022-10-08 16:56:26 +01:00
c96dfcac5b . 2022-10-08 16:22:05 +01:00
07412c905f . 2022-10-08 16:21:40 +01:00
3efef96fa6 . 2022-10-08 12:49:12 +01:00
6c4cbc7fed typos 2022-10-06 00:23:03 +01:00
49d190081b typo 2022-10-06 00:21:21 +01:00
82a5971502 . 2022-10-05 23:21:51 +01:00
657b305eef . 2022-10-05 15:12:15 +01:00
f79da09e97 . 2022-10-05 14:58:29 +01:00
3459ef7101 . 2022-10-05 14:34:40 +01:00
370d409851 . 2022-10-05 14:06:46 +01:00
2f66c0cd94 . 2022-10-05 14:02:39 +01:00
c872f7c6cb Update 'documentation/issue#8.md' 2022-10-05 13:18:18 +01:00
dd36b2b5ba Add 'documentation/issue#8.md' 2022-10-05 13:15:06 +01:00
b57e15b7d6 . 2022-10-05 11:39:37 +01:00
88d8ace2e8 Merge branch 'feature/#8-lxc' of https://git.limbosolutions.com/limbosolutions.com/git.limbosolutions.com into feature/#8-lxc 2022-10-04 00:56:07 +01:00
2bfc501395 . 2022-10-04 00:49:19 +01:00
9eb54fc4ca Update 'documentation/setup.md' 2022-10-01 17:11:02 +01:00
fffb6ddfa4 Update 'documentation/restore.md' 2022-10-01 17:02:45 +01:00
d45a9c8d03 Update 'documentation/restore.md' 2022-10-01 17:01:08 +01:00
dbf874fd7f Update 'documentation/restore.md' 2022-10-01 16:59:33 +01:00
874b2705ce Update 'documentation/restore.md' 2022-10-01 16:58:58 +01:00
5f28f2ef8a Update 'documentation/restore.md' 2022-10-01 16:55:06 +01:00
5513b14587 Update 'documentation/restore.md' 2022-10-01 16:52:16 +01:00
0e7c34489c Update 'documentation/restore.md' 2022-10-01 16:51:17 +01:00
10f7cf88d2 Update 'documentation/restore.md' 2022-10-01 16:37:11 +01:00
8628a12ec5 Add 'documentation/restore.md' 2022-10-01 16:31:22 +01:00
dbe6acbf0e under development 2022-10-01 15:40:00 +01:00
32 changed files with 332 additions and 929 deletions

View File

@@ -1,34 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
{
"name": "git-limbosolutions-com-dev",
"image": "git.limbosolutions.com/mylimbo/devcontainers/devops:latest",
"runArgs": ["--hostname=git-limbosolutions-com-dev-container"],
"remoteUser": "vscode",
"mounts": [
"source=${localWorkspaceFolder}/.kube,target=/home/vscode/.kube,type=bind",
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind",
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind"
],
"customizations": {
"vscode": {
"extensions": [
"ms-kubernetes-tools.vscode-kubernetes-tools",
"redhat.ansible",
"mtxr.sqltools-driver-mysql",
"stateful.runme",
"yzhang.markdown-all-in-one",
"davidanson.vscode-markdownlint",
"eamodio.gitlens",
"m4ns0ur.base64",
"rogalmic.bash-debug",
"streetsidesoftware.code-spell-checker",
"ms-azuretools.vscode-containers",
"eamodio.gitlens",
"shd101wyy.markdown-preview-enhanced",
"bierner.markdown-preview-github-styles"
]
}
}
}

View File

@@ -1,93 +0,0 @@
on:
schedule:
- cron: '0 9 * * 0' # every sunday 9 am
push:
branches:
- main
pull_request:
branches:
- main
jobs:
continuous-deploy:
runs-on: ubuntu-latest
container:
image: git.limbosolutions.com/kb/gitea/act:latest-network-stack
env:
GITHUB_TEMP: ${{ runner.temp }} # fix missing GITHUB_TEMP on gitea
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: limbo public actions
env:
WORKSPACE: "${{ gitea.workspace }}"
run: |
curl -fsSL https://git.limbosolutions.com/kb/gitea/raw/branch/main/cloud-scripts/setup-limbo-actions.sh | bash 2>&1
# limbo custom actions required https://git.limbosolutions.com/kb/gitea/raw/branch/main
- name: Configure kubectl config
uses: ./.gitea/limbo_actions/kubectl-setup
with:
kube_server: ${{ secrets.HOSTING_KUBE_SERVER }}
kube_ca_base64: ${{ secrets.HOSTING_KUBE_CA_BASE64 }}
kube_token: ${{ secrets.HOSTING_KUBE_TOKEN }}
- name: Deploy
shell: bash
env:
# cron jobs env
CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY }}
CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD }}
CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT }}
CRONJOBS_BACKUPS_SECRETS_BORG_REPO: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_REPO }}
CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE }}
CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER }}
CRONJOBS_BACKUPS_SECRETS_ID_RSA: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_ID_RSA }}
CRONJOBS_BACKUPS_SECRETS_BORG_KEY: ${{ secrets.CRONJOBS_BACKUPS_SECRETS_BORG_KEY }}
# helm chart values
APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD: ${{ secrets.APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD }}
APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD }}
APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD }}
APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE }}
APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME: ${{ secrets.APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME }}
APP_HELM_VALUE_GITEA_ADMIN_USERNAME: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_USERNAME }}
APP_HELM_VALUE_GITEA_ADMIN_PASSWORD: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_PASSWORD }}
APP_HELM_VALUE_GITEA_ADMIN_EMAIL: ${{ secrets.APP_HELM_VALUE_GITEA_ADMIN_EMAIL }}
APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET }}
APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET }}
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY }}
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES }}
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN }}
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO }}
APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET: ${{ secrets.APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET }}
run: |
set -euo pipefail
# ensure cleanup always runs
trap 'rm -f \
deploy/app/cronjobs/backups/.env.d/secrets \
deploy/app/cronjobs/backups/.env.d/id_rsa \
deploy/app/cronjobs/backups/.env.d/borg_key' EXIT
# setup env for cronjobs backups
echo "PBS_REPOSITORY=${CRONJOBS_BACKUPS_SECRETS_PBS_REPOSITORY}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "PBS_PASSWORD=${CRONJOBS_BACKUPS_SECRETS_PBS_PASSWORD}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "PBS_FINGERPRINT=${CRONJOBS_BACKUPS_SECRETS_PBS_FINGERPRINT}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "BORG_REPO=${CRONJOBS_BACKUPS_SECRETS_BORG_REPO}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "BORG_PASSPHRASE=${CRONJOBS_BACKUPS_SECRETS_BORG_PASSPHRASE}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "OFFSITE_TARGET_FOLDER=${CRONJOBS_BACKUPS_SECRETS_OFFSITE_TARGET_FOLDER}" >> deploy/app/cronjobs/backups/.env.d/secrets
echo "${CRONJOBS_BACKUPS_SECRETS_ID_RSA}" >> deploy/app/cronjobs/backups/.env.d/id_rsa
echo "${CRONJOBS_BACKUPS_SECRETS_BORG_KEY}" >> deploy/app/cronjobs/backups/.env.d/borg_key
# enforce security
chmod 600 deploy/app/cronjobs/backups/.env.d/secrets
chmod 600 deploy/app/cronjobs/backups/.env.d/id_rsa
chmod 600 deploy/app/cronjobs/backups/.env.d/borg_key
# invoke deploy script
ops-scripts/apply-app.sh

8
.gitignore vendored
View File

@@ -1,5 +1,3 @@
tmp
**.env
**.private.**
**.local.**
.kube/**
*.local/*
*.env
*.env.d/*

View File

@@ -1,5 +0,0 @@
{
"cSpell.words": [
"valkey"
]
}

View File

@@ -1,44 +1,11 @@
# git.limbosolutions.com
Welcome to public repository of my [Git Server](https://git.limbosolutions.com)
Using [gitea](https://git.limbosolutions.com/kb/gitea) as git server.
- [Deploy](#deploy)
- [App](#app)
- [Continuous Deploy](#continuous-deploy)
- [Infra](#infra)
- [Backups](#backups)
## Setup
## Deploy
for more information check /documentation/setup.md
### App
## Backup Strategy
**Environment files:**
- ./deploy/app/cronjobs/backups/.env.d/secrets [Example](./deploy/app/cronjobs/backups/.env.d/secrets.example)
- ./deploy/app/cronjobs/backups/.env.d/borg_key [Example](./deploy/app/cronjobs/backups/.env.d/borg_key.example)
- ./deploy/app/cronjobs/backups/.env.d/id_rsa [Example](./deploy/app/cronjobs/backups/.env.d/id_rsa.example)
- ./deploy/helm/.env [Example](./deploy/helm/.env.example)
```bash
./ops-scripts/apply-app.sh
```
- [kustomization](/deploy/app/kustomization.yaml)
### Continuous Deploy
Executes [App Deploy](#app) using [Gitea workflow](./.gitea/workflows/app-deploy.yaml).
### Infra
```bash
./ops-scripts/apply-infra.sh
```
- [kustomization](/deploy/infra/kustomization.yaml)
## Backups
for more information [check readme](./docs/backups.md).
Duplicati running on docker.

View File

@@ -1,3 +0,0 @@
**
!.gitignore
!*.example

View File

@@ -1 +0,0 @@
BORG_KEY an valid borg key

View File

@@ -1,3 +0,0 @@
-----BEGIN OPENSSH PRIVATE KEY-----
AND VALID PRIVATE SSH KEY WITH ACCESS TO SSH SERVER
-----END OPENSSH PRIVATE KEY-----

View File

@@ -1,7 +0,0 @@
PBS_REPOSITORY="pbs repository"
PBS_PASSWORD="pbs access passwordd"
PBS_FINGERPRINT="00:00:00:00:00" # the pbs finger print
BORG_REPO="ssh://user@reposerver/path" # required by offsite babckup
BORG_PASSPHRASE="borg passphare" # required by offsite babckup
OFFSITE_TARGET_FOLDER="test:target_path" # follow rclone naming convension

View File

@@ -1,163 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-borg-offsite
namespace: git-limbosolutions-com
spec:
schedule: "0 16 * * 0" #every sunday at 4pm
jobTemplate:
spec:
backoffLimit: 1
template:
metadata:
labels:
app: offsite-backup
spec:
restartPolicy: Never
initContainers:
- name: postgres-export
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
image: postgres:latest
command: ["sh", "-c"]
args:
- |
set -e
. /root/.gitea-inline-config/database
export PGPASSWORD=$PASSWD
pg_dump -h gitea-postgresql.git-limbosolutions-com.svc.cluster.local -U $USER -d $NAME > /data/postgresql-export/db_backup.sql
volumeMounts:
- name: backup-var-data
mountPath: /data/postgresql-export
subPath: postgresql-export
- name: gitea-inline-config
mountPath: /root/.gitea-inline-config
readOnly: true
containers:
- name: borg-client
image: git.limbosolutions.com/kb/borg-backup:latest
imagePullPolicy: Always
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
env:
- name: BORG_REPO
valueFrom:
secretKeyRef:
name: gitea-backup
key: BORG_REPO
- name: BORG_PASSPHRASE
valueFrom:
secretKeyRef:
name: gitea-backup
key: BORG_PASSPHRASE
- name: OFFSITE_TARGET_FOLDER
valueFrom:
secretKeyRef:
name: gitea-backup
key: OFFSITE_TARGET_FOLDER
- name: BORG_RSH
value: ssh -p 2222 -o StrictHostKeyChecking=no -o LogLevel=ERROR
- name: REPO_SYNC_MAX_SIZE
value: "16106127360" # 15GB
- name: MODE
value: SHELL
args:
- |
set -e
SCRIPT_START_TIME=$(date +%s)
# while true; do
# sleep 5
# done
borg create ${BORG_REPO}::postgresql-export-$(date +%Y%m%d%H%M%S) /data/postgresql-export
borg create ${BORG_REPO}::gitea-data-$(date +%Y%m%d%H%M%S) /data/gitea-data
#cleanup
borg prune -v --list --keep-daily=10 --keep-weekly=7 --keep-monthly=-1 ${BORG_REPO} --glob-archives='gitea-data*'
borg prune -v --list --keep-daily=10 --keep-weekly=7 --keep-monthly=-1 ${BORG_REPO} --glob-archives='postgresql-export*'
borg compact ${BORG_REPO}
# check repo size
REPO_SIZE_IN_BYTES=$(remote-get-folder-size)
echo "Repository size: $((REPO_SIZE_IN_BYTES / 1024 / 1024))MB"
if [ $REPO_SIZE_IN_BYTES -gt $REPO_SYNC_MAX_SIZE ]; then \
echo "ERROR: Repository size $((REPO_SIZE_IN_BYTES / 1024 / 1024))MB exceeds $((REPO_SYNC_MAX_SIZE / 1024 / 1024))MB";
exit 1;
else
# Repository size is within limits for offsite sync
# ssh to backup server and enforce rclone to onedrive
remote-connect "rclone sync $SSH_FOLDER $OFFSITE_TARGET_FOLDER --stats=0" && \
echo "INFO: Finished Backup of git.limbosolutions.com (offsite) ($((SCRIPT_DURATION / 60 / 60)):$((SCRIPT_DURATION / 60)):$((SCRIPT_DURATION % 60))) "
fi
#outputs info
borg info ${BORG_REPO}
#borg info ${BORG_REPO} --json
volumeMounts:
- name: gitea-data
mountPath: /data/gitea-data
- name: backup-var-data
mountPath: /data/postgresql-export
subPath: postgresql-export
- name: gitea-backup-secrets
mountPath: /root/.ssh/id_rsa
subPath: SSH_ID_RSA
readOnly: true
- name: gitea-backup-secrets
mountPath: /app/borg/key
subPath: BORG_KEY
volumes:
- name: gitea-data
persistentVolumeClaim:
claimName: gitea-shared-storage
- name: gitea-inline-config
secret:
secretName: gitea-inline-config
- name: gitea-backup-secrets
secret:
secretName: gitea-backup
defaultMode: 0600
- name: backup-var-data
emptyDir: {}

View File

@@ -1,123 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-pbs
namespace: git-limbosolutions-com
spec:
schedule: "0 1 * * *"
jobTemplate:
spec:
backoffLimit: 1
template:
metadata:
labels:
app: pbs-backup
spec:
restartPolicy: Never
initContainers:
- name: postgres-export
image: postgres:latest
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
command: ["sh", "-c"]
args:
- |
#echo "INFO: Starting export"
. /root/.gitea-inline-config/database
export PGPASSWORD=$PASSWD
#echo "INFO: Exporting database"
pg_dump -h gitea-postgresql.git-limbosolutions-com.svc.cluster.local -U $USER -d $NAME > /data/postgresql-export/db_backup.sql
if [ $? -ne 0 ]; then
echo "ERROR: Exporting database failed"
exit 1
fi
#echo "INFO: Exporting database finished"
volumeMounts:
- name: backup-run-data
mountPath: /data/postgresql-export
subPath: postgresql-export
- name: gitea-inline-config
mountPath: /root/.gitea-inline-config
readOnly: true
containers:
- name: gitea-pbs-client
image: git.limbosolutions.com/kb/pbsclient
imagePullPolicy: Always
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
env:
- name: MODE
value: shell
- name: PBS_REPOSITORY
valueFrom:
secretKeyRef:
name: gitea-backup
key: PBS_REPOSITORY
- name: PBS_PASSWORD
valueFrom:
secretKeyRef:
name: gitea-backup
key: PBS_PASSWORD
- name: PBS_FINGERPRINT
valueFrom:
secretKeyRef:
name: gitea-backup
key: PBS_FINGERPRINT
command: ["bash", "-c"]
args:
- |
set -e
# while true; do
# sleep 1s
# done
SCRIPT_START_TIME=$(date +%s)
proxmox-backup-client backup gitea-data.pxar:/data/gitea-data postgresql-data.pxar:/data/postgresql-data postgresql-export.pxar:/data/postgresql-export --include-dev /data/postgresql-data --include-dev /data/postgresql-export --include-dev /data/gitea-data --backup-id "gitea-full" -ns git.limbosolutions.com
SCRIPT_DURATION=$(($(date +%s) - SCRIPT_START_TIME))
echo "INFO: Finished Backup of git.limbosolutions.com ($((SCRIPT_DURATION / 60 / 60)):$((SCRIPT_DURATION / 60)):$((SCRIPT_DURATION % 60))) "
volumeMounts:
- name: gitea-shared-storage
mountPath: /data/gitea-data
- name: db-postgresql-data
mountPath: /data/postgresql-data
- name: backup-run-data
mountPath: /data/postgresql-export
subPath: postgresql-export
- name: backup-run-data
mountPath: /tmp
subPath: tmp
volumes:
- name: gitea-shared-storage
persistentVolumeClaim:
claimName: gitea-shared-storage
- name: db-postgresql-data
persistentVolumeClaim:
claimName: data-gitea-postgresql-0
- name: backup-run-data
emptyDir: {}
- name: gitea-inline-config
secret:
secretName: gitea-inline-config

View File

@@ -1,17 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cronjobs/backups/backup-borg-offsite-cronjob.yaml
- cronjobs/backups/backup-pbs-cronjob.yaml
secretGenerator:
- name: gitea-backup
namespace: git-limbosolutions-com
envs:
- cronjobs/backups/.env.d/secrets
files:
- BORG_KEY=cronjobs/backups/.env.d/borg_key
- SSH_ID_RSA=cronjobs/backups/.env.d/id_rsa
generatorOptions:
disableNameSuffixHash: true

View File

@@ -1,15 +0,0 @@
APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD="????"
APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD="????"
APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD="????"
APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE="????"
APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME="????"
APP_HELM_VALUE_GITEA_ADMIN_USERNAME="????"
APP_HELM_VALUE_GITEA_ADMIN_PASSWORD="????"
APP_HELM_VALUE_GITEA_ADMIN_EMAIL="????"
APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET="????"
APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET="????"
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY="????"
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES="????"
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN="????"
APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO="????"
APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET="????"

View File

@@ -1,149 +0,0 @@
image:
registry: ""
repository: gitea/gitea
pullPolicy: Always
tag: "1"
cache:
enabled: false
valkey-cluster:
enabled: false
valkey:
enabled: true
architecture: standalone
global:
valkey:
password: "???"
master:
count: 1
service:
ports:
valkey: 6379
postgresql:
enabled: true
image:
registry: ""
repository: bitnami/postgresql
tag: 16
imagePullPolicy: IfNotPresent
global:
postgresql:
auth:
postgresPassword: "???"
password: "???"
database: "???"
username: "???"
service:
ports:
postgresql: 5432
primary:
persistence:
size: 10Gi
metrics:
enabled: true
collectors:
wal: false
postgresql-ha:
enabled: false
persistence:
enabled: true
service:
ssh:
enabled: true
port: 2222
annotations:
metallb.universe.tf/allow-shared-ip: test
http:
clusterIP: "" # empty string → Kubernetes assigns a routable ClusterIP
type: ClusterIP
port: 3000
gitea:
admin:
username: "???"
password: "???"
email: "???"
config:
oauth2:
JWT_SECRET: "???"
actions:
ENABLED: true
database:
DB_TYPE: postgres
indexer:
ISSUE_INDEXER_TYPE: bleve
REPO_INDEXER_ENABLED: true
picture:
AVATAR_UPLOAD_PATH: /data/avatars
server:
DOMAIN: git.limbosolutions.com
SSH_DOMAIN: git.limbosolutions.com
ROOT_URL: https://git.limbosolutions.com
DISABLE_SSH: false
SSH_PORT: 2222
SSH_LISTEN_PORT: 2222
LFS_START_SERVER: true
START_SSH_SERVER: true
LFS_PATH: /data/git/lfs
LFS_JWT_SECRET: "???"
OFFLINE_MODE: false
#MFF 03/08/2024
REPO_INDEXER_ENABLED: true
REPO_INDEXER_PATH: indexers/repos.bleve
MAX_FILE_SIZE: 1048576
REPO_INDEXER_INCLUDE:
REPO_INDEXER_EXCLUDE: resources/bin/**
####
service:
DISABLE_REGISTRATION: true
REQUIRE_SIGNIN_VIEW: false
REGISTER_EMAIL_CONFIRM: false
ENABLE_NOTIFY_MAIL: false
ALLOW_ONLY_EXTERNAL_REGISTRATION: false
ENABLE_CAPTCHA: true
DEFAULT_KEEP_EMAIL_PRIVATE : true
DEFAULT_ALLOW_CREATE_ORGANIZATION: true
DEFAULT_ENABLE_TIMETRACKING: true
NO_REPLY_ADDRESS: noreply.localhost
oauth2:
JWT_SECRET: "???"
mailer:
ENABLED: false
openid:
ENABLE_OPENID_SIGNIN: false
ENABLE_OPENID_SIGNUP: false
security:
INSTALL_LOCK: true
SECRET_KEY: "???"
REVERSE_PROXY_LIMIT: 1
REVERSE_PROXY_TRUSTED_PROXIES: "???"
INTERNAL_TOKEN: "???"
PASSWORD_HASH_ALGO: "???"
ingress:
enabled: true
className: traefik
annotations:
kubernetes.io/ingress.class: traefik
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure, public-https
hosts:
- host: git.limbosolutions.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: limbosolutions-com-tls
hosts:
- "git.limbosolutions.com"

View File

@@ -1,43 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: git-limbosolutions-com
name: continuous-deploy
rules:
- apiGroups: [""]
resources: ["pods", "services", "secrets", "configmaps", "persistentvolumeclaims", "endpoints", "serviceaccounts"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
- apiGroups: ["batch"]
resources: ["cronjobs", "jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["networkpolicies", "ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["get", "list", "watch", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: continuous-deploy
namespace: git-limbosolutions-com
subjects:
- kind: ServiceAccount
name: continuous-deploy
namespace: git-limbosolutions-com
roleRef:
kind: Role
name: continuous-deploy
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: continuous-deploy
annotations:
kubernetes.io/service-account.name: continuous-deploy
type: kubernetes.io/service-account-token

View File

@@ -1,6 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: continuous-deploy
namespace: git-limbosolutions-com

View File

@@ -1,8 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- cd-service-account.yaml
- cd-service-account-token.yaml
- cd-service-account-rbac.yaml

View File

@@ -1,6 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: git-limbosolutions-com
labels:
name: git-limbosolutions-com

View File

@@ -1,61 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: borg-backup-sidekick
namespace: git-limbosolutions-com
labels:
app: borg-backup-sidekick
spec:
containers:
- name: borg-backup-sidekick
image: git.limbosolutions.com/kb/borg-backup:latest
imagePullPolicy: Always
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
env:
- name: BORG_REPO
valueFrom:
secretKeyRef:
name: gitea-backup-secret
key: borg_repo
- name: BORG_PASSPHRASE
valueFrom:
secretKeyRef:
name: gitea-backup-secret
key: borg_passphrase
- name: BORG_RSH
value: ssh -p 2222 -o StrictHostKeyChecking=no -o LogLevel=ERROR
- name: borg_key_file
value: /root/.borg/key
command: ["sh", "-c"]
args:
- |
while true; do
sleep 1s
done
volumeMounts:
- name: gitea-backup-secrets
mountPath: /root/.ssh/id_rsa
subPath: ssh_id_rsa
readOnly: true
- name: gitea-backup-secrets
mountPath: /app/borg/key
subPath: borg_key
volumes:
- name: gitea-backup-secrets
secret:
secretName: gitea-backup
defaultMode: 0600

View File

@@ -0,0 +1,30 @@
version: "3"
services:
duplicati:
image: duplicati-mysqlclient
environment:
- MYSQL_HOST=db
- MYSQL_DATABASE=${DB_NAME}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- DESTINATION=/git/db-dumps
volumes:
- duplicati-data:/data
- duplicati-data:/git/duplicati-data:ro
- data:/git/data:ro
- db:/git/db:ro
- db-dumps:/git/db-dumps
ports:
- ${DUPLICATI_PORT}:8200
restart: unless-stopped
volumes:
duplicati-data:
data:
name: ${GITEA_APP_DATA_VOLUME_NAME}
db:
name: ${GITEA_DB_DATA_VOLUME_NAME}
db-dumps:
name: ${GITEA_DB_DUMPS_VOLUME_NAME}
networks:
gitea:
name: ${DEFAULT_NETWORK_NAME}

View File

@@ -0,0 +1,45 @@
version: "3"
services:
app:
image: gitea/gitea:1.17
environment:
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=db:3306
- GITEA__database__NAME=${DB_NAME}
- GITEA__database__USER=${DB_USER}
- GITEA__database__PASSWD=${DB_PASSWORD}
- DISABLE_SSH=true
restart: unless-stopped
volumes:
- data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- ${GITEA_PORT}:80
networks:
- gitea
db:
image: mysql:8
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_DATABASE=${DB_NAME}
volumes:
- db:/var/lib/mysql
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- db-dumps:/db-dumps
networks:
- gitea
volumes:
data:
name: ${GITEA_APP_DATA_VOLUME_NAME}
db:
name: ${GITEA_DB_DATA_VOLUME_NAME}
db-dumps:
name: ${GITEA_DB_DUMPS_VOLUME_NAME}
networks:
gitea:
name: ${DEFAULT_NETWORK_NAME}

View File

@@ -1,63 +0,0 @@
# Git Action
## runners
## lxc container - proxmox
Template : debian-12-turnkey-core_18.1-1_amd64.tar.gz
- Unprivileged contrainer - Yes
- Nesting -Yes
```bash
# setup new lxc container with docker
apt update -y
apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sh ./get-docker.sh
```
### act runner
```bash
nano setup-act-runners.sh
```
```bash
#/bin/bash
setup(){
CONTAINER_NAME=${OWNER}_act_runner
docker container stop $CONTAINER_NAME
docker container rm $CONTAINER_NAME
docker run \
--restart=unless-stopped \
-v ${CONTAINER_NAME}_data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-e GITEA_INSTANCE_URL=${INSTANCE_URL} \
-e GITEA_RUNNER_REGISTRATION_TOKEN=${REGISTRATION_TOKEN} \
-e GITEA_RUNNER_NAME=${OWNER}_ubuntu_default \
--name ${CONTAINER_NAME} \
-d gitea/act_runner
}
INSTANCE_URL=https://git.limbosolutions.com
OWNER=kb
REGISTRATION_TOKEN=???
setup
OWNER=????
REGISTRATION_TOKEN=???
setup
```
```bash
chmod +x setup-act-runners.sh
./setup-act-runners.sh
```

View File

@@ -1,36 +0,0 @@
# borgbackup sidekick
**Create borgbackup-sidekick pod:**
```bash
kubectl apply -f deploy/ops/borg-backup-sidekick/pod.yaml
```
**Remove borgbackup-sidekick pod:**
```bash
# delete the sidekick pod after use
kubectl delete pod -l app=borg-backup-sidekick
```
```bash
# attach to borgbackup-sidekick
POD_NAME=$(kubectl get pod -l app=borg-backup-sidekick -n git-limbosolutions-com -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it ${POD_NAME} -- bash
```
```bash
# list borg repo
POD_NAME=$(kubectl get pod -l app=borg-backup-sidekick -n git-limbosolutions-com -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it ${POD_NAME} -- bash -c "\
borg list ${BORG_REPO} \
"
```
```bash
# get borg info
POD_NAME=$(kubectl get pod -l app=borg-backup-sidekick -n git-limbosolutions-com -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it ${POD_NAME} -- bash -c "\
borg info ${BORG_REPO}\
"
```

29
documentation/issue#8.md Normal file
View File

@@ -0,0 +1,29 @@
# Feature - Migrate to LXC container
_[Issue 8](https://git.limbosolutions.com/limbosolutions.com/git.limbosolutions.com/issues/8)_
## Development & Testing
- [x] Create LXC Container
- [x] Documentation Scripts for Setup
- [x] Scripts for Setup
- [ ] Restore Backup
- [ ] Documentation for backup and restore
- [ ] Validate Backup
- [x] Recreate System from scripts
## Day 1
- [ ] Backup Current Production
- [ ] Stop Current Production
- [ ] Restore to new Production
- [ ] Change DNS Servers
- [ ] Check OK
- [ ] Production - Reativate Backup
- [ ] Production - Execute Backup
- [ ] Production - Check Backup
## Day 2
- [ ] Production - Check Daily Backup
- [ ] Delete Old Production

View File

@@ -0,0 +1,87 @@
# LXC Setup
## Install
### Requirements
- Currently hosted using macvlan network
- Instructions are provided for $LXC_PROFILE defined as macvlan
_For more information how to setup a lxc profile with macvlan network https://git.limbosolutions.com/kb/lxc_
Replace and execute on bash
```bash
LXC_CONTAINER_NAME=gitsrv01
LXC_PROFILE=default
```
then execute
```bash
## Create ubuntu container
lxc launch ubuntu $LXC_CONTAINER_NAME -p $LXC_PROFILE
## Setup container for docker
curl -s "https://git.limbosolutions.com/kb/lxc/raw/branch/main/scripts/lxc-config-docker-requirements.sh" | bash -s $LXC_CONTAINER_NAME
## update ubuntu container
lxc exec $LXC_CONTAINER_NAME -- bash -c "apt update -y && apt upgrade -y"
## Install fuse and docker on lxc container
lxc exec $LXC_CONTAINER_NAME -- bash -c "curl -s \"https://git.limbosolutions.com/kb/docker/raw/branch/main/scripts/ubuntu-fuse-setup.sh\" | bash"
## Check docker for fusefs
lxc exec $LXC_CONTAINER_NAME -- bash -c "docker info"
#Setup Portainer
lxc exec $LXC_CONTAINER_NAME -- bash -c "curl -s \"https://git.limbosolutions.com/kb/portainer/raw/branch/main/scripts/setup.sh\" | bash"
#confirm container ip address
lxc exec $LXC_CONTAINER_NAME -- bash -c "ip a"
lxc restart $LXC_CONTAINER_NAME
```
### Check instalation
From other computer
```bash
ping $LXC_CONTAINER_NAME
```
Access portainer (https://$LXC_CONTAINER_NAME:9443/) for inicial setup:
- Setup administration username and password
## Remove
```bash
lxc rm $LXC_CONTAINER_NAME --force
```
## set a static ip
On lxc container
``` bash
Example:
/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.121.221/24
gateway4: 192.168.121.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
``` bash

104
documentation/setup.md Normal file
View File

@@ -0,0 +1,104 @@
# Setup
## Install
Setup assumes that I don't have access to the host except through Portainer.
This demonstrates that access to docker is the only real requirement to host git.limbosolutions.com
### Requirements
- Docker
_Currently hosted on an ubuntu lxc container with docker and portainer [+ information](setup-lxc.md)._
- On instructions replace githost with host ip or address
### Services (Stacks)
If portainer installed use portainer (https://githost:9443) to setup/manage services
Required environment variables (.env):
```bash
GITEA_APP_DATA-VOLUME_NAME=gitea_app_data
GITEA_DB_DATA_VOLUME_NAME=gitea_db_data
GITEA_DB-DUMPS_VOLUME_NAME=gitea_db-dumps
DEFAULT_NETWORK_NAME=gitea_default
# gitea mysql dbname
DB_NAME=??
# gitea mysql user
DB_USER=??
# gitea mysql password
DB_PASSWORD=??
# gitea mysql root password
DB_ROOT_PASSWORD=??
#git tea access port
GITEA_PORT=80
#duplicati access port
DUPLICATI_PORT=8200
```
#### Gitea
_[Docker Compose File](../docker/gitea-docker-compose.yaml)_
#### Duplicati
Requirements:
- [Duplicati Image with mySql client](https://git.limbosolutions.com/kb/duplicati/src/branch/main/docker/mysqlclient/README.md)
_[Docker Compose File](../docker/dupliticati-docker-compose.yaml)_
After starting stack:
- Access duplicati (http://ipaddress:8200) and set a password
## Restore
### Requirements
- Host setup with docker and portainer [+ information](setup.md)
### Process
1) Recreate stack gitea _[Docker Compose](../docker/docker-compose.yaml)_ removing read only restrictions on duplicati volumes
1) Check every Container is ok and running
1) Stop every Container except duplicati and portainer
_note: restore of portainer/duplicati not tested_
1) Enter Duplicati (http://hostip:8200)
1) Import Backup job (if not possible next steps must be adapted)
- Restore with permissions checked
- All Imported jobs schedules must be disabled (or disable write permissions on backup host)
1) Recreate duplicati local database (home-> backup-> advanced-> database-> Recreate (delete and repair))
1) Restore all files (except portainer and duplicati data) to original location
- If database engine is diferent do not restore db_data and check restore database **before next steps**with this processs because duplicati is running!
1) Recreate stack gitea _[Docker Compose](../docker/docker-compose.yaml)_ with original read only restrictions on duplicati volumes
1) Confirm everything is ok and running
1) Return to duplicati on schedule job add script to run-script-before-required /data/myScripts/backupdb.sh
1) Execute a backup
1) Reenable Scheduling
### Database
Only required if database data files not recovarable. (Example: diferent database engine from backup)
1) Start Portainer container (if stopped in restore process)
2) Start Database container (if stopped in restore process)
3) Enter Database container bash (by using portainer)
4) Execute:
```bash
#select a file to import
ls /db-dumps
#select a file to import
DB_FILE= "file name to import"
#
mysql --host db -uroot -p ${MYSQL_DATABASE} < /db-dumps/$DB_FILE
#enter root password (root password is in enviromnent variable ${MYSQL_ROOT_PASSWORD})
```

View File

@@ -1,36 +0,0 @@
#/bin/bash
kubectl kustomize deploy/app | kubectl apply -f -
if [ -f "deploy/helm/.env" ]; then
# Export all variables from the file
echo "export variables from file helm/.env"
set -a
. deploy/helm/.env
set +a
fi
if [ -n "${APP_HELM_VALUE_GITEA_ADMIN_USERNAME:-}" ]; then
echo "Executing helm deploy."
helm repo add gitea-charts https://dl.gitea.com/charts/
helm repo update
helm upgrade --install gitea gitea-charts/gitea --version 12.4.0 \
--values deploy/helm/values.yaml \
--set valkey.global.valkey.password=${APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD} \
--set postgresql.global.postgresql.auth.postgresPassword=${APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD} \
--set postgresql.global.postgresql.auth.password=${APP_HELM_VALUE_POSTGRESQL_AUTH_PASSWORD} \
--set postgresql.global.postgresql.auth.database=${APP_HELM_VALUE_POSTGRESQL_AUTH_DATABASE} \
--set postgresql.global.postgresql.auth.username=${APP_HELM_VALUE_POSTGRESQL_AUTH_USERNAME} \
--set gitea.admin.username=${APP_HELM_VALUE_GITEA_ADMIN_USERNAME} \
--set gitea.admin.password=${APP_HELM_VALUE_GITEA_ADMIN_PASSWORD} \
--set gitea.admin.email=${APP_HELM_VALUE_GITEA_ADMIN_EMAIL} \
--set gitea.config.oauth2.JWT_SECRET=${APP_HELM_VALUE_GITEA_CONFIG_OAUTH2_JWT_SECRET} \
--set gitea.config.server.LFS_JWT_SECRET=${APP_HELM_VALUE_GITEA_CONFIG_SERVER_LFS_JWT_SECRET} \
--set gitea.config.security.SECRET_KEY=${APP_HELM_VALUE_GITEA_CONFIG_SECURITY_SECRET_KEY} \
--set gitea.config.security.REVERSE_PROXY_TRUSTED_PROXIES=${APP_HELM_VALUE_GITEA_CONFIG_SECURITY_REVERSE_PROXY_TRUSTED_PROXIES} \
--set gitea.config.security.INTERNAL_TOKEN=${APP_HELM_VALUE_GITEA_CONFIG_SECURITY_INTERNAL_TOKEN} \
--set gitea.config.security.PASSWORD_HASH_ALGO=${APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO} \
--set gitea.config.service.oauth2.JWT_SECRET=${APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET} \
--namespace=git-limbosolutions-com
fi

View File

@@ -1,7 +0,0 @@
#!/bin/bash
set -e
echo "Executing infra deploy."
kubectl kustomize deploy/infra | kubectl apply -f -

23
scripts/setup-lxc.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
## Create a container
lxc launch ubuntu $LXC_CONTAINER_NAME -p $LXC_PROFILE && \
## Setup container for docker
curl - "https://git.limbosolutions.com/kb/lxc/raw/branch/main/scripts/lxc-config-docker-requirements.sh" | bash $LXC_CONTAINER_NAME
## update container
lxc exec $LXC_CONTAINER_NAME bash -c "apt update -y && apt upgrade -y"
## Install docker on lxc container
lxc exec $LXC_CONTAINER_NAME bash -c "curl -s \"https://git.limbosolutions.com/kb/docker/raw/branch/main/scripts/ubuntu-fuse-setup.sh\" | bash "
#install Portainer
lxc exec $LXC_CONTAINER_NAME bash -c "curl -s \"https://git.limbosolutions.com/kb/portainer/raw/branch/main/scripts/setup.sh\" | bash "

3
scripts/setup.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
chmod +x ./setup-lxc.sh
./setup-lxc.sh

4
scripts/web-setup.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
git clone https://git.limbosolutions.com/limbosolutions.com/git.limbosolutions.com
chmod +x ./git.limbosolutions.com/scripts/setup.sh
./git.limbosolutions.com/scripts/setup.sh