This commit is contained in:
52
.gitea/workflows/ci.yaml
Normal file
52
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request: {}
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Setup docker buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Container Registery
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registery: git.housh.dev
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Extract metadata for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: git.housh.dev/homelab/docs
|
||||||
|
tags: |
|
||||||
|
type=schedule
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semvar,pattern={{version}}
|
||||||
|
type=semvar,pattern={{major}}.{{minor}}
|
||||||
|
type=semvar,pattern={{major}}
|
||||||
|
type=sha
|
||||||
|
type=raw,value=latest
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
@@ -43,6 +43,15 @@ extension Item where M == ArticleMetadata {
|
|||||||
}
|
}
|
||||||
return primaryTag
|
return primaryTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDate() -> Date {
|
||||||
|
guard let date = metadata.date else { return date }
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpdatedDate() -> Date? {
|
||||||
|
return metadata.updated
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Most of these are taken from https://github.com/loopwerk/loopwerk.io
|
// NOTE: Most of these are taken from https://github.com/loopwerk/loopwerk.io
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ enum SiteMetadata {
|
|||||||
|
|
||||||
/// Represents the valid file metadata for an article.
|
/// Represents the valid file metadata for an article.
|
||||||
struct ArticleMetadata: Metadata {
|
struct ArticleMetadata: Metadata {
|
||||||
|
|
||||||
|
/// The creation date of the article.
|
||||||
|
let date: Date?
|
||||||
|
|
||||||
|
/// The updated date of the article.
|
||||||
|
let updated: Date?
|
||||||
|
|
||||||
/// The articles associated tags.
|
/// The articles associated tags.
|
||||||
let tags: [String]
|
let tags: [String]
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ private func siteHeader(_ section: Section) -> Node {
|
|||||||
div(class: "header__logo") {
|
div(class: "header__logo") {
|
||||||
a(href: "/") {
|
a(href: "/") {
|
||||||
div(class: "logo") {
|
div(class: "logo") {
|
||||||
"docs.housh.dev"
|
img(src: "/static/favicon-32x32.png")
|
||||||
|
span(class: "pl-2") { "docs.housh.dev" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,6 +51,9 @@ private func siteHeader(_ section: Section) -> Node {
|
|||||||
li {
|
li {
|
||||||
a(class: section == .articles ? "active" : "", href: "/articles/") { "Articles" }
|
a(class: section == .articles ? "active" : "", href: "/articles/") { "Articles" }
|
||||||
}
|
}
|
||||||
|
li {
|
||||||
|
a(href: "https://uptime.housh.dev/status/housh-dev", rel: "nofollow", target: "_blank") { "Server-Monitor" }
|
||||||
|
}
|
||||||
li {
|
li {
|
||||||
a(class: section == .about ? "active" : "", href: "/about.html") { "About" }
|
a(class: section == .about ? "active" : "", href: "/about.html") { "About" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ func tagPrefix(index: Int, totalTags: Int) -> Node {
|
|||||||
func renderArticleInfo(_ article: Item<ArticleMetadata>) -> Node {
|
func renderArticleInfo(_ article: Item<ArticleMetadata>) -> Node {
|
||||||
div(class: "text-slate-400 gray-links text-sm mb-8") {
|
div(class: "text-slate-400 gray-links text-sm mb-8") {
|
||||||
span(class: "border-r border-gray pr-2 mr-2") {
|
span(class: "border-r border-gray pr-2 mr-2") {
|
||||||
article.date.formatted("MMMM dd, yyyy")
|
article.getDate().formatted("MMMM dd, yyyy")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let updated = article.getUpdatedDate() {
|
||||||
|
span(class: "border-r border-gray pr-2 mr-2") {
|
||||||
|
"Updated: \(updated.formatted("MMMM dd, yyyy"))"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%.text("\(article.body.withoutHtmlTags.numberOfWords) words, posted in ")
|
%.text("\(article.body.withoutHtmlTags.numberOfWords) words, posted in ")
|
||||||
@@ -94,7 +100,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
|
|||||||
title: context.item.title,
|
title: context.item.title,
|
||||||
extraHeader: generateHeader(.article(context.item))
|
extraHeader: generateHeader(.article(context.item))
|
||||||
) {
|
) {
|
||||||
article(class: "pt-8 font-avenir text-lg") {
|
article(class: "pt-8") {
|
||||||
h1 { context.item.title }
|
h1 { context.item.title }
|
||||||
div {
|
div {
|
||||||
renderArticleInfo(context.item)
|
renderArticleInfo(context.item)
|
||||||
@@ -104,7 +110,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
|
|||||||
|
|
||||||
div(class: "border-t border-light pt-8 mt-16") {
|
div(class: "border-t border-light pt-8 mt-16") {
|
||||||
div(class: "grid lg:grid-cols-2") {
|
div(class: "grid lg:grid-cols-2") {
|
||||||
h2(class: "text-4xl font-extrabold mb-8") { otherArticles.title }
|
h4(class: "text-3xl text-amber-500 font-extrabold mb-8") { otherArticles.title }
|
||||||
if let tag = otherArticles.tag {
|
if let tag = otherArticles.tag {
|
||||||
a(href: "/articles/tag/\(tag)") {
|
a(href: "/articles/tag/\(tag)") {
|
||||||
div(class: " [&:hover]:border-b border-orange px-5 flex flex-row gap-5") {
|
div(class: " [&:hover]:border-b border-orange px-5 flex flex-row gap-5") {
|
||||||
@@ -133,7 +139,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
|
|||||||
|
|
||||||
func renderArticleForGrid(article: Item<ArticleMetadata>) -> Node {
|
func renderArticleForGrid(article: Item<ArticleMetadata>) -> Node {
|
||||||
section {
|
section {
|
||||||
h2(class: "post-title text-2xl font-bold mb-2") {
|
h3(class: "post-title text-2xl font-bold mb-2") {
|
||||||
a(class: "[&:hover]:border-b border-orange-400", href: article.url) { article.title }
|
a(class: "[&:hover]:border-b border-orange-400", href: article.url) { article.title }
|
||||||
}
|
}
|
||||||
renderArticleInfo(article)
|
renderArticleInfo(article)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
date: 2025-4-02
|
date: 2025-4-02
|
||||||
|
updated: 2025-4-03
|
||||||
author: "Michael Housh"
|
author: "Michael Housh"
|
||||||
tags: network, infrastructure
|
tags: network, infrastructure
|
||||||
---
|
---
|
||||||
@@ -53,12 +54,15 @@ This is the network where all the VoIP phones are on. It is considered
|
|||||||
|
|
||||||
This is the network where all IoT (internet of things) devices are. This is
|
This is the network where all IoT (internet of things) devices are. This is
|
||||||
considered an "untrusted" network and communications with other networks are
|
considered an "untrusted" network and communications with other networks are
|
||||||
minimized to what is actually needed to work.
|
minimized to what is actually needed to work. This network is not able to
|
||||||
|
communicate with the internet, because these devices are made by so many
|
||||||
|
different companies with unknown intentions, this adds an extra layer of
|
||||||
|
security by ensuring all communications are internal to our networks.
|
||||||
|
|
||||||
The exception to items placed on the IoT network is "apple" specific devices,
|
The exception to items placed on the IoT network are "apple" specific devices,
|
||||||
such as home-pods and apple-tv because there are network challenges with these
|
such as home-pods and apple-tv because there are network challenges with these
|
||||||
devices operating properly when placed on the IoT network (which may be resolved
|
devices operating properly when placed on the IoT network, such as airdrop and
|
||||||
in the future).
|
screen casting (which may be resolved in the future).
|
||||||
|
|
||||||
## Firewall
|
## Firewall
|
||||||
|
|
||||||
@@ -72,9 +76,9 @@ from communicating with other networks or the internet.
|
|||||||
|
|
||||||
## DNS
|
## DNS
|
||||||
|
|
||||||
DNS is what translates IP addresses to domain names (i.e. `po.housh.dev` ->
|
DNS is what translates IP addresses to domain names (i.e.
|
||||||
`192.168.50.6`). This is managed by the unifi management console and is accessed
|
`po.housh.dev -> 192.168.50.6`). This is managed by the unifi management console
|
||||||
via `Settings -> Routing -> DNS`.
|
and is accessed via `Settings -> Routing -> DNS`.
|
||||||
|
|
||||||
We primarily use wildcard records, which allow the actual routing to be handled
|
We primarily use wildcard records, which allow the actual routing to be handled
|
||||||
by the servers to the correct service.
|
by the servers to the correct service.
|
||||||
|
|||||||
@@ -33,6 +33,14 @@
|
|||||||
--green: #a6e3a1;
|
--green: #a6e3a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset */
|
||||||
|
* {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
/* HEADER */
|
/* HEADER */
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -92,6 +100,8 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Nav */
|
||||||
|
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
@apply border-b-2 border-orange-400;
|
@apply border-b-2 border-orange-400;
|
||||||
}
|
}
|
||||||
@@ -99,16 +109,18 @@ nav a.active {
|
|||||||
@apply border-b-2 border-orange-400;
|
@apply border-b-2 border-orange-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Body */
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-slate-900 font-avenir;
|
@apply bg-slate-900 font-avenir text-xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@apply text-4xl;
|
@apply text-6xl pb-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@apply text-3xl mb-4 pt-4;
|
@apply text-5xl mb-8 pt-4;
|
||||||
color: var(--green);
|
color: var(--green);
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
@@ -119,26 +131,27 @@ p {
|
|||||||
@apply mb-8;
|
@apply mb-8;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
article h2 {
|
article h2 {
|
||||||
@apply border-b-2 border-slate-200;
|
@apply border-b-2 border-slate-200;
|
||||||
}
|
}
|
||||||
|
|
||||||
article {
|
article a {
|
||||||
@apply font-avenir text-lg;
|
@apply text-orange-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
article a:hover {
|
||||||
|
@apply border-b border-green-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
article code {
|
||||||
|
@apply bg-amber-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@apply px-10;
|
@apply px-10;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
.container img {
|
||||||
-webkit-box-sizing: border-box;
|
padding-top: 10px;
|
||||||
-moz-box-sizing: border-box;
|
padding-bottom: 10px;
|
||||||
-ms-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -9,7 +9,7 @@ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+cli
|
|||||||
code[class*="language-"],
|
code[class*="language-"],
|
||||||
pre[class*="language-"] {
|
pre[class*="language-"] {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
background: none;
|
background: #121416;
|
||||||
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|||||||
Reference in New Issue
Block a user