Doel
In vorige post installeerde ik volgende servers:
“templ-ubuntu”, “demo-LinuxMint”, “home-devdepserver” en “home-utilityserver”.
In deze post zal ik “home-pvehelper”, “home-testappserver” en “home-prodappserver” installeren.
Het opruimen van bestaande “pve” en “home-fileserver” zal later volgen.
Ik wil een eerste minimale demonstratie web-applicatie in Golang met een SQLite database ontwikkelen,
gebruikmakend van de centrale repository voor source code opslag.
De applicatie dient daarna als OCI container opgeleverd te worden en in de centrale registry voor binaries opgeslagen te worden.
Daarna dient een applicatie-execution server-omgeving op mijn home-server aangemaakt te worden (“nas-prodappserver” genoemd).
De aangemaakte containerized applicatie en database dient op deze server-omgeving vervolgens gedeployed te worden.
Als laatste wil ik deze gedeployde web-applicatie publiek toegankelijk maken via tunneling.
De applicatie moet kunnen opgeroepen worden via een link in de “Demo” pagina van mijn website op Cloudflare.
Met dit project werk ik de realisatie van al mijn ideeën voor de publieke website volledig af.
In volgend project wil ik starten met de verdere uitwerking van mijn ideeën
over application development tools, testing, security, CI/CD, Kubernetes en app/infra-monitoring.
Resultaat
1 - Ontwikkeling van minimale demo web-applicatie in Go
Als eerste maakte ik een “HelloWorld” applicatie aan in Golang (in “example” folder in Gitea).
Ik koos Golang als programmeertaal omdat het een eenvoudige, performante taal is en echt geschikt om in containers/cloud te draaien.
Dit HelloWorld project gebruikte ik om een “go_template” project (in “util” folder in Gitea) uit te werken en te testen.
Het go_template project zal hierna gebruikt worden om de development van alle nieuwe golang projecten gemakkelijk te kunnen opstarten.
Dit go_template project bevat de te gebruiken github/gitea configuraties, local git configuraties, en de golang setup.
Het bevat ook een eenvoudige makefile om een compile, linter-ing en test workflow door automatisatie te vereenvoudigen.
Later zal ook andere pipeline-logica toegevoegd worden.
Op deze manier werd onmiddelijk bij de start een goede development workflow afgedwongen.
Zie Overview for golang beginners 👆 voor meer uitleg.
??? TODO ???
Daarna werd het “todo_web” project (in “app” folder in Gitea) aangemaakt met go_template project als starter.
De project-structuur werd voorzien om niet enkel golang source code te bevatten,
maar ook golang test code, sql script files, pipeline specificaties, etc.
Vervolgens heb ik dan een sqlite database aangemaakt met sql scripts voor creatie van db-objecten en testdata.
Sqlite is de meest gebruikte database ter wereld en draait op alle OS’s.
Het is een sql database die alle ACID eigenschappen (zoals transacties) ondersteunt.
Ze is gratis, uiterst performant (in-process) en eenvoudig te gebruiken/beheren (alle data weggeschreven in 1 file).
Sqlite readers blokkeren nooit andere readers of writers, en writers blokkeren nooit readers maar wel andere writers.
Een sqlite database zal ik in latere projecten ook in kubernetes gebruiken (met horizontal scaling en backup),
en er dan performantietesten op uitvoeren.
Na de aanmaak van de databank werd een eerste versie van de web applicatie ontwikkeld.
Deze toonde enkel de database-inhoud als todo-rijen in een tabel op het scherm.
Hiervoor werd de standaard http library en de templ library in go gebruikt.
Voor de toegang tot de databank gebruikte ik de sqlc tool,
die vanuit een tekst file met sql en specificaties de db-access code in golang genereert.
Voor de web presentatie gebruikte ik de reeds gekende tailwind css technologie.
Als laatste werden web-schermen aangemaakt om een todo-lijn toe te voegen, te verwijderen, of todo-details te wijzigen.
Hiervoor maakte ik gebruik van AlpineJs en DaisyUI als extra frontend-technologieën.
AlpineJS is een kleine Javascript library die nieuwe attributes aan bestaande HTML elementen toevoegt.
Hiermee kan code in de browser uitgevoerd worden zonder javascript programmatie,
bijvoorbeeld voor form validaties of communicatie met backend server code.
DaisyUI is een UI componenten bibliotheek volledig gebaseerd op Tailwind css,
die toelaat om sneller mooiere web interfaces te maken.
2 - Containerize web-applicatie en deploy op applicatie-server
??? TODO ???
build van container image met Alpine of Distroless base image (via Docker of Podman)
3 - Maak zelf gehoste web-applicatie publiek toegankelijk
De ToDo web-applicatie is gehost in mijn thuis-netwerk en niet zonder meer toegankelijk over het internet.
Om publieke toegang te voorzien, heb ik eerst veel bijgeleerd over networking en hiervan een overzicht gemaakt.
Zie Overview of network technology and middleware 👆 voor meer uitleg.
In dit overzicht vind je:
- Netwerk-technologieën
- Netwerk-middleware om websites en web applicaties te ondersteunen
- Producten om vanuit internet toegang te hebben tot applicaties in je thuis-netwerk
Ik koos er uiteindelijk voor om gebruik te maken van Cloudflare Tunneling,
omdat ik al beschikte over een domein-naam en een (gratis) Cloudflare account.
Ik diende dus enkel nog een Cloudflare connector aan te maken en te configureren in mijn LAN.
Ik maakte voor de installatie van de connector gebruik van docker.
Mijn ToDo applicatie is nu bereikbaar via mijn publieke website op Cloudflare.
Voor het ophalen van static web resources voor web applicaties kan gebruik gemaakt worden van de CDN functionaliteit van Cloudflare.
Hierdoor kan dit veel efficienter en on the Edge gebeuren.
Voor de ToDo applicatie gebruikte ik daarom deze CDN mogelijklheid wat resulteert in volgende architectuur:
Dit plaatje werd gemaakt met “Mermaid” software.
Ik gebruikte hiervoor “Markdown Preview Mermaid Support” en “markdownlint” als VSCode extensies.
In vorige projecten gebruikte ik reeds “PlantUML” en “Drawio” in VSCode om diagramma’s aan te maken.
Mermaid kan enkel eenvoudigere diagram’s dan PlantUML aanmaken,
maar de renderer is standaard reeds voorzien in GitLab, GitHub en Gitea.
In deze sectie installeerde ik dus software Portainer en Cloudflare-Agent op “home-testappserver” en “home-prodappserver”.
4 - Voorzie infrastructuur om andere zelf gehoste web-applicaties publiek toegankelijk te maken
Ik ga later ook zelf-gehoste web applicaties publiek maken via https en port forwarding.
Een client kan dan mijn web applicatie bereiken via mijn wan-router thuis,
die via port forwarding de request doorgeeft aan een reverse proxy (zoals nginx).
Deze reverse proxy zal de https request omvormen naar een http request,
en forwarden naar mijn zelf-gehoste web applicatie.
Dit vereist wel een statisch publiek IP-adres, wat zou kunnen opgelost worden via DDNS.
Het vereist ook een geldig SSL certificaat, wat gratis zou kunnen opgelost worden met DNS Challenge.
De reverse proxy moet dit wel ondersteunen (zoals nginx).
Dit resulteert dan in bovenstaande architectuur.
Vervolgens installeerde ik software Cloudflare-DDNS op “home-pvehelper”,
en software Nginx naast Portainer en Cloudflare-Agent op “home-testappserver” en “home-prodappserver”.
Om dit uit te testen, maakte ik op deze manier de “HelloWorld” applicatie publiek toegankelijk.
Ik installeerde en gebruikte hiervoor nginx als reverse proxy.
Omdat ik zo veilig mogelijk wil werken,
maakte ik gebruik van Cloudflare om mijn eigen publiek IP-adres verborgen te houden.
Op deze manier kan ik applicaties ook tijdelijk beschikbaar stellen,
zodat andere developers deze bijvoorbeeld gemakkelijk kunnen testen.
5 - Automatische data backup van zelf gehoste software
Heel wat gebruikte software slaat actieve data op die ik ook wil backup-en:
- Homarr: links in dashboard content
- Passbolt: secrets collection
- Gitea: repositories en registries
- eigen applicaties: sqlite database
??? TODO ???
ISP-Router & Smart-Switch -> VLAN ?
In deze sectie reorganiseerde en installeerde ik dus opnieuw de bestaande software “proxmox01” (OS) en “nas-fileserver”.
Deze servers werden ook hernoemd naar “pve” en “home-fileserver”.
Op de home-fileserver werd software geinstalleerd om data op alle apparaten te repliceren,
en daarna te backup-en op externe media op een performante manier.
