549 Commits
Author SHA1 Message Date
Gitea Actions f2d4847703 Auto-update blog content from Obsidian: 2026-10-18 16:06:19
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-10-18 16:06:19 +00:00
Gitea Actions 0cee67e6fb Auto-update blog content from Obsidian: 2026-10-18 15:44:06
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-10-18 15:44:06 +00:00
Gitea Actions 9a555f2be1 Auto-update blog content from Obsidian: 2026-10-18 13:39:26
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Skipped
2026-10-18 13:39:26 +00:00
Gitea Actions ee35da62d8 Auto-update blog content from Obsidian: 2026-10-18 08:59:50
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 21s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-10-18 08:59:50 +00:00
Gitea Actions a042099223 Auto-update blog content from Obsidian: 2026-10-14 21:11:40
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 14s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 1s
2026-10-14 21:11:40 +00:00
Gitea Actions b06572f376 Auto-update blog content from Obsidian: 2026-10-14 21:05:30
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-10-14 21:05:30 +00:00
Gitea Actions 0beb470cde Auto-update blog content from Obsidian: 2026-10-14 21:00:50
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 1s
2026-10-14 21:00:50 +00:00
Gitea Actions dffba69632 Auto-update blog content from Obsidian: 2026-10-14 20:18:35
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
2026-10-14 20:18:35 +00:00
Vezpi 2785900d4f Merge branch 'preview'
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 7s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 24s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Notify (push) Successful in 2s
2026-10-14 18:56:39 +00:00
VezpiandGitea Actions 90451c07c3 feat: use dart sass instead of libsass (#17)
Co-authored-by: Gitea Actions <actions@local>
Reviewed-on: #17
2026-10-14 20:54:36 +02:00
Gitea Actions d844a331be Auto-update blog content from Obsidian: 2026-10-14 12:21:59
Blog Deployment / Build (push) Successful in 32s
Blog Deployment / Deploy-Staging (push) Failing after 15s
Blog Deployment / Test-Staging (push) Skipped
Blog Deployment / Merge (push) Skipped
Blog Deployment / Deploy-Production (push) Skipped
Blog Deployment / Test-Production (push) Skipped
Blog Deployment / Clean (push) Skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Notify (push) Successful in 4s
2026-10-14 12:21:59 +00:00
Gitea Actions 634c579ac5 Auto-update blog content from Obsidian: 2026-10-01 21:17:09
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Successful in 49s
Blog Deployment / Deploy-Staging (push) Successful in 27s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 29s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 3s
2026-10-01 21:17:09 +00:00
Gitea Actions e416769280 Auto-update blog content from Obsidian: 2026-09-27 21:18:29
Blog Deployment / Deploy-Staging (push) Successful in 16s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
2026-09-27 21:18:29 +00:00
Gitea Actions 28bc4a8c13 Auto-update blog content from Obsidian: 2026-09-27 21:13:20
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 17s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 16s
2026-09-27 21:13:20 +00:00
Gitea Actions a222745af2 Auto-update blog content from Obsidian: 2026-09-27 20:57:07
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 18s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 17s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
2026-09-27 20:57:07 +00:00
Gitea Actions f2ca91361c Auto-update blog content from Obsidian: 2026-09-20 19:00:58
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 16s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 17s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
2026-09-20 19:00:58 +00:00
Gitea Actions 0501815481 Auto-update blog content from Obsidian: 2026-09-20 18:54:54
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 17s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
2026-09-20 18:54:54 +00:00
Gitea Actions a24e95ff7c Auto-update blog content from Obsidian: 2026-09-19 21:43:07
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 16s
Blog Deployment / Build (push) Skipped
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
2026-09-19 21:43:07 +00:00
Gitea Actions 5f87c0dabf Auto-update blog content from Obsidian: 2026-09-19 21:42:13
Blog Deployment / Deploy-Staging (push) Successful in 16s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 18s
2026-09-19 21:42:13 +00:00
Gitea Actions 511d4a7718 Auto-update blog content from Obsidian: 2026-09-19 20:42:22
Blog Deployment / Check-Rebuild (push) Successful in 12s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 17s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 3s
2026-09-19 20:42:22 +00:00
Gitea Actions 4784b46dfa Auto-update blog content from Obsidian: 2026-09-18 21:21:03
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 18s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Notify (push) Successful in 2s
2026-09-18 21:21:03 +00:00
Gitea Actions 61d870afcd Auto-update blog content from Obsidian: 2026-09-16 11:38:12
Blog Deployment / Deploy-Production (push) Successful in 31s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 31s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
2026-09-16 11:38:12 +00:00
Vezpi 81f032031b feat: leverage healthcheck (#16)
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
Reviewed-on: #16
2026-09-16 11:24:25 +02:00
Vezpi 246ba7bf07 feat: use persistent hugo resources folder (#15)
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Merge (push) Successful in 10s
Blog Deployment / Build (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 45s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
Reviewed-on: #15
2026-09-16 10:55:40 +02:00
Gitea Actions a4c8a3215f Auto-update blog content from Obsidian: 2026-09-16 06:49:51
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Skipped
Blog Deployment / Deploy-Production (push) Skipped
Blog Deployment / Test-Production (push) Skipped
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-16 06:49:51 +00:00
Gitea Actions 1ac0e63ddf Auto-update blog content from Obsidian: 2026-09-16 06:38:47
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 37s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Skipped
2026-09-16 06:38:47 +00:00
Gitea Actions c14cb6b00b Auto-update blog content from Obsidian: 2026-09-14 12:13:14
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 1s
2026-09-14 12:13:14 +00:00
Gitea Actions cd29c474c8 Auto-update blog content from Obsidian: 2026-09-14 11:13:09
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 1s
2026-09-14 11:13:09 +00:00
Gitea Actions 495b650d25 Auto-update blog content from Obsidian: 2026-09-14 09:51:29
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Skipped
2026-09-14 09:51:29 +00:00
Gitea Actions 5c10bad790 Auto-update blog content from Obsidian: 2026-09-14 09:35:02
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 33s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 1s
2026-09-14 09:35:02 +00:00
Gitea Actions f92688be0f Auto-update blog content from Obsidian: 2026-09-14 09:27:41
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-14 09:27:41 +00:00
Gitea Actions 10d1ea8f9b Auto-update blog content from Obsidian: 2026-09-14 09:14:20
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-14 09:14:20 +00:00
Gitea Actions b86691b3bf Auto-update blog content from Obsidian: 2026-09-14 06:57:34
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-14 06:57:34 +00:00
Gitea Actions 1632d1a3f7 Auto-update blog content from Obsidian: 2026-09-13 21:54:50
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 45s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-09-13 21:54:50 +00:00
Vezpi 6ab502e9d9 add: if always for Deploy-Staging step
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Skipped
Blog Deployment / Deploy-Production (push) Skipped
Blog Deployment / Test-Production (push) Skipped
Blog Deployment / Clean (push) Skipped
2026-09-13 21:36:46 +00:00
Vezpi 838d360a90 remove: if condition for Deploy-Staging step
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Skipped
Blog Deployment / Test-Staging (push) Skipped
Blog Deployment / Merge (push) Skipped
Blog Deployment / Deploy-Production (push) Skipped
Blog Deployment / Test-Production (push) Skipped
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-13 21:29:45 +00:00
Gitea Actions 648c7b94dc Auto-update blog content from Obsidian: 2026-09-13 21:09:40
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Skipped
Blog Deployment / Deploy-Staging (push) Skipped
Blog Deployment / Test-Staging (push) Skipped
Blog Deployment / Merge (push) Skipped
Blog Deployment / Deploy-Production (push) Skipped
Blog Deployment / Test-Production (push) Skipped
Blog Deployment / Clean (push) Skipped
Blog Deployment / Notify (push) Successful in 2s
2026-09-13 21:09:40 +00:00
Gitea Actions 576371646f Auto-update blog content from Obsidian: 2026-09-13 20:22:22
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Successful in 28s
Blog Deployment / Test-Staging (push) Successful in 33s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 36s
Blog Deployment / Merge (push) Successful in 13s
Blog Deployment / Notify (push) Successful in 2s
2026-09-13 20:22:22 +00:00
Gitea Actions 3e25cf0b48 Auto-update blog content from Obsidian: 2026-08-21 20:36:36
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-08-21 20:36:36 +00:00
Gitea Actions 79391d97ef Auto-update blog content from Obsidian: 2026-08-21 20:31:22
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 25s
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 33s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-08-21 20:31:22 +00:00
Gitea Actions 091b3b8e29 Auto-update blog content from Obsidian: 2026-08-21 07:25:55
Blog Deployment / Check-Rebuild (push) Failing after 2s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-08-21 07:25:55 +00:00
Gitea Actions 64c29c71db Auto-update blog content from Obsidian: 2026-08-01 20:55:28
Blog Deployment / Check-Rebuild (push) Successful in 14s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 46s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 14s
Blog Deployment / Deploy-Production (push) Successful in 49s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-08-01 20:55:28 +00:00
Gitea Actions d7523ba978 Auto-update blog content from Obsidian: 2026-07-19 21:21:41
Blog Deployment / Check-Rebuild (push) Successful in 13s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 49s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 14s
Blog Deployment / Deploy-Production (push) Successful in 47s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-07-19 21:21:41 +00:00
Gitea Actions 400f4abf95 Auto-update blog content from Obsidian: 2026-07-18 22:26:17
Blog Deployment / Check-Rebuild (push) Successful in 11s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 49s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 15s
Blog Deployment / Deploy-Production (push) Successful in 49s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-07-18 22:26:17 +00:00
Gitea Actions 3240e029fa Auto-update blog content from Obsidian: 2026-07-18 21:26:18
Blog Deployment / Check-Rebuild (push) Successful in 13s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 15s
Blog Deployment / Deploy-Production (push) Successful in 35s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-07-18 21:26:18 +00:00
Gitea Actions 57768b598f Auto-update blog content from Obsidian: 2026-06-09 20:24:47
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 35s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-06-09 20:24:47 +00:00
Gitea Actions 2fac832345 Auto-update blog content from Obsidian: 2026-06-09 20:17:47
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 35s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
2026-06-09 20:17:47 +00:00
Gitea Actions bd6934ee8e Auto-update blog content from Obsidian: 2026-06-09 19:39:07
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 30s
Blog Deployment / Deploy-Staging (push) Successful in 34s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 3s
2026-06-09 19:39:07 +00:00
Vezpi e41c25b64f feat: secure docker image removal
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 35s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-05-25 13:47:56 +00:00
Vezpi ce1c7e36bb feat: reduce the sleep to 30s
Blog Test / Check-Rebuild (push) Successful in 6s
Blog Test / Build (push) Successful in 7s
Blog Test / Deploy-Test (push) Successful in 36s
Blog Test / Test (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 7s
Blog Deployment / Deploy-Staging (push) Successful in 35s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 34s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Failing after 2s
Blog Deployment / Notify (push) Successful in 3s
2026-05-25 13:30:26 +00:00
Vezpi 6a4fdcb6ff fix: corrected new sleep timer to 60 for test pipeline
Blog Test / Check-Rebuild (push) Successful in 6s
Blog Test / Build (push) Successful in 8s
Blog Test / Deploy-Test (push) Successful in 1m3s
Blog Test / Test (push) Successful in 2s
2026-05-25 13:27:35 +00:00
Vezpi 07ce7c58ef feat: remove deprecation workaround
Blog Test / Check-Rebuild (push) Successful in 6s
Blog Test / Build (push) Successful in 36s
Blog Test / Deploy-Test (push) Successful in 8s
Blog Test / Test (push) Failing after 3s
2026-05-25 13:18:04 +00:00
Gitea Actions bd121d794c Auto-update blog content from Obsidian: 2026-05-24 21:07:44
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m3s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 1m3s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Test / Check-Rebuild (push) Successful in 7s
Blog Test / Build (push) Has been skipped
Blog Test / Deploy-Test (push) Failing after 4s
Blog Test / Test (push) Has been skipped
2026-05-24 21:07:44 +00:00
Gitea Actions 19258d081c Auto-update blog content from Obsidian: 2026-05-24 20:58:30
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m4s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 1m4s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-05-24 20:58:30 +00:00
Gitea Actions 40ec16e974 Auto-update blog content from Obsidian: 2026-05-24 20:12:49
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 1m3s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m3s
Blog Deployment / Test-Staging (push) Successful in 2s
2026-05-24 20:12:49 +00:00
Gitea Actions 8e4e4601d7 Auto-update blog content from Obsidian: 2026-05-24 19:12:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m4s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 1m5s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-05-24 19:12:42 +00:00
Gitea Actions 8facd6010b Auto-update blog content from Obsidian: 2026-05-24 14:31:31
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Production (push) Successful in 1m4s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 1m4s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-05-24 14:31:31 +00:00
Gitea Actions 49631bbabc Auto-update blog content from Obsidian: 2026-05-24 13:31:24
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m4s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 1m5s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-05-24 13:31:24 +00:00
Gitea Actions 0e81ddf7ed Auto-update blog content from Obsidian: 2026-05-24 12:30:51
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m5s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 1m4s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-05-24 12:30:51 +00:00
Vezpi a01f4dcf4e fix: typo
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 1m4s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 1m4s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-05-02 17:09:10 +00:00
Vezpi 8d88e5c87f change: wait 60s before showing logs
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 7s
Blog Deployment / Deploy-Staging (push) Successful in 1m3s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 1m3s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-04-30 10:52:02 +00:00
Vezpi 7728af1cdb change: wait 15s before showing logs
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Build (push) Successful in 7s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-04-30 10:43:39 +00:00
Vezpi ab9a714b3e change: wait 10s before showing logs
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 9s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-04-30 10:39:30 +00:00
Vezpi 2a1debc648 add: i18n pagination 2026-04-30 10:38:27 +00:00
Vezpi ec54ddd1c3 fix: Locale
Blog Deployment / Check-Rebuild (push) Successful in 11s
Blog Deployment / Build (push) Successful in 25s
Blog Deployment / Deploy-Staging (push) Successful in 28s
Blog Deployment / Test-Staging (push) Failing after 6s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 26s
2026-04-29 22:20:45 +00:00
Vezpi 2b14785ea4 test: replace site by hugo
Blog Deployment / Check-Rebuild (push) Successful in 11s
Blog Deployment / Build (push) Successful in 16s
Blog Deployment / Deploy-Staging (push) Successful in 23s
Blog Deployment / Test-Staging (push) Failing after 15s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 20s
2026-04-29 22:15:24 +00:00
Vezpi b5612b24ee add: workaround for rss.xml
Blog Deployment / Check-Rebuild (push) Successful in 11s
Blog Deployment / Test-Staging (push) Failing after 17s
Blog Deployment / Build (push) Successful in 49s
Blog Deployment / Deploy-Staging (push) Successful in 48s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 17s
2026-04-29 22:07:00 +00:00
Vezpi 14f9160c3d add: workaround for LanguageCode
Blog Deployment / Check-Rebuild (push) Successful in 33s
Blog Deployment / Build (push) Successful in 27s
Blog Deployment / Deploy-Staging (push) Successful in 27s
Blog Deployment / Test-Staging (push) Failing after 6s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 8s
2026-04-29 22:02:00 +00:00
Vezpi 88cbc90fca add: workaround for LanguageDirection
Blog Deployment / Check-Rebuild (push) Successful in 11s
Blog Deployment / Build (push) Successful in 22s
Blog Deployment / Deploy-Staging (push) Successful in 33s
Blog Deployment / Test-Staging (push) Failing after 20s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 11s
2026-04-29 21:56:55 +00:00
Vezpi fb06ae4e93 update: stack theme
Blog Deployment / Test-Staging (push) Failing after 5s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
2026-04-29 21:27:21 +00:00
Vezpi 6403ffd8ba change: languageName by label
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2026-04-29 20:54:16 +00:00
Vezpi 3fb76c0caf change: languageCode by locale
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 4s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
2026-04-29 20:52:34 +00:00
Vezpi 18c318f31e delete: img folder in static
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-04-29 20:48:39 +00:00
Gitea Actions 4143724c86 Auto-update blog content from Obsidian: 2026-04-29 20:40:29
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
2026-04-29 20:40:29 +00:00
Gitea Actions 5936475f99 Auto-update blog content from Obsidian: 2026-04-29 19:59:52
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Successful in 31s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-04-29 19:59:52 +00:00
Vezpi c731b7eaf5 fix: refactor removal of old docker images
Blog Test / Check-Rebuild (push) Successful in 6s
Blog Test / Build (push) Has been skipped
Blog Test / Deploy-Test (push) Successful in 9s
Blog Test / Test (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-04-10 15:38:28 +02:00
Vezpi 4cc467b0db Merge branch 'main' into preview
Blog Test / Check-Rebuild (push) Successful in 8s
Blog Test / Build (push) Has been skipped
Blog Test / Deploy-Test (push) Successful in 10s
Blog Test / Test (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 16s
Blog Deployment / Build (push) Successful in 39s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 34s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2026-04-03 12:45:14 +00:00
Vezpi 1712356889 fix: no-redirect (#12)
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Failing after 8s
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Reviewed-on: #12
2026-04-03 14:43:06 +02:00
Vezpi 9a4f91dfbb Merge branch 'preview'
Blog Test / Check-Rebuild (push) Successful in 8s
Blog Test / Build (push) Has been skipped
Blog Test / Deploy-Test (push) Successful in 11s
Blog Test / Test (push) Successful in 3s
2026-04-03 11:35:51 +00:00
Vezpi eea734f2fe feat: create a dedicated dev pipeline (#10)
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Reviewed-on: #10
2026-04-03 13:33:18 +02:00
Vezpi c23735f94d fix/not-deploying-hugo-v159 (#9)
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 10s
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
Reviewed-on: #9
2026-04-03 10:02:12 +02:00
Vezpi 4c2265cde6 fix: revert to git clone instead of checkout
Blog Deployment / Check-Rebuild (push) Successful in 20s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Failing after 4s
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Notify (push) Successful in 5s
2026-03-30 10:49:02 +00:00
Vezpi 73bd106b02 feat: separate workflow for testing
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Failing after 5s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 5s
Blog Test / Check-Rebuild (push) Failing after 6s
Blog Test / Build (push) Has been skipped
Blog Test / Deploy-Test (push) Has been skipped
Blog Test / Test (push) Has been skipped
2026-03-30 08:05:52 +00:00
Gitea Actions e1012e2480 Auto-update blog content from Obsidian: 2026-03-13 18:19:09
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-03-13 18:19:09 +00:00
Gitea Actions 2edae8b301 Auto-update blog content from Obsidian: 2026-03-12 21:06:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-03-12 21:06:30 +00:00
Gitea Actions 44ba9fc8b4 Auto-update blog content from Obsidian: 2026-02-27 22:10:02
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 22:10:02 +00:00
Gitea Actions ef4a5aefd1 Auto-update blog content from Obsidian: 2026-02-27 22:01:25
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 22:01:25 +00:00
Gitea Actions 6fa0fed3c5 Auto-update blog content from Obsidian: 2026-02-27 21:30:47
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 21:30:47 +00:00
Gitea Actions 5fb57c5dc0 Auto-update blog content from Obsidian: 2026-02-27 20:30:37
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 20:30:37 +00:00
Gitea Actions 7d7ab3493c Auto-update blog content from Obsidian: 2026-02-27 19:30:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 19:30:30 +00:00
Gitea Actions 44b8f36979 Auto-update blog content from Obsidian: 2026-02-27 17:43:07
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 17:43:07 +00:00
Gitea Actions b388107289 Auto-update blog content from Obsidian: 2026-02-27 15:43:01
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-27 15:43:01 +00:00
Gitea Actions 68cbef5791 Auto-update blog content from Obsidian: 2026-02-27 13:02:25
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
2026-02-27 13:02:25 +00:00
Gitea Actions 48ff17c292 Auto-update blog content from Obsidian: 2026-02-26 22:52:19
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-26 22:52:19 +00:00
Gitea Actions d495546120 Auto-update blog content from Obsidian: 2026-02-26 22:06:14
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-26 22:06:14 +00:00
Gitea Actions 4d2f015de0 Auto-update blog content from Obsidian: 2026-02-25 19:40:02
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-02-25 19:40:02 +00:00
Gitea Actions 2fdbd11020 Auto-update blog content from Obsidian: 2026-02-24 18:56:22
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-24 18:56:22 +00:00
Gitea Actions 4f152bf733 Auto-update blog content from Obsidian: 2026-02-24 14:37:54
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-24 14:37:54 +00:00
Gitea Actions 08708e2c6c Auto-update blog content from Obsidian: 2026-02-24 13:37:37
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-24 13:37:37 +00:00
Gitea Actions 0b24515e7f Auto-update blog content from Obsidian: 2026-02-24 12:37:21
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-24 12:37:21 +00:00
Gitea Actions fc6c382c52 Auto-update blog content from Obsidian: 2026-02-24 10:34:56
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2026-02-24 10:34:56 +00:00
Gitea Actions 3048c96362 Auto-update blog content from Obsidian: 2026-02-24 09:34:43
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-24 09:34:43 +00:00
Gitea Actions 0ff5d0de9e Auto-update blog content from Obsidian: 2026-02-23 14:15:30
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-23 14:15:30 +00:00
Gitea Actions 3fce8381c5 Auto-update blog content from Obsidian: 2026-02-23 10:31:22
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-23 10:31:22 +00:00
Gitea Actions 53c3af0e11 Auto-update blog content from Obsidian: 2026-02-23 09:31:08
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-23 09:31:08 +00:00
Gitea Actions 437f03f496 Auto-update blog content from Obsidian: 2026-02-23 08:30:52
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-23 08:30:52 +00:00
Gitea Actions ae86e4299e Auto-update blog content from Obsidian: 2026-02-20 13:13:10
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-02-20 13:13:10 +00:00
Gitea Actions 4eaf78ada7 Auto-update blog content from Obsidian: 2026-02-16 13:41:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-16 13:41:48 +00:00
Gitea Actions 940bc95436 Auto-update blog content from Obsidian: 2026-02-14 16:23:07
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-02-14 16:23:07 +00:00
Gitea Actions 1266824a75 Auto-update blog content from Obsidian: 2026-02-09 09:49:05
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2026-02-09 09:49:05 +00:00
Gitea Actions 52cb5cf946 Auto-update blog content from Obsidian: 2026-02-09 09:36:32
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 1s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-02-09 09:36:32 +00:00
Gitea Actions 3bf8b55f9b Auto-update blog content from Obsidian: 2026-02-09 08:48:46
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 35s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Clean (push) Successful in 1s
Blog Deployment / Notify (push) Successful in 2s
2026-02-09 08:48:46 +00:00
Gitea Actions 2ec0509d55 Auto-update blog content from Obsidian: 2026-02-07 21:28:16
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-07 21:28:16 +00:00
Gitea Actions e9aef5e181 Auto-update blog content from Obsidian: 2026-02-07 14:23:43
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-07 14:23:43 +00:00
Gitea Actions 5919b95364 Auto-update blog content from Obsidian: 2026-02-07 13:53:31
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-07 13:53:31 +00:00
Gitea Actions 5829b3a198 Auto-update blog content from Obsidian: 2026-02-06 22:28:54
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-06 22:28:54 +00:00
Gitea Actions e088e8ab18 Auto-update blog content from Obsidian: 2026-02-06 21:55:10
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-06 21:55:10 +00:00
Gitea Actions ab7996e685 Auto-update blog content from Obsidian: 2026-02-06 14:57:50
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-06 14:57:50 +00:00
Gitea Actions 97b79cc592 Auto-update blog content from Obsidian: 2026-02-06 08:03:38
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2026-02-06 08:03:38 +00:00
Gitea Actions dfb50b5e9e Auto-update blog content from Obsidian: 2026-02-06 07:55:26
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-06 07:55:26 +00:00
Gitea Actions ea07c41c93 Auto-update blog content from Obsidian: 2026-02-05 14:24:33
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-05 14:24:33 +00:00
Gitea Actions d55e0e1724 Auto-update blog content from Obsidian: 2026-02-04 15:22:28
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-04 15:22:28 +00:00
Gitea Actions f609fda5a2 Auto-update blog content from Obsidian: 2026-02-04 10:21:41
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-04 10:21:41 +00:00
Gitea Actions 697af312f0 Auto-update blog content from Obsidian: 2026-02-04 09:21:24
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-04 09:21:24 +00:00
Gitea Actions 9c98652535 Auto-update blog content from Obsidian: 2026-02-04 08:21:10
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-04 08:21:10 +00:00
Gitea Actions dc6bf7b47d Auto-update blog content from Obsidian: 2026-02-03 15:00:18
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-03 15:00:18 +00:00
Gitea Actions 6f0b6363e0 Auto-update blog content from Obsidian: 2026-02-02 20:29:09
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2026-02-02 20:29:09 +00:00
Gitea Actions 80c05adf83 Auto-update blog content from Obsidian: 2026-02-02 19:55:52
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-02 19:55:52 +00:00
Gitea Actions 5213faad68 Auto-update blog content from Obsidian: 2026-02-02 17:55:37
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-02-02 17:55:37 +00:00
Gitea Actions 54569bc98b Auto-update blog content from Obsidian: 2026-02-02 15:39:09
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-02-02 15:39:09 +00:00
Gitea Actions e2b1e02c0a Auto-update blog content from Obsidian: 2026-02-02 14:39:10
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2026-02-02 14:39:10 +00:00
Gitea Actions e20fb0b37e Auto-update blog content from Obsidian: 2026-02-02 13:38:57
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 30s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-02-02 13:38:57 +00:00
Gitea Actions 1ea2845767 Auto-update blog content from Obsidian: 2026-01-31 22:07:40
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-01-31 22:07:40 +00:00
Gitea Actions 97c2ef3a85 Auto-update blog content from Obsidian: 2026-01-31 10:46:44
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-01-31 10:46:44 +00:00
Gitea Actions c206deeafb Auto-update blog content from Obsidian: 2026-01-30 21:54:43
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-01-30 21:54:43 +00:00
Gitea Actions c5c6557691 Auto-update blog content from Obsidian: 2026-01-30 21:32:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2026-01-30 21:32:42 +00:00
Gitea Actions 54d09bf788 Auto-update blog content from Obsidian: 2026-01-30 20:32:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 29s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2026-01-30 20:32:32 +00:00
Gitea Actions a741aebd3f Auto-update blog content from Obsidian: 2026-01-28 20:32:42
Blog Deployment / Check-Rebuild (push) Successful in 22s
Blog Deployment / Build (push) Successful in 54s
Blog Deployment / Deploy-Staging (push) Successful in 13s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 11s
Blog Deployment / Deploy-Production (push) Successful in 15s
Blog Deployment / Test-Production (push) Successful in 8s
Blog Deployment / Clean (push) Successful in 4s
Blog Deployment / Notify (push) Successful in 7s
2026-01-28 20:32:42 +00:00
Gitea Actions fd48512c1b Auto-update blog content from Obsidian: 2025-12-10 21:35:16
Blog Deployment / Check-Rebuild (push) Successful in 13s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 22s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 4s
Blog Deployment / Build (push) Successful in 32s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-12-10 21:35:16 +00:00
Gitea Actions d7ab8cdab3 Auto-update blog content from Obsidian: 2025-11-24 10:15:07
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-24 10:15:07 +00:00
Gitea Actions bc44f93c3f Auto-update blog content from Obsidian: 2025-11-20 20:53:52
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-20 20:53:52 +00:00
Gitea Actions 61309cfb4e Auto-update blog content from Obsidian: 2025-11-20 20:52:11
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-20 20:52:11 +00:00
Gitea Actions 50cc6c195a Auto-update blog content from Obsidian: 2025-11-20 20:50:20
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-20 20:50:20 +00:00
Gitea Actions c27bd9f906 Auto-update blog content from Obsidian: 2025-11-20 20:44:04
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-11-20 20:44:04 +00:00
Gitea Actions e495593cc1 Auto-update blog content from Obsidian: 2025-11-20 20:02:03
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
2025-11-20 20:02:03 +00:00
Gitea Actions dc9c6d7164 Auto-update blog content from Obsidian: 2025-11-20 19:53:59
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-11-20 19:53:59 +00:00
Gitea Actions ca68e911eb Auto-update blog content from Obsidian: 2025-11-20 19:39:23
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-20 19:39:23 +00:00
Gitea Actions 721e911258 Auto-update blog content from Obsidian: 2025-11-20 19:35:27
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-20 19:35:27 +00:00
Gitea Actions 09ed5ade30 Auto-update blog content from Obsidian: 2025-11-19 21:46:00
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-19 21:46:00 +00:00
Gitea Actions ddb46f8aa3 Auto-update blog content from Obsidian: 2025-11-17 22:38:59
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-17 22:38:59 +00:00
Gitea Actions 65af7bcee5 Auto-update blog content from Obsidian: 2025-11-17 22:37:32
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-17 22:37:32 +00:00
Gitea Actions 271fe23e23 Auto-update blog content from Obsidian: 2025-11-17 21:58:34
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-17 21:58:34 +00:00
Gitea Actions 5a2a530d32 Auto-update blog content from Obsidian: 2025-11-16 20:56:31
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-16 20:56:31 +00:00
Gitea Actions a88e3158c5 Auto-update blog content from Obsidian: 2025-11-16 20:53:15
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
2025-11-16 20:53:15 +00:00
Gitea Actions 4cd7c76c0a Auto-update blog content from Obsidian: 2025-11-16 18:45:45
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-16 18:45:45 +00:00
Gitea Actions 67d23c90ac Auto-update blog content from Obsidian: 2025-11-15 22:19:47
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-15 22:19:47 +00:00
Gitea Actions 36f1374128 Auto-update blog content from Obsidian: 2025-11-14 19:51:04
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-14 19:51:04 +00:00
Gitea Actions b801726508 Auto-update blog content from Obsidian: 2025-11-12 20:19:17
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-12 20:19:17 +00:00
Gitea Actions c87b9f4bc9 Auto-update blog content from Obsidian: 2025-11-11 22:50:23
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-11-11 22:50:23 +00:00
Gitea Actions 08a8b65a1d Auto-update blog content from Obsidian: 2025-11-11 20:49:53
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-11 20:49:53 +00:00
Gitea Actions ce1249a924 Auto-update blog content from Obsidian: 2025-11-11 19:49:48
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-11 19:49:48 +00:00
Gitea Actions 545720c4c0 Auto-update blog content from Obsidian: 2025-11-07 21:38:49
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-11-07 21:38:49 +00:00
Gitea Actions 2119cbf695 Auto-update blog content from Obsidian: 2025-11-07 19:38:18
Blog Deployment / Check-Rebuild (push) Successful in 12s
Blog Deployment / Build (push) Successful in 39s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 3s
2025-11-07 19:38:18 +00:00
Gitea Actions ce2288dabe Auto-update blog content from Obsidian: 2025-11-07 14:37:12
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-07 14:37:12 +00:00
Gitea Actions a1fa2c0d53 Auto-update blog content from Obsidian: 2025-11-07 13:37:01
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-07 13:37:01 +00:00
Gitea Actions bacb22987a Auto-update blog content from Obsidian: 2025-11-07 10:36:35
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-07 10:36:35 +00:00
Gitea Actions 4a20a913e0 Auto-update blog content from Obsidian: 2025-11-07 08:36:22
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Successful in 5s
2025-11-07 08:36:22 +00:00
Gitea Actions c5c6d9b91d Auto-update blog content from Obsidian: 2025-11-04 21:43:49
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-11-04 21:43:49 +00:00
Gitea Actions 236e9fa668 Auto-update blog content from Obsidian: 2025-11-04 21:37:02
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
2025-11-04 21:37:02 +00:00
Gitea Actions 35b8a8596f Auto-update blog content from Obsidian: 2025-11-04 21:30:44
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 21:30:44 +00:00
Gitea Actions d73aaad0b4 Auto-update blog content from Obsidian: 2025-11-04 21:26:16
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-11-04 21:26:16 +00:00
Gitea Actions c43d2af086 Auto-update blog content from Obsidian: 2025-11-04 21:22:05
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
2025-11-04 21:22:05 +00:00
Gitea Actions 011dbc7293 Auto-update blog content from Obsidian: 2025-11-04 21:16:26
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 21:16:26 +00:00
Gitea Actions 37025b683a Auto-update blog content from Obsidian: 2025-11-04 20:52:43
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 20:52:43 +00:00
Gitea Actions ef84e229b2 Auto-update blog content from Obsidian: 2025-11-04 19:52:37
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 19:52:37 +00:00
Gitea Actions 0598cf2a5f Auto-update blog content from Obsidian: 2025-11-04 18:52:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 18:52:30 +00:00
Gitea Actions e851ee9bd9 Auto-update blog content from Obsidian: 2025-11-04 14:55:05
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-04 14:55:05 +00:00
Gitea Actions 3389de98d8 Auto-update blog content from Obsidian: 2025-11-04 14:46:39
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 14:46:39 +00:00
Gitea Actions aa9077a47b Auto-update blog content from Obsidian: 2025-11-04 13:54:03
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-04 13:54:03 +00:00
Gitea Actions d888220239 Auto-update blog content from Obsidian: 2025-11-03 22:42:44
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-03 22:42:44 +00:00
Gitea Actions 44ddcb6589 Auto-update blog content from Obsidian: 2025-11-03 21:29:17
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-03 21:29:17 +00:00
Gitea Actions d3ad691387 Auto-update blog content from Obsidian: 2025-11-03 19:20:46
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-03 19:20:46 +00:00
Gitea Actions 57db4726d7 Auto-update blog content from Obsidian: 2025-11-03 11:17:20
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-03 11:17:20 +00:00
Gitea Actions 58856f4668 Auto-update blog content from Obsidian: 2025-11-02 08:44:06
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-02 08:44:06 +00:00
Gitea Actions 62833b288a Auto-update blog content from Obsidian: 2025-11-01 18:37:00
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-11-01 18:37:00 +00:00
Gitea Actions 739763bc9c Auto-update blog content from Obsidian: 2025-11-01 16:43:01
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-11-01 16:43:01 +00:00
Gitea Actions 8482223f48 Auto-update blog content from Obsidian: 2025-10-31 19:55:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-31 19:55:42 +00:00
Gitea Actions 302c6d1a46 Auto-update blog content from Obsidian: 2025-10-31 16:59:25
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-31 16:59:25 +00:00
Gitea Actions fbafb580a0 Auto-update blog content from Obsidian: 2025-10-29 20:21:07
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 13s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 10s
Blog Deployment / Deploy-Production (push) Successful in 16s
Blog Deployment / Test-Production (push) Successful in 5s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-10-29 20:21:07 +00:00
Gitea Actions 8ed82a75ab Auto-update blog content from Obsidian: 2025-10-28 10:38:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-28 10:38:32 +00:00
Gitea Actions b6b8083adb Auto-update blog content from Obsidian: 2025-10-27 20:28:54
Blog Deployment / Check-Rebuild (push) Successful in 10s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 13s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-10-27 20:28:54 +00:00
Gitea Actions b6e3849e06 Auto-update blog content from Obsidian: 2025-10-27 17:02:46
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-27 17:02:46 +00:00
Gitea Actions 356d6922d5 Auto-update blog content from Obsidian: 2025-10-26 20:56:09
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-26 20:56:09 +00:00
Gitea Actions 4178d55075 Auto-update blog content from Obsidian: 2025-10-24 20:19:14
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-24 20:19:14 +00:00
Gitea Actions 2d18d8e681 Auto-update blog content from Obsidian: 2025-10-24 17:08:08
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 27s
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-10-24 17:08:08 +00:00
Gitea Actions 72c9b26c68 Auto-update blog content from Obsidian: 2025-10-23 22:08:23
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-23 22:08:23 +00:00
Gitea Actions 2dede1bfb5 Auto-update blog content from Obsidian: 2025-10-23 19:44:06
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-23 19:44:06 +00:00
Gitea Actions 90c30b19c1 Auto-update blog content from Obsidian: 2025-10-22 20:05:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 20:05:48 +00:00
Gitea Actions 8dfda8ba2c Auto-update blog content from Obsidian: 2025-10-22 19:54:34
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 19:54:34 +00:00
Gitea Actions 65f4bc1794 Auto-update blog content from Obsidian: 2025-10-22 19:38:15
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-22 19:38:15 +00:00
Gitea Actions 3bfe8ca2fd Auto-update blog content from Obsidian: 2025-10-22 19:33:43
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-10-22 19:33:43 +00:00
Gitea Actions 09e1da30bc Auto-update blog content from Obsidian: 2025-10-22 19:28:12
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 28s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 19:28:12 +00:00
Gitea Actions 3247e5871c Auto-update blog content from Obsidian: 2025-10-22 19:25:53
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-22 19:25:53 +00:00
Gitea Actions f9d1260a28 Auto-update blog content from Obsidian: 2025-10-22 19:20:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Test-Staging (push) Successful in 3s
2025-10-22 19:20:42 +00:00
Gitea Actions fe5ff08667 Auto-update blog content from Obsidian: 2025-10-22 19:15:36
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-22 19:15:36 +00:00
Gitea Actions 46dfbd8bfe Auto-update blog content from Obsidian: 2025-10-22 19:11:35
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 11s
2025-10-22 19:11:35 +00:00
Gitea Actions a2b6c49379 Auto-update blog content from Obsidian: 2025-10-22 19:05:53
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 19:05:53 +00:00
Gitea Actions 32366df0a6 Auto-update blog content from Obsidian: 2025-10-22 19:00:52
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-22 19:00:52 +00:00
Gitea Actions 6647db993c Auto-update blog content from Obsidian: 2025-10-22 18:38:51
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-22 18:38:51 +00:00
Gitea Actions abb3dfef72 Auto-update blog content from Obsidian: 2025-10-22 17:54:33
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 17:54:33 +00:00
Gitea Actions 779734d642 Auto-update blog content from Obsidian: 2025-10-22 15:45:50
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-22 15:45:50 +00:00
Gitea Actions 490d77c76b Auto-update blog content from Obsidian: 2025-10-21 18:37:25
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-21 18:37:25 +00:00
Gitea Actions c5dabfcd87 Auto-update blog content from Obsidian: 2025-10-21 16:58:02
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-10-21 16:58:02 +00:00
Gitea Actions c60dc7aeb9 Auto-update blog content from Obsidian: 2025-10-20 20:02:27
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 20:02:27 +00:00
Gitea Actions 99bea3a191 Auto-update blog content from Obsidian: 2025-10-20 18:53:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 18:53:48 +00:00
Gitea Actions 3b5699eecb Auto-update blog content from Obsidian: 2025-10-20 16:08:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 16:08:48 +00:00
Gitea Actions e061db89f3 Auto-update blog content from Obsidian: 2025-10-20 15:55:29
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 15:55:29 +00:00
Gitea Actions b54a3580e3 Auto-update blog content from Obsidian: 2025-10-20 14:16:10
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 14:16:10 +00:00
Gitea Actions f6dc6256af Auto-update blog content from Obsidian: 2025-10-20 13:46:04
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 13:46:04 +00:00
Gitea Actions 64aeae8c4a Auto-update blog content from Obsidian: 2025-10-20 12:44:14
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 12:44:14 +00:00
Gitea Actions e5f2430d23 Auto-update blog content from Obsidian: 2025-10-20 12:31:02
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 12:31:02 +00:00
Gitea Actions 6231ef83c2 Auto-update blog content from Obsidian: 2025-10-20 11:55:47
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
2025-10-20 11:55:47 +00:00
Gitea Actions ca85848041 Auto-update blog content from Obsidian: 2025-10-20 10:37:04
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 10:37:04 +00:00
Gitea Actions 7d4be00d18 Auto-update blog content from Obsidian: 2025-10-20 10:03:04
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 10:03:04 +00:00
Gitea Actions 753f72b862 Auto-update blog content from Obsidian: 2025-10-20 09:31:36
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 09:31:36 +00:00
Gitea Actions 8c293620d7 Auto-update blog content from Obsidian: 2025-10-20 09:01:24
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 13s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-10-20 09:01:24 +00:00
Gitea Actions a98b2fefd0 Auto-update blog content from Obsidian: 2025-10-20 08:53:26
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 08:53:26 +00:00
Gitea Actions a5e0ed1c1b Auto-update blog content from Obsidian: 2025-10-20 08:22:51
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 08:22:51 +00:00
Gitea Actions 09b192536c Auto-update blog content from Obsidian: 2025-10-20 08:05:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 08:05:48 +00:00
Gitea Actions f254c610b4 Auto-update blog content from Obsidian: 2025-10-20 07:57:22
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 07:57:22 +00:00
Gitea Actions 5f0498ad50 Auto-update blog content from Obsidian: 2025-10-20 07:52:28
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 07:52:28 +00:00
Gitea Actions e1f21161d3 Auto-update blog content from Obsidian: 2025-10-20 07:47:18
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 07:47:18 +00:00
Gitea Actions 68849fc3f4 Auto-update blog content from Obsidian: 2025-10-20 07:42:18
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-20 07:42:18 +00:00
Gitea Actions e15451dbec Auto-update blog content from Obsidian: 2025-10-20 07:37:14
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 07:37:14 +00:00
Gitea Actions ebc97e13e1 Auto-update blog content from Obsidian: 2025-10-20 07:31:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 07:31:42 +00:00
Gitea Actions 81048128f0 Auto-update blog content from Obsidian: 2025-10-20 06:44:25
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-20 06:44:25 +00:00
Gitea Actions 98606abce1 Auto-update blog content from Obsidian: 2025-10-20 06:21:54
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
2025-10-20 06:21:54 +00:00
Gitea Actions 28e9aaa073 Auto-update blog content from Obsidian: 2025-10-19 22:15:56
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-19 22:15:56 +00:00
Gitea Actions 11003e6a46 Auto-update blog content from Obsidian: 2025-10-19 21:55:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-19 21:55:30 +00:00
Gitea Actions 9f01e48774 Auto-update blog content from Obsidian: 2025-10-19 20:52:19
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-19 20:52:19 +00:00
Gitea Actions 364fb2a653 Auto-update blog content from Obsidian: 2025-10-19 19:47:25
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-19 19:47:25 +00:00
Gitea Actions 38e4826dd3 Auto-update blog content from Obsidian: 2025-10-19 19:14:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-19 19:14:32 +00:00
Gitea Actions c037b32887 Auto-update blog content from Obsidian: 2025-10-19 18:58:12
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
2025-10-19 18:58:12 +00:00
Gitea Actions 5ab146be02 Auto-update blog content from Obsidian: 2025-10-19 18:22:50
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-19 18:22:50 +00:00
Gitea Actions 9a6a4f7d93 Auto-update blog content from Obsidian: 2025-10-17 21:33:09
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 21:33:09 +00:00
Gitea Actions 80857d07a9 Auto-update blog content from Obsidian: 2025-10-17 21:18:33
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
2025-10-17 21:18:33 +00:00
Gitea Actions bca41ed138 Auto-update blog content from Obsidian: 2025-10-17 20:57:35
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 20:57:35 +00:00
Gitea Actions ec53bf807b Auto-update blog content from Obsidian: 2025-10-17 20:35:28
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 20:35:28 +00:00
Gitea Actions 46ef3307ad Auto-update blog content from Obsidian: 2025-10-17 19:53:34
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 19:53:34 +00:00
Gitea Actions 0a76af4175 Auto-update blog content from Obsidian: 2025-10-17 19:30:58
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-17 19:30:58 +00:00
Gitea Actions 67480f64f4 Auto-update blog content from Obsidian: 2025-10-17 19:19:37
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 19:19:37 +00:00
Gitea Actions 7083e449f3 Auto-update blog content from Obsidian: 2025-10-17 18:53:28
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-17 18:53:28 +00:00
Gitea Actions e55b24825f Auto-update blog content from Obsidian: 2025-10-16 21:08:42
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-10-16 21:08:42 +00:00
Gitea Actions b61ae7c295 Auto-update blog content from Obsidian: 2025-10-16 20:54:29
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-16 20:54:29 +00:00
Gitea Actions 13e0d3467f Auto-update blog content from Obsidian: 2025-10-16 20:18:33
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 28s
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-10-16 20:18:33 +00:00
Gitea Actions 85a0cd3c3c Auto-update blog content from Obsidian: 2025-10-15 20:56:15
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 20:56:15 +00:00
Gitea Actions 473047d709 Auto-update blog content from Obsidian: 2025-10-15 20:42:40
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 20:42:40 +00:00
Gitea Actions fa394086d5 Auto-update blog content from Obsidian: 2025-10-15 20:06:35
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 20:06:35 +00:00
Gitea Actions 07bd9782a9 Auto-update blog content from Obsidian: 2025-10-15 19:55:19
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-10-15 19:55:19 +00:00
Gitea Actions 05220fcd0b Auto-update blog content from Obsidian: 2025-10-15 19:48:35
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 19:48:35 +00:00
Gitea Actions ecf1040879 Auto-update blog content from Obsidian: 2025-10-15 19:36:50
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 19:36:50 +00:00
Gitea Actions 13b9b0810a Auto-update blog content from Obsidian: 2025-10-15 19:27:09
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 19:27:09 +00:00
Gitea Actions 064c5d6533 Auto-update blog content from Obsidian: 2025-10-15 19:08:35
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 28s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-10-15 19:08:35 +00:00
Gitea Actions 9a6f36ca21 Auto-update blog content from Obsidian: 2025-10-15 08:09:42
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-15 08:09:42 +00:00
Gitea Actions 7d531756e2 Auto-update blog content from Obsidian: 2025-10-13 19:51:23
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-13 19:51:23 +00:00
Gitea Actions 9915a36aa3 Auto-update blog content from Obsidian: 2025-10-13 19:32:03
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-13 19:32:03 +00:00
Gitea Actions 4e2b73da88 Auto-update blog content from Obsidian: 2025-10-13 19:21:47
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-13 19:21:47 +00:00
Gitea Actions 8319641211 Auto-update blog content from Obsidian: 2025-10-13 19:12:08
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-13 19:12:08 +00:00
Gitea Actions ec736f9de9 Auto-update blog content from Obsidian: 2025-10-13 19:01:45
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-13 19:01:45 +00:00
Gitea Actions 8e33b2aa95 Auto-update blog content from Obsidian: 2025-10-13 14:48:46
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-10-13 14:48:46 +00:00
Gitea Actions 942fa38fa0 Auto-update blog content from Obsidian: 2025-10-13 13:35:45
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-13 13:35:45 +00:00
Gitea Actions 42e6965f95 Auto-update blog content from Obsidian: 2025-10-12 20:52:17
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-12 20:52:17 +00:00
Gitea Actions 0eb34ed4f8 Auto-update blog content from Obsidian: 2025-10-12 20:46:49
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-12 20:46:49 +00:00
Gitea Actions 7116b44075 Auto-update blog content from Obsidian: 2025-10-12 20:31:01
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 20:31:01 +00:00
Gitea Actions 76d707ac15 Auto-update blog content from Obsidian: 2025-10-12 20:20:31
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 20:20:31 +00:00
Gitea Actions 4f9d56bd38 Auto-update blog content from Obsidian: 2025-10-12 19:29:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 26s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 34s
2025-10-12 19:29:32 +00:00
Gitea Actions 9ff3891659 Auto-update blog content from Obsidian: 2025-10-12 19:19:05
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 19:19:05 +00:00
Gitea Actions faa1655597 Auto-update blog content from Obsidian: 2025-10-12 19:07:54
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 19:07:54 +00:00
Gitea Actions 3b55a96d88 Auto-update blog content from Obsidian: 2025-10-12 17:20:19
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-10-12 17:20:19 +00:00
Gitea Actions 0644be25dc Auto-update blog content from Obsidian: 2025-10-12 13:49:47
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-10-12 13:49:47 +00:00
Gitea Actions 7416866cad Auto-update blog content from Obsidian: 2025-10-12 13:32:59
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 13:32:59 +00:00
Gitea Actions 976ebd1d80 Auto-update blog content from Obsidian: 2025-10-12 13:08:11
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-12 13:08:11 +00:00
Gitea Actions 26604b3035 Auto-update blog content from Obsidian: 2025-10-12 12:42:51
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-12 12:42:51 +00:00
Gitea Actions b8fd471372 Auto-update blog content from Obsidian: 2025-10-11 20:30:11
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-11 20:30:11 +00:00
Gitea Actions 9eade305ad Auto-update blog content from Obsidian: 2025-10-11 19:56:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-11 19:56:32 +00:00
Gitea Actions 372cb53c54 Auto-update blog content from Obsidian: 2025-10-10 21:19:13
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-10-10 21:19:13 +00:00
Gitea Actions fc88903a3b Auto-update blog content from Obsidian: 2025-10-10 21:11:12
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-10 21:11:12 +00:00
Gitea Actions f9624cf14a Auto-update blog content from Obsidian: 2025-10-10 20:47:50
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 13s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-10 20:47:50 +00:00
Gitea Actions f2c691aa0a Auto-update blog content from Obsidian: 2025-10-10 20:23:11
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-10-10 20:23:11 +00:00
Gitea Actions 9cdfe58197 Auto-update blog content from Obsidian: 2025-09-29 13:13:12
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-29 13:13:12 +00:00
Gitea Actions fd2827e0a8 Auto-update blog content from Obsidian: 2025-09-29 12:59:15
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-29 12:59:15 +00:00
Gitea Actions ea325bed60 Auto-update blog content from Obsidian: 2025-09-29 12:48:42
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-09-29 12:48:42 +00:00
Gitea Actions ac4d3b9a45 Auto-update blog content from Obsidian: 2025-09-29 12:46:07
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-29 12:46:07 +00:00
Gitea Actions 8c340d6e8a Auto-update blog content from Obsidian: 2025-09-29 10:36:20
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-29 10:36:20 +00:00
Gitea Actions 0d9befcb8d Auto-update blog content from Obsidian: 2025-09-29 07:34:49
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-09-29 07:34:49 +00:00
Gitea Actions aeb2d33162 Auto-update blog content from Obsidian: 2025-09-29 05:35:26
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-29 05:35:26 +00:00
Gitea Actions 62f267dad4 Auto-update blog content from Obsidian: 2025-09-28 17:28:00
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-28 17:28:00 +00:00
Gitea Actions 452f4497b2 Auto-update blog content from Obsidian: 2025-09-27 20:50:37
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-27 20:50:37 +00:00
Gitea Actions 89ebf0ddcc Auto-update blog content from Obsidian: 2025-09-27 18:11:45
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-27 18:11:45 +00:00
Gitea Actions ba4d20b861 Auto-update blog content from Obsidian: 2025-09-25 09:02:08
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-25 09:02:08 +00:00
Gitea Actions 95512dc407 Auto-update blog content from Obsidian: 2025-09-25 05:51:17
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-09-25 05:51:17 +00:00
Gitea Actions d635eeffc4 Auto-update blog content from Obsidian: 2025-09-23 20:47:40
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-23 20:47:40 +00:00
Gitea Actions e0d7ec4bde Auto-update blog content from Obsidian: 2025-09-23 08:48:08
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-23 08:48:08 +00:00
Gitea Actions 6c2856e935 Auto-update blog content from Obsidian: 2025-09-22 15:10:01
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-22 15:10:01 +00:00
Gitea Actions 2b3cc8d687 Auto-update blog content from Obsidian: 2025-09-18 11:52:25
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-18 11:52:25 +00:00
Gitea Actions 11137262a1 Auto-update blog content from Obsidian: 2025-09-17 21:24:37
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-17 21:24:37 +00:00
Gitea Actions 41c3a7d7a9 Auto-update blog content from Obsidian: 2025-09-16 09:17:55
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-09-16 09:17:55 +00:00
Gitea Actions e1cd58ed50 Auto-update blog content from Obsidian: 2025-09-15 20:29:58
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-09-15 20:29:58 +00:00
Gitea Actions 3144fd29f7 Auto-update blog content from Obsidian: 2025-09-14 10:43:59
Blog Deployment / Check-Rebuild (push) Successful in 17s
Blog Deployment / Build (push) Successful in 29s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-09-14 10:43:59 +00:00
Gitea Actions 29b9af9085 Auto-update blog content from Obsidian: 2025-09-12 09:53:54
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-09-12 09:53:54 +00:00
Gitea Actions 90bb1ba3b3 Auto-update blog content from Obsidian: 2025-09-12 09:47:06
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Test-Production (push) Successful in 2s
2025-09-12 09:47:06 +00:00
Gitea Actions 0f70fab68a Auto-update blog content from Obsidian: 2025-09-12 08:59:00
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 5s
2025-09-12 08:59:00 +00:00
Gitea Actions 61697ad237 Auto-update blog content from Obsidian: 2025-09-12 07:29:29
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 7s
2025-09-12 07:29:29 +00:00
Gitea Actions 097d088847 Auto-update blog content from Obsidian: 2025-09-12 06:29:39
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-12 06:29:39 +00:00
Gitea Actions f99d986f3a Auto-update blog content from Obsidian: 2025-09-11 20:44:48
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-11 20:44:48 +00:00
Gitea Actions 548d9a37b5 Auto-update blog content from Obsidian: 2025-09-11 19:44:34
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-11 19:44:34 +00:00
Gitea Actions fe8656f9df Auto-update blog content from Obsidian: 2025-09-11 18:44:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-11 18:44:30 +00:00
Gitea Actions 9578f503be Auto-update blog content from Obsidian: 2025-09-11 07:01:31
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-11 07:01:31 +00:00
Gitea Actions ed94d0adc5 Auto-update blog content from Obsidian: 2025-09-10 18:33:51
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-10 18:33:51 +00:00
Gitea Actions 593954a59f Auto-update blog content from Obsidian: 2025-09-10 11:20:27
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-09-10 11:20:27 +00:00
Gitea Actions 8928bfde23 Auto-update blog content from Obsidian: 2025-09-10 09:48:40
Blog Deployment / Check-Rebuild (push) Successful in 19s
Blog Deployment / Build (push) Successful in 40s
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-09-10 09:48:40 +00:00
Vezpi 8078a6afb3 chore: remove lock
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 8s
2025-09-08 08:09:13 +00:00
Vezpi e440b075ea feat: add noindex on taxonomy and term pages
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-09-08 07:53:15 +00:00
Vezpi d027da53a2 debug: change debug as meta
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-09-05 12:29:40 +00:00
Vezpi 5548718ba6 debug: add debug kind in all pages
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-09-05 12:17:34 +00:00
Vezpi 720b4b6ce1 feat: change analytic domain for vezpi.com
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 13s
Blog Deployment / Test-Production (push) Successful in 6s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 5s
2025-09-04 12:09:39 +00:00
Gitea Actions 759b06b28e Auto-update blog content from Obsidian: 2025-09-04 11:50:11
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
Blog Deployment / Test-Production (push) Successful in 4s
2025-09-04 11:50:11 +00:00
Vezpi c4bd44e1f2 change: git repo in the entrypoint.sh vezpi.com
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 16s
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 16s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 8s
Blog Deployment / Clean (push) Successful in 5s
Blog Deployment / Notify (push) Successful in 5s
2025-09-04 11:38:19 +00:00
Vezpi a3d24345aa change: domain root vezpi.com
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-09-04 11:32:12 +00:00
Vezpi 34bc536396 change: ntfy URL to vezpi.com
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 10s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-09-03 19:35:46 +00:00
Vezpi ada377ef8e feat: add rm blog dir in init script
Blog Deployment / Check-Rebuild (push) Successful in 21s
Blog Deployment / Merge (push) Successful in 10s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 4s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Build (push) Successful in 49s
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 42s
2025-09-01 18:25:50 +00:00
Gitea Actions a71cba5e61 Auto-update blog content from Obsidian: 2025-08-26 18:41:22
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-08-26 18:41:22 +00:00
Gitea Actions 2c5f8e14dd Auto-update blog content from Obsidian: 2025-08-24 08:11:28
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-08-24 08:11:28 +00:00
Gitea Actions 5456a2f998 Auto-update blog content from Obsidian: 2025-08-24 07:59:39
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-08-24 07:59:39 +00:00
Gitea Actions 2376b15d9d Auto-update blog content from Obsidian: 2025-08-24 07:56:38
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-08-24 07:56:38 +00:00
Gitea Actions 6d95ce333b Auto-update blog content from Obsidian: 2025-08-24 07:40:43
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-08-24 07:40:43 +00:00
Gitea Actions 098d38e1d6 Auto-update blog content from Obsidian: 2025-08-22 19:12:29
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-08-22 19:12:29 +00:00
Gitea Actions ea236c3865 Auto-update blog content from Obsidian: 2025-08-22 11:03:27
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-08-22 11:03:27 +00:00
Gitea Actions 921ceb6ce0 Auto-update blog content from Obsidian: 2025-08-22 09:21:52
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-08-22 09:21:52 +00:00
Gitea Actions 6e6d16e474 Auto-update blog content from Obsidian: 2025-08-19 14:01:03
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
Blog Deployment / Deploy-Production (push) Successful in 12s
2025-08-19 14:01:03 +00:00
Gitea Actions 1a8ca54ada Auto-update blog content from Obsidian: 2025-08-19 12:11:03
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 5s
2025-08-19 12:11:03 +00:00
Gitea Actions 650808a9c0 Auto-update blog content from Obsidian: 2025-08-18 15:19:50
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 24s
Blog Deployment / Test-Production (push) Successful in 10s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 10s
Blog Deployment / Merge (push) Successful in 8s
2025-08-18 15:19:50 +00:00
Gitea Actions a160e45ff3 Auto-update blog content from Obsidian: 2025-08-14 09:55:04
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 14s
Blog Deployment / Test-Staging (push) Successful in 4s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 13s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-08-14 09:55:04 +00:00
Gitea Actions 03bbd72ede Auto-update blog content from Obsidian: 2025-08-04 19:23:43
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-08-04 19:23:43 +00:00
Gitea Actions ab14c4bcf7 Auto-update blog content from Obsidian: 2025-08-03 18:22:37
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 13s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 28s
Blog Deployment / Test-Production (push) Successful in 12s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-08-03 18:22:37 +00:00
Gitea Actions 7e817a021e Auto-update blog content from Obsidian: 2025-07-31 10:47:50
Blog Deployment / Check-Rebuild (push) Successful in 13s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 21s
Blog Deployment / Test-Staging (push) Successful in 5s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-07-31 10:47:50 +00:00
Gitea Actions febb26e1e9 Auto-update blog content from Obsidian: 2025-07-31 09:15:10
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 12s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 8s
Blog Deployment / Deploy-Production (push) Successful in 12s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-07-31 09:15:10 +00:00
Gitea Actions 12db348a61 Auto-update blog content from Obsidian: 2025-07-29 09:18:22
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-07-29 09:18:22 +00:00
Gitea Actions 2ec49c1496 Auto-update blog content from Obsidian: 2025-07-29 06:57:19
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-29 06:57:19 +00:00
Gitea Actions b98c7dc534 Auto-update blog content from Obsidian: 2025-07-28 14:48:25
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-28 14:48:25 +00:00
Gitea Actions 4d06825dcf Auto-update blog content from Obsidian: 2025-07-28 11:26:10
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 10s
2025-07-28 11:26:10 +00:00
Gitea Actions bb422a47cb Auto-update blog content from Obsidian: 2025-07-28 08:28:30
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 11s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-28 08:28:30 +00:00
Gitea Actions 988319fc34 Auto-update blog content from Obsidian: 2025-07-28 07:12:20
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-28 07:12:20 +00:00
Gitea Actions 88f56d5b98 Auto-update blog content from Obsidian: 2025-07-28 06:07:37
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-28 06:07:37 +00:00
Gitea Actions c3d58d1b4e Auto-update blog content from Obsidian: 2025-07-27 13:56:27
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-07-27 13:56:27 +00:00
Gitea Actions 228c79a658 Auto-update blog content from Obsidian: 2025-07-22 09:58:07
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-07-22 09:58:07 +00:00
Gitea Actions f24a14164f Auto-update blog content from Obsidian: 2025-07-21 09:52:22
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-21 09:52:22 +00:00
Gitea Actions 12a0a997f1 Auto-update blog content from Obsidian: 2025-07-21 06:34:50
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-21 06:34:50 +00:00
Gitea Actions f861acac7f Auto-update blog content from Obsidian: 2025-07-18 21:18:35
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-18 21:18:35 +00:00
Gitea Actions f6b4affd1e Auto-update blog content from Obsidian: 2025-07-18 16:40:54
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-18 16:40:54 +00:00
Gitea Actions a14ad90979 Auto-update blog content from Obsidian: 2025-07-18 15:11:36
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-07-18 15:11:36 +00:00
Gitea Actions ec473f542d Auto-update blog content from Obsidian: 2025-07-18 14:37:16
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
2025-07-18 14:37:16 +00:00
Gitea Actions 3e0a0cfd47 Auto-update blog content from Obsidian: 2025-07-18 13:21:28
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-18 13:21:28 +00:00
Gitea Actions f272a529ee Auto-update blog content from Obsidian: 2025-07-18 11:38:30
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-18 11:38:30 +00:00
Gitea Actions de21e876d6 Auto-update blog content from Obsidian: 2025-07-18 08:23:42
Blog Deployment / Check-Rebuild (push) Successful in 18s
Blog Deployment / Build (push) Successful in 30s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-07-18 08:23:42 +00:00
Gitea Actions d91f1996a0 Auto-update blog content from Obsidian: 2025-07-18 06:24:08
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Test-Production (push) Successful in 2s
2025-07-18 06:24:08 +00:00
Gitea Actions 7e33d65bf6 Auto-update blog content from Obsidian: 2025-07-17 12:06:40
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 4s
2025-07-17 12:06:40 +00:00
Gitea Actions 372f7aa8ae Auto-update blog content from Obsidian: 2025-07-16 15:05:47
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-16 15:05:47 +00:00
Gitea Actions dc0c4ecfa6 Auto-update blog content from Obsidian: 2025-07-16 10:34:32
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 10s
2025-07-16 10:34:32 +00:00
Gitea Actions a1725ecfbb Auto-update blog content from Obsidian: 2025-07-07 07:10:43
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-07 07:10:43 +00:00
Gitea Actions 43c30b2903 Auto-update blog content from Obsidian: 2025-07-04 21:29:03
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-07-04 21:29:03 +00:00
Gitea Actions 207bc826db Auto-update blog content from Obsidian: 2025-07-04 21:23:42
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-04 21:23:42 +00:00
Gitea Actions b83d21103d Auto-update blog content from Obsidian: 2025-07-04 19:49:13
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-04 19:49:13 +00:00
Gitea Actions 2ba7e9d986 Auto-update blog content from Obsidian: 2025-07-02 11:37:58
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-07-02 11:37:58 +00:00
Gitea Actions a6e0968ea6 Auto-update blog content from Obsidian: 2025-07-02 05:59:23
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Merge (push) Successful in 5s
2025-07-02 05:59:23 +00:00
Gitea Actions c4ed7d6ea8 Auto-update blog content from Obsidian: 2025-07-01 20:14:02
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-07-01 20:14:02 +00:00
Gitea Actions cdd006cc09 Auto-update blog content from Obsidian: 2025-07-01 11:45:05
Blog Deployment / Check-Rebuild (push) Successful in 12s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 2s
2025-07-01 11:45:05 +00:00
Gitea Actions 5504c6bebf Auto-update blog content from Obsidian: 2025-06-27 08:17:03
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-27 08:17:03 +00:00
Gitea Actions 7ae7170478 Auto-update blog content from Obsidian: 2025-06-27 08:08:30
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-27 08:08:30 +00:00
Gitea Actions 4609fe6301 Auto-update blog content from Obsidian: 2025-06-27 08:02:08
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-27 08:02:08 +00:00
Gitea Actions d23643bd32 Auto-update blog content from Obsidian: 2025-06-27 07:52:01
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Build (push) Has been skipped
2025-06-27 07:52:01 +00:00
Gitea Actions bfb1dbf1d3 Auto-update blog content from Obsidian: 2025-06-27 07:24:19
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-27 07:24:19 +00:00
Gitea Actions a7fc4cae7b Auto-update blog content from Obsidian: 2025-06-27 06:43:17
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-27 06:43:17 +00:00
Gitea Actions a610bca89a Auto-update blog content from Obsidian: 2025-06-26 19:08:49
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-26 19:08:49 +00:00
Gitea Actions 93dfed6c5e Auto-update blog content from Obsidian: 2025-06-26 13:47:31
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-26 13:47:31 +00:00
Gitea Actions bebd72319b Auto-update blog content from Obsidian: 2025-06-25 20:57:29
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
2025-06-25 20:57:29 +00:00
Gitea Actions 3d34e7f5ee Auto-update blog content from Obsidian: 2025-06-25 15:27:27
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-25 15:27:27 +00:00
Vezpi 0be3fe6ec1 fix: merge workflow
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-24 21:10:09 +00:00
Vezpi 4fb227de56 merge to main
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Build (push) Has been skipped
2025-06-24 21:06:26 +00:00
Vezpi 23fb1992d6 remove: padding in homepage header
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 21:02:45 +00:00
Vezpi e7e889092d fix: use .Language.Lang
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:59:35 +00:00
Vezpi 3f7a2e47a0 change: edit toggle title
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:57:53 +00:00
Gitea Actions 3734c1ccf8 Auto-update blog content from Obsidian: 2025-06-24 20:53:05
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:53:05 +00:00
Vezpi c72b05f83e fix: forgot en menu
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-24 20:38:10 +00:00
Vezpi 1bf469c20a remove: git social and svgs
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:37:31 +00:00
Vezpi 58a16633f8 add: margin-left: auto
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 3s
2025-06-24 20:34:39 +00:00
Vezpi 5973472126 test: use custom scss for toggle icon
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:28:58 +00:00
Vezpi 2b651f14d3 test: use object instead of helper
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
2025-06-24 20:24:14 +00:00
Vezpi f4715e5262 fix: add a dev
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 6s
2025-06-24 20:11:55 +00:00
Vezpi 5e137ec974 fix: force li width to 64
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 20:05:27 +00:00
Vezpi 10d5bf3b76 fix: force width to 64
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-24 20:03:55 +00:00
Vezpi 93b6d5c4b0 fix: move style to li
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 19:56:58 +00:00
Vezpi c6c06bed87 fix: add style
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 19:53:54 +00:00
Vezpi 0ac571acf4 fix: syntax
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 19:48:18 +00:00
Vezpi 732bf86858 test: use svg instead of img
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-24 19:45:49 +00:00
Vezpi 5d9afb9206 Delete static/icons/en_toggle/en_toggle_256.svg
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 15:46:09 +02:00
Vezpi 53e4ce701e Delete static/icons/fr_toggle/fr_toggle_256.svg
Blog Deployment / Build (push) Has been cancelled
Blog Deployment / Deploy-Staging (push) Has been cancelled
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Has been cancelled
2025-06-24 15:46:03 +02:00
Vezpi 0e925fffc0 Delete static/icons/fr_toggle.svg
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Deploy-Staging (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
2025-06-24 15:45:51 +02:00
Vezpi 73418f151e Delete static/icons/en_toggle.svg
Blog Deployment / Build (push) Has been cancelled
Blog Deployment / Deploy-Staging (push) Has been cancelled
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Has been cancelled
2025-06-24 15:45:46 +02:00
Vezpi 6cfccc8f16 add: en toggle
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Has started running
Blog Deployment / Merge (push) Has been cancelled
2025-06-24 15:45:36 +02:00
Vezpi 68ffa3b1f5 Delete static/icons/toggle_to_fr.svg
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Deploy-Staging (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Successful in 10s
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
2025-06-24 15:45:20 +02:00
Vezpi 683b65f420 add: fr toggle
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 15:40:33 +02:00
Vezpi e0f3750751 Delete static/icons/toggle_to_en.svg
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Failing after 15s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been skipped
2025-06-24 15:40:02 +02:00
Vezpi 52fc169051 change: new toggle icons
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
2025-06-24 14:01:16 +02:00
Vezpi fcb186bc2b add: new toggle to fr
Blog Deployment / Check-Rebuild (push) Failing after 13s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-24 13:59:01 +02:00
Vezpi e8c50d8fd2 add: new toggle to en
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 13:56:51 +02:00
Vezpi 663ebb8e3b fix: toggle height
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 11:59:28 +02:00
Vezpi 8e7536111a fix: remove fixed width
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 11:55:38 +02:00
Vezpi 2d003c0d5c add: en toggle
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 11:53:11 +02:00
Vezpi e0b35532fd add: fr toggle
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Deploy-Staging (push) Has been cancelled
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
2025-06-24 11:52:52 +02:00
Vezpi 630e182e72 change: use toggle icon instead of flags
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
2025-06-24 11:48:47 +02:00
Vezpi e39247c28a add: en toggle switch
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-24 11:46:57 +02:00
Vezpi 4a7d691baa add: fr toggle switch
Blog Deployment / Check-Rebuild (push) Failing after 11s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been skipped
2025-06-24 11:46:14 +02:00
Vezpi e7e98998aa fix: use page instead of global
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-24 11:14:56 +02:00
Vezpi ef7792bafe fix: change flag size
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 21:47:45 +00:00
Vezpi 1ce187a4c8 fix: png instead of svg
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 8s
2025-06-23 21:44:38 +00:00
Vezpi e10b8da995 fix: save global
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 21:42:29 +00:00
Vezpi 3add412ffe fix: syntax
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
2025-06-23 21:37:18 +00:00
Vezpi 04e6e82401 fix: range .Site.Home.AllTranslations
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 10s
2025-06-23 21:32:25 +00:00
Vezpi 091273aab6 fix: language button
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 21:21:43 +00:00
Vezpi 9b2183d37d change: move language switch to the social menu
Blog Deployment / Check-Rebuild (push) Successful in 10s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 2s
2025-06-23 21:14:22 +00:00
Vezpi 7d7f0645f0 change: flags png size
Blog Deployment / Check-Rebuild (push) Successful in 10s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 20:14:46 +00:00
Vezpi 55c527f9a2 feat: replace language icon bu flags
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Production (push) Has been skipped
2025-06-23 20:09:59 +00:00
Vezpi 17075b53f7 change: language switch keep the current page
Blog Deployment / Check-Rebuild (push) Successful in 9s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:55:29 +00:00
Gitea Actions db586c2926 Auto-update blog content from Obsidian: 2025-06-23 19:38:56
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
2025-06-23 19:38:56 +00:00
Vezpi 7f9323246c fix: change class
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
2025-06-23 19:34:15 +00:00
Gitea Actions 5bd1cc092b Auto-update blog content from Obsidian: 2025-06-23 19:33:37
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:33:37 +00:00
Vezpi a83c16e3e9 remove custom scss for text
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:32:01 +00:00
Gitea Actions 86607c2563 Auto-update blog content from Obsidian: 2025-06-23 19:31:44
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Deploy-Staging (push) Has been cancelled
2025-06-23 19:31:44 +00:00
Vezpi 19d5119cb6 fix: rename css to scss
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:20:35 +00:00
Vezpi 616efe845d add: custom.css
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 19s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:14:02 +00:00
Vezpi 299c13cb9f fix: add right-sidebar
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 19:10:22 +00:00
Vezpi ecb5bccd77 fix: move index
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 18:52:34 +00:00
Vezpi 4ed5972a11 test: edit layouts/index.html
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 10s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-23 18:46:52 +00:00
Gitea Actions 3482f94916 Auto-update blog content from Obsidian: 2025-06-23 18:27:09
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
2025-06-23 18:27:09 +00:00
Vezpi c2cd9c3c7d test: rollback to post as mainSections
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 18:21:13 +00:00
Gitea Actions 9375667d3b Auto-update blog content from Obsidian: 2025-06-23 18:19:37
Blog Deployment / Check-Rebuild (push) Successful in 8s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
2025-06-23 18:19:37 +00:00
Vezpi 0edfb71926 test: use home as mainSections
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 13:55:04 +00:00
Gitea Actions 1f448ec52d Auto-update blog content from Obsidian: 2025-06-23 13:54:36
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Test-Production (push) Has been cancelled
Blog Deployment / Clean (push) Has been cancelled
Blog Deployment / Notify (push) Has been cancelled
Blog Deployment / Merge (push) Has been cancelled
Blog Deployment / Deploy-Production (push) Has been cancelled
2025-06-23 13:54:36 +00:00
Vezpi 9e3a50f649 test: use page/about
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Has been skipped
2025-06-23 13:51:14 +00:00
Vezpi 1ff68dbb30 test: remove post from mainSections
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 13:49:30 +00:00
Vezpi 109eff71c8 test: add about in mainSectuibs
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
2025-06-23 13:40:55 +00:00
Vezpi 9a34b0ea70 fix: don't run notify job when locked
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-23 13:35:40 +00:00
Vezpi 48fcc8f7b3 fix: syntax
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
2025-06-23 13:34:08 +00:00
Vezpi 4d8ad5779b fix: disable notification when locked
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 3s
2025-06-23 13:32:36 +00:00
Vezpi 90ce31b2ec fix: add dev_lock as output
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Successful in 30s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-23 13:27:01 +00:00
Vezpi 73a583bb22 feat: add merge lock
Blog Deployment / Check-Rebuild (push) Successful in 6s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-22 19:55:56 +00:00
Gitea Actions 8b6938db17 Auto-update blog content from Obsidian: 2025-06-19 15:16:42
Blog Deployment / Check-Rebuild (push) Successful in 12s
Blog Deployment / Build (push) Successful in 36s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 3s
Blog Deployment / Notify (push) Successful in 3s
2025-06-19 15:16:42 +00:00
Gitea Actions a8a282b4d9 Auto-update blog content from Obsidian: 2025-06-18 10:48:17
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-18 10:48:17 +00:00
Gitea Actions 48a6c3fea7 Auto-update blog content from Obsidian: 2025-06-12 18:47:17
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-12 18:47:17 +00:00
Gitea Actions b3baeeb1f6 Auto-update blog content from Obsidian: 2025-06-12 17:55:02
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-12 17:55:02 +00:00
Vezpi ea41ac753b change: cron from everyday to every friday
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-12 07:01:19 +00:00
Vezpi e391a05867 feat: add trigger at 3AM everyday
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
2025-06-11 12:33:43 +00:00
Vezpi 74c37501b5 test: remove failure on purpose
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
2025-06-11 12:20:51 +00:00
Vezpi 5cc0f25a12 fix: add second option
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-11 12:17:19 +00:00
Vezpi ddf552562a fix: moving quote
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-11 12:14:58 +00:00
Vezpi c7d2005178 fix: typo
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-11 12:13:45 +00:00
Vezpi 3e78c8e6e0 debug: add clear
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-11 12:12:15 +00:00
Vezpi 9bb8f336d7 fix: remove trailing whitespace
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-11 12:08:43 +00:00
Vezpi 03ee63f945 debug: rollback to one action
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 3s
2025-06-11 12:07:46 +00:00
Vezpi 4355b61dd2 debug: remove 2nd action
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-11 12:02:20 +00:00
Vezpi fa6736b9f2 fix: add whitespace
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-11 11:59:57 +00:00
Vezpi 122180025d fix: both actions on one line
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-11 11:58:52 +00:00
Vezpi 9dc8b0646a fix: remove true
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 3s
Blog Deployment / Deploy-Staging (push) Successful in 8s
2025-06-11 11:57:43 +00:00
Vezpi fd93c00262 fix: remove clear
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 3s
2025-06-11 11:56:39 +00:00
Vezpi fcd52e524b change: add Verify Blog button
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
2025-06-11 11:47:58 +00:00
Gitea Actions c55e2649bb Auto-update blog content from Obsidian: 2025-06-11 11:33:33
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
2025-06-11 11:33:33 +00:00
Vezpi 75f7136ba3 change: remove action when successful
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Deploy-Staging (push) Successful in 9s
2025-06-11 09:30:08 +00:00
Vezpi c23c6c1bd0 fix: remove backslashes
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-11 09:20:00 +00:00
Vezpi 1d2e69a1ff fix: typo
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 3s
2025-06-11 09:18:31 +00:00
Vezpi cf2d7d6ec9 fix: remove function
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Failing after 2s
2025-06-11 09:17:23 +00:00
Vezpi f8ff02b404 debug: add echo
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Notify (push) Successful in 2s
2025-06-11 09:11:13 +00:00
Vezpi 49005ef7ae debug: add echo
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-11 09:09:08 +00:00
Vezpi a69e13af08 fix: change condition
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 3s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 3s
2025-06-11 09:05:04 +00:00
Vezpi 90284665a6 test: fail on purpose for notification
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-10 21:45:19 +00:00
Vezpi c1483e0cca fix: replace run_id by run_number
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 4s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-10 21:43:25 +00:00
Vezpi 81d6d6f64e fix: extra quotes
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 7s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 4s
Blog Deployment / Deploy-Production (push) Successful in 7s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-10 21:38:26 +00:00
Vezpi 734b426559 fix: typo
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 4s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 7s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Notify (push) Successful in 2s
2025-06-10 21:33:49 +00:00
Vezpi 20a9dfa633 feat: add notification for the workflow
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 1s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
2025-06-10 21:29:09 +00:00
Vezpi bdd5002700 fix: use style
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
2025-06-10 13:36:22 +00:00
Vezpi d7591005a3 fix: reduce description size
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 13:19:40 +00:00
Vezpi 8abef26a30 fix: style
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 13:17:48 +00:00
Vezpi a790afa511 fix: style
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 13:12:37 +00:00
Vezpi 4a878c08e1 fix: use style instead of align
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 13:06:31 +00:00
Vezpi 195978b948 feat: align avatar and site name
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 12:53:56 +00:00
Vezpi 86fd5e7567 fix: remove brightness-up icon
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Build (push) Has been skipped
2025-06-10 12:47:03 +00:00
Vezpi 6952888acc fix: change language icon 2025-06-10 12:45:43 +00:00
Vezpi 7a5de897b0 feat: change dark mode icons
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-10 12:25:58 +00:00
Vezpi 2e09675b36 fix: syntax
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Merge (push) Successful in 5s
2025-06-10 12:19:43 +00:00
Vezpi 69c843ea04 fix: remove translations variables
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-10 12:17:12 +00:00
Vezpi 397cee6a4b feat: change language button
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Failing after 2s
Blog Deployment / Merge (push) Has been skipped
Blog Deployment / Test-Production (push) Has been skipped
Blog Deployment / Deploy-Production (push) Has been skipped
Blog Deployment / Clean (push) Has been skipped
2025-06-10 12:11:52 +00:00
Vezpi aa9f7dc147 fix: avoid having lastmod inferior than date
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 8s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 2s
2025-06-10 11:46:35 +00:00
Gitea Actions 05d0573e00 Auto-update blog content from Obsidian: 2025-06-10 11:35:53
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 4s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
2025-06-10 11:35:53 +00:00
Vezpi d5a6aebd19 fix: compare dates at day level
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
2025-06-10 09:25:13 +00:00
Vezpi ee680ea691 fix: unshallow git repo and enableGitInfo
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 9s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
2025-06-10 09:05:39 +00:00
Vezpi c0ec67eb1e feat: change article header
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Successful in 27s
Blog Deployment / Deploy-Staging (push) Successful in 10s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
2025-06-10 09:00:31 +00:00
Gitea Actions 5511ffb9f9 Auto-update blog content from Obsidian: 2025-06-05 19:28:49
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-05 19:28:49 +00:00
Gitea Actions 94d68f775c Auto-update blog content from Obsidian: 2025-06-05 19:26:10
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-05 19:26:10 +00:00
Gitea Actions 64c31e3c2e Auto-update blog content from Obsidian: 2025-06-05 18:38:15
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 7s
Blog Deployment / Deploy-Production (push) Successful in 11s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Has been skipped
2025-06-05 18:38:15 +00:00
Gitea Actions 558d53d797 Auto-update blog content from Obsidian: 2025-06-05 10:32:51
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-06-05 10:32:51 +00:00
Vezpi 6bde228d4c revert: no image prune
Blog Deployment / Test-Staging (push) Successful in 33s
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 10s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Check-Rebuild (push) Successful in 12s
Blog Deployment / Build (push) Successful in 6s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Clean (push) Successful in 2s
2025-06-05 08:58:39 +00:00
Vezpi ea8297466c add: image prune on clean
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Build (push) Successful in 9s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 3s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Successful in 2s
2025-06-05 08:55:38 +00:00
Vezpi 06e32273d2 fix: typo
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Successful in 5s
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Successful in 5s
2025-06-05 08:51:55 +00:00
Vezpi 9e532d5d4f add: remove old docker image
Blog Deployment / Build (push) Successful in 10s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 3s
Blog Deployment / Clean (push) Failing after 2s
Blog Deployment / Check-Rebuild (push) Successful in 5s
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s
2025-06-05 08:48:46 +00:00
Vezpi 6a9aa3be2b style: capitalize job names
Blog Deployment / Check-Rebuild (push) Successful in 4s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 8s
Blog Deployment / Test-Staging (push) Successful in 2s
Blog Deployment / Merge (push) Successful in 5s
Blog Deployment / Deploy-Production (push) Successful in 8s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
2025-06-05 08:29:27 +00:00
Vezpi 404b5cc34c fix: typo
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 8s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 4s
Blog Deployment / deploy-production (push) Successful in 8s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-05 07:40:11 +00:00
Vezpi 182806bef8 fix: remove duplicate lang
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 8s
Blog Deployment / test-staging (push) Failing after 2s
Blog Deployment / merge (push) Has been skipped
Blog Deployment / deploy-production (push) Has been skipped
Blog Deployment / test-production (push) Has been skipped
Blog Deployment / clean (push) Has been skipped
2025-06-05 07:34:29 +00:00
Gitea Actions 8ed35ae1f9 Auto-update blog content from Obsidian: 2025-06-05 07:28:06
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 7s
Blog Deployment / test-staging (push) Successful in 1s
Blog Deployment / merge (push) Successful in 4s
Blog Deployment / deploy-production (push) Successful in 7s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-05 07:28:06 +00:00
Vezpi c12e1dcf7f fix: change sitemap format
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 8s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 6s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-05 07:25:32 +00:00
Vezpi 805d834063 feat: enhance sitemap by excluding some pages
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 10s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 7s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 3s
Blog Deployment / clean (push) Has been skipped
2025-06-05 07:20:08 +00:00
Vezpi c7164b4575 fix: test
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / test-production (push) Successful in 3s
Blog Deployment / clean (push) Has been skipped
Blog Deployment / build (push) Successful in 9s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / deploy-production (push) Successful in 9s
2025-06-04 21:55:38 +00:00
Vezpi 0f5b05e711 test: echo BRANCH name
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Successful in 8s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:50:55 +00:00
Vezpi f5b980b996 fix: draft and URL
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / build (push) Successful in 8s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 3s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:46:29 +00:00
Vezpi d51b89690b fix: remove URL
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Successful in 8s
Blog Deployment / deploy-staging (push) Successful in 8s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 6s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:37:43 +00:00
Vezpi 492f3ffb43 add: comments in entrypoint.sh
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Successful in 8s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:32:04 +00:00
Vezpi c5546106a6 fix: add condition on version for cleaning
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / test-staging (push) Failing after 3s
Blog Deployment / merge (push) Has been skipped
Blog Deployment / deploy-production (push) Has been skipped
Blog Deployment / test-production (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:29:28 +00:00
Vezpi 8a926a119e test: fail on purpose
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / build (push) Successful in 8s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Failing after 2s
Blog Deployment / deploy-production (push) Has been skipped
Blog Deployment / test-production (push) Has been skipped
Blog Deployment / clean (push) Has been skipped
Blog Deployment / merge (push) Has been skipped
2025-06-04 21:26:02 +00:00
Vezpi 6515c0b7d2 fix: diff wit origin/main
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
Blog Deployment / merge (push) Successful in 5s
2025-06-04 21:24:51 +00:00
Vezpi 6a54d815f6 fix: add checkout repo
Blog Deployment / check-rebuild (push) Successful in 5s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:21:40 +00:00
Vezpi eab0acaec0 add: URL and drafts
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 8s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:18:48 +00:00
Vezpi 51ff489523 add: rebuild when docker folder change
Blog Deployment / check-rebuild (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 21:08:17 +00:00
Vezpi 6190e4664b clean: remove useless files
Blog Deployment / check-hugo-version (push) Successful in 4s
Blog Deployment / test-staging (push) Successful in 2s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-production (push) Successful in 8s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 20:31:22 +00:00
Vezpi 6a98a4fba2 fix: jobs order
Blog Deployment / check-hugo-version (push) Successful in 3s
Blog Deployment / build (push) Has been skipped
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
Blog Deployment / merge (push) Successful in 5s
2025-06-04 20:20:55 +00:00
Vezpi fe32c88403 change: merge staging and production workflow
Blog Deployment / check-hugo-version (push) Successful in 4s
Blog Deployment / build (push) Has been skipped
Blog Deployment / merge (push) Successful in 5s
Blog Deployment / deploy-staging (push) Successful in 9s
Blog Deployment / deploy-production (push) Successful in 9s
Blog Deployment / test-staging (push) Successful in 3s
Blog Deployment / test-production (push) Successful in 2s
Blog Deployment / clean (push) Has been skipped
2025-06-04 20:18:48 +00:00
Gitea Actions 853beb33a4 Auto-update blog content from Obsidian: 2025-06-04 20:04:47
Staging Blog Deployment / check-hugo-version (push) Successful in 4s
Staging Blog Deployment / build (push) Has been skipped
Staging Blog Deployment / deploy (push) Successful in 9s
Staging Blog Deployment / test (push) Successful in 3s
Staging Blog Deployment / merge (push) Successful in 5s
Staging Blog Deployment / clean (push) Has been skipped
2025-06-04 20:04:47 +00:00
Vezpi 8d3f20f947 add branches to workflow_run
Staging Blog Deployment / check-hugo-version (push) Successful in 3s
Staging Blog Deployment / build (push) Has been skipped
Staging Blog Deployment / deploy (push) Successful in 8s
Staging Blog Deployment / test (push) Successful in 2s
Staging Blog Deployment / merge (push) Successful in 5s
Staging Blog Deployment / clean (push) Has been skipped
2025-06-04 20:03:05 +00:00
Vezpi 22ec714b46 change production workflow trigger
Staging Blog Deployment / check-hugo-version (push) Successful in 3s
Staging Blog Deployment / build (push) Has been skipped
Staging Blog Deployment / deploy (push) Successful in 9s
Staging Blog Deployment / test (push) Successful in 2s
Staging Blog Deployment / merge (push) Successful in 5s
Staging Blog Deployment / clean (push) Has been skipped
2025-06-04 19:54:42 +00:00
Vezpi 91711bd972 Delete .hugo_build.lock
Staging Blog Deployment / check-hugo-version (push) Successful in 3s
Staging Blog Deployment / build (push) Has been skipped
Production Blog Deployment / deploy (push) Successful in 9s
Production Blog Deployment / test (push) Successful in 3s
Staging Blog Deployment / deploy (push) Successful in 9s
Staging Blog Deployment / test (push) Successful in 2s
Staging Blog Deployment / merge (push) Successful in 5s
Staging Blog Deployment / clean (push) Has been skipped
2025-06-04 21:46:47 +02:00
Gitea Actions ecb68e1d72 Auto-update blog content from Obsidian: 2025-06-04 19:45:07
Staging Blog Deployment / check-hugo-version (push) Successful in 3s
Staging Blog Deployment / build (push) Has been skipped
Staging Blog Deployment / deploy (push) Successful in 9s
Staging Blog Deployment / test (push) Successful in 2s
Staging Blog Deployment / merge (push) Successful in 6s
Staging Blog Deployment / clean (push) Has been skipped
2025-06-04 19:45:07 +00:00
Vezpi 041ed1fe42 rework: deployment workflow
Staging Blog Deployment / check-hugo-version (push) Successful in 3s
Staging Blog Deployment / deploy (push) Successful in 9s
Staging Blog Deployment / test (push) Successful in 3s
Staging Blog Deployment / clean (push) Has been skipped
Staging Blog Deployment / build (push) Has been skipped
Staging Blog Deployment / merge (push) Successful in 5s
2025-06-04 19:40:36 +00:00
Vezpi e835486965 change: add HUGO_DEST and remove metrics
Deploy / Deploy (push) Failing after 3s
2025-06-02 13:04:51 +00:00
Vezpi 4d1a265b9d fix: change verbose to logLevel
Deploy / Deploy (push) Successful in 3s
2025-06-02 12:58:32 +00:00
Vezpi c05ccae7ff change: harden hugo page generation
Deploy / Deploy (push) Successful in 4s
2025-06-02 12:56:18 +00:00
Vezpi 82170a7ee5 add: index.json layout
Deploy / Deploy (push) Successful in 3s
2025-06-02 12:52:40 +00:00
Vezpi 31ab29ccbb remove: unused themes PaperMod and hugo-coder
Deploy / Deploy (push) Successful in 3s
2025-06-02 11:28:37 +02:00
Vezpi 687595b4c9 fix: add recurse-submodules in the git clone
Deploy / Deploy (push) Successful in 4s
2025-06-02 09:21:09 +00:00
Vezpi 51a5046f3c fix: change image base from alpine to stable
Deploy / Deploy (push) Successful in 4s
2025-06-02 08:38:52 +00:00
Vezpi b9b4d0bf8b add: docker folder for image build
Deploy / Deploy (push) Successful in 6s
2025-06-02 08:02:23 +00:00
Gitea Actions 6b194c5069 Auto-update blog content from Obsidian: 2025-06-01 18:48:25
Deploy / Deploy (push) Successful in 4s
2025-06-01 18:48:25 +00:00
299 changed files with 17176 additions and 12015 deletions
-45
View File
@@ -1,45 +0,0 @@
name: Deploy
on: [push]
jobs:
Deploy:
runs-on: ubuntu
env:
BLOG_FOLDER: /blog
container:
volumes:
- /appli/data/blog:/blog
steps:
- name: Check out repository
run: |
cd ${BLOG_FOLDER}
git config --global user.name "Gitea Actions"
git config --global user.email "actions@local"
git config --global --add safe.directory ${BLOG_FOLDER}
git submodule update --init --recursive
git fetch origin
git reset --hard origin/main
- name: Get current Hugo version
run: |
current_version=$(${BLOG_FOLDER}/hugo version | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
echo "current_version=$current_version" | tee -a $GITEA_ENV
- name: Verify latest Hugo version
run: |
latest_version=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep -oP '"tag_name": "\K[^"]+')
echo "latest_version=$latest_version" | tee -a $GITEA_ENV
- name: Download latest Hugo version
if: env.current_version != env.latest_version
run: |
rm -f ${BLOG_FOLDER}/{LICENSE,README.md,hugo}
curl -L https://github.com/gohugoio/hugo/releases/download/$latest_version/hugo_extended_${latest_version#v}_Linux-64bit.tar.gz -o hugo.tar.gz
tar -xzvf hugo.tar.gz -C ${BLOG_FOLDER}/
- name: Generate the static files with Hugo
run: |
rm -f ${BLOG_FOLDER}/content/posts/template.md
rm -rf ${BLOG_FOLDER}/private/* ${BLOG_FOLDER}/public/*
${BLOG_FOLDER}/hugo -D -b https://blog-dev.vezpi.com -s ${BLOG_FOLDER} -d ${BLOG_FOLDER}/private
${BLOG_FOLDER}/hugo -s ${BLOG_FOLDER} -d ${BLOG_FOLDER}/public
chown 1000:1000 -R ${BLOG_FOLDER}
+326
View File
@@ -0,0 +1,326 @@
name: Blog Deployment
on:
push:
branches:
- preview
schedule:
- cron: '0 3 * * 5'
env:
DOCKER_IMAGE: vezpi-blog
jobs:
Check-Rebuild:
runs-on: docker
defaults:
run:
shell: sh
outputs:
latest_hugo_version: ${{ steps.get_latest.outputs.version }}
current_hugo_version: ${{ steps.get_current.outputs.version }}
newer_version_available: ${{ steps.compare.outputs.version }}
current_docker_image: ${{ steps.current_docker.outputs.image }}
docker_folder_changed: ${{ steps.docker_folder.outputs.changed }}
steps:
- name: Checkout Repository
run: git clone --branch ${{ gitea.ref_name }} https://${{ secrets.REPO_TOKEN }}@git.vezpi.com/Vezpi/blog.git .
- name: Check Latest Hugo Version
id: get_latest
run: |
apk add curl
latest_version=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name | sed -E 's/.*"v([^"]+)".*/\1/')
echo "version=$latest_version" | tee -a $GITEA_OUTPUT
- name: Check Current Hugo Version
id: get_current
run: |
current_version=$(docker image ls ${DOCKER_IMAGE} --format '{{.Tag}}' | head -n1)
echo "version=$current_version" | tee -a $GITEA_OUTPUT
- name: Compare Current and Latest Hugo Versions
id: compare
run: |
if [ "${{ steps.get_latest.outputs.version }}" != "${{ steps.get_current.outputs.version }}" ]; then
new_version_available=true
echo "New version available: ${{ steps.get_latest.outputs.version }}"
else
new_version_available=false
echo "Current version is the latest: ${{ steps.get_latest.outputs.version }}"
fi
echo "version=$new_version_available" | tee -a $GITEA_OUTPUT
- name: Get Current Docker Image ID
id: current_docker
run: |
current_image=$(docker image ls ${DOCKER_IMAGE}:latest --format '{{.ID}}' | head -n1)
echo "image=$current_image" | tee -a $GITEA_OUTPUT
- name: Check Changes in the Docker Folder
id: docker_folder
run: |
if git diff --name-only origin/main | grep -q '^docker/';
then
docker_folder_changed=true
echo "Change detected in the /docker folder"
else
docker_folder_changed=false
echo "No change in the /docker folder"
fi
echo "changed=$docker_folder_changed" | tee -a $GITEA_OUTPUT
Build:
needs: Check-Rebuild
if: needs.Check-Rebuild.outputs.newer_version_available == 'true' || needs.Check-Rebuild.outputs.docker_folder_changed == 'true'
runs-on: docker
defaults:
run:
shell: sh
steps:
- name: Checkout Repository
run: git clone --branch ${{ gitea.ref_name }} https://${{ secrets.REPO_TOKEN }}@git.vezpi.com/Vezpi/blog.git .
- name: Build Docker Image
run: |
cd docker
docker build \
--build-arg HUGO_VERSION=${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
--tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
.
docker tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} ${DOCKER_IMAGE}:latest
Deploy-Staging:
needs: [Check-Rebuild, Build]
if: always()
runs-on: docker
container:
volumes:
- /appli/docker/blog:/blog
defaults:
run:
shell: sh
env:
CONTAINER_NAME: blog_staging
steps:
- name: Launch Blog Deployment
run: |
cd /blog
echo "- Stopping existing ${CONTAINER_NAME}..."
docker compose down ${CONTAINER_NAME}
echo "- Starting ${CONTAINER_NAME}..."
docker compose up -d ${CONTAINER_NAME}
echo "- Waiting for ${CONTAINER_NAME} to become healthy..."
timeout=300
elapsed=0
while true; do
status=$(docker inspect \
--format='{{.State.Health.Status}}' \
${CONTAINER_NAME})
echo "Health status: ${status}"
case "$status" in
healthy)
echo "✅ ${CONTAINER_NAME} is healthy"
break
;;
unhealthy)
echo "❌ ${CONTAINER_NAME} is unhealthy"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
;;
*)
;;
esac
if [ "$elapsed" -ge "$timeout" ]; then
echo "❌ Timed out waiting for ${CONTAINER_NAME}"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
fi
sleep 2
elapsed=$((elapsed + 2))
done
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
Test-Staging:
needs: Deploy-Staging
runs-on: ubuntu
env:
URL: "https://blog-staging.vezpi.com/en/"
steps:
- name: Check HTTP Response
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
echo "HTTP response code: $code"
if [ "$code" -ne 200 ]; then
echo "❌ Service is not healthy (HTTP $code)"
exit 1
else
echo "✅ Service is healthy"
fi
Merge:
needs: [Check-Rebuild, Test-Staging]
if: needs.Test-Staging.result == 'success'
runs-on: ubuntu
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: main
- name: Merge preview Branch on main
run: |
git merge --ff-only origin/${{ gitea.ref_name }}
git push origin main
Deploy-Production:
needs: Merge
runs-on: docker
container:
volumes:
- /appli/docker/blog:/blog
defaults:
run:
shell: sh
env:
CONTAINER_NAME: blog_production
steps:
- name: Launch Blog Deployment
run: |
cd /blog
echo "- Stopping existing ${CONTAINER_NAME}..."
docker compose down ${CONTAINER_NAME}
echo "- Starting ${CONTAINER_NAME}..."
docker compose up -d ${CONTAINER_NAME}
echo "- Waiting for ${CONTAINER_NAME} to become healthy..."
timeout=300
elapsed=0
while true; do
status=$(docker inspect \
--format='{{.State.Health.Status}}' \
${CONTAINER_NAME})
echo "Health status: ${status}"
case "$status" in
healthy)
echo "✅ ${CONTAINER_NAME} is healthy"
break
;;
unhealthy)
echo "❌ ${CONTAINER_NAME} is unhealthy"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
;;
*)
;;
esac
if [ "$elapsed" -ge "$timeout" ]; then
echo "❌ Timed out waiting for ${CONTAINER_NAME}"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
fi
sleep 2
elapsed=$((elapsed + 2))
done
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
Test-Production:
needs: Deploy-Production
runs-on: ubuntu
env:
URL: "https://blog.vezpi.com/en/"
steps:
- name: Check HTTP Response
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
echo "HTTP response code: $code"
if [ "$code" -ne 200 ]; then
echo "❌ Service is not healthy (HTTP $code)"
exit 1
else
echo "✅ Service is healthy"
fi
Clean:
needs: [Check-Rebuild, Build, Test-Production]
runs-on: docker
defaults:
run:
shell: sh
steps:
- name: Remove Old Docker Image
run: |
IMAGE_IDS=$(docker image ls "${DOCKER_IMAGE}" 2>/dev/null | awk '$NF != "U" && NR>1 {print $2}')
if [ -n "$IMAGE_IDS" ]; then
docker image rm $IMAGE_IDS
fi
Notify:
needs: [Check-Rebuild, Build, Deploy-Staging, Test-Staging, Merge, Deploy-Production, Test-Production, Clean]
runs-on: ubuntu
if: always()
env:
NTFY_URL: https://ntfy.vezpi.com
NTFY_TOPIC: blog
NTFY_TOKEN: ${{ secrets.NTFY_CREDENTIALS }}
steps:
- name: Notify Workflow Result
run: |
if [[
"${{ needs.Check-Rebuild.result }}" == "success" &&
("${{ needs.Build.result }}" == "success" || "${{ needs.Build.result }}" == "skipped") &&
"${{ needs.Deploy-Staging.result }}" == "success" &&
"${{ needs.Test-Staging.result }}" == "success" &&
"${{ needs.Merge.result }}" == "success" &&
"${{ needs.Deploy-Production.result }}" == "success" &&
"${{ needs.Test-Production.result }}" == "success" &&
("${{ needs.Clean.result }}" == "success" || "${{ needs.Clean.result }}" == "skipped")
]]; then
curl -H "Priority: min" \
-H "Tags: white_check_mark" \
-d "Blog workflow completed successfully." \
-u ${NTFY_TOKEN} \
${NTFY_URL}/${NTFY_TOPIC}
else
curl -H "Priority: high" \
-H "Tags: x" \
-H "Actions: view, View Run, ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_number }}, clear=true; \
view, Verify Blog, https://blog.vezpi.com, clear=true" \
-d "Blog workflow failed!" \
-u ${NTFY_TOKEN} \
${NTFY_URL}/${NTFY_TOPIC}
fi
+179
View File
@@ -0,0 +1,179 @@
name: Blog Test
on:
push:
branches:
- 'fix/**'
- 'feat/**'
env:
DOCKER_IMAGE: vezpi-blog
jobs:
Check-Rebuild:
runs-on: docker
defaults:
run:
shell: sh
outputs:
latest_hugo_version: ${{ steps.get_latest.outputs.version }}
current_hugo_version: ${{ steps.get_current.outputs.version }}
newer_version_available: ${{ steps.compare.outputs.version }}
current_docker_image: ${{ steps.current_docker.outputs.image }}
docker_folder_changed: ${{ steps.docker_folder.outputs.changed }}
steps:
- name: Checkout Repository
run: git clone --branch ${{ gitea.ref_name }} https://${{ secrets.REPO_TOKEN }}@git.vezpi.com/Vezpi/blog.git .
- name: Check Latest Hugo Version
id: get_latest
run: |
apk add curl
latest_version=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name | sed -E 's/.*"v([^"]+)".*/\1/')
echo "version=$latest_version" | tee -a $GITEA_OUTPUT
- name: Check Current Hugo Version
id: get_current
run: |
current_version=$(docker image ls ${DOCKER_IMAGE} --format '{{.Tag}}' | head -n1)
echo "version=$current_version" | tee -a $GITEA_OUTPUT
- name: Compare Current and Latest Hugo Versions
id: compare
run: |
if [ "${{ steps.get_latest.outputs.version }}" != "${{ steps.get_current.outputs.version }}" ]; then
new_version_available=true
echo "New version available: ${{ steps.get_latest.outputs.version }}"
else
new_version_available=false
echo "Current version is the latest: ${{ steps.get_latest.outputs.version }}"
fi
echo "version=$new_version_available" | tee -a $GITEA_OUTPUT
- name: Get Current Docker Image ID
id: current_docker
run: |
current_image=$(docker image ls ${DOCKER_IMAGE}:latest --format '{{.ID}}' | head -n1)
echo "image=$current_image" | tee -a $GITEA_OUTPUT
- name: Check Changes in the Docker Folder
id: docker_folder
run: |
if git diff --name-only origin/main | grep -q '^docker/';
then
docker_folder_changed=true
echo "Change detected in the /docker folder"
else
docker_folder_changed=false
echo "No change in the /docker folder"
fi
echo "changed=$docker_folder_changed" | tee -a $GITEA_OUTPUT
Build:
needs: Check-Rebuild
if: needs.Check-Rebuild.outputs.newer_version_available == 'true' || needs.Check-Rebuild.outputs.docker_folder_changed == 'true'
runs-on: docker
defaults:
run:
shell: sh
steps:
- name: Checkout Repository
run: git clone --branch ${{ gitea.ref_name }} https://${{ secrets.REPO_TOKEN }}@git.vezpi.com/Vezpi/blog.git .
- name: Build Docker Image
run: |
cd docker
docker build \
--build-arg HUGO_VERSION=${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
--tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
.
docker tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} ${DOCKER_IMAGE}:dev
Deploy-Test:
needs:
- Check-Rebuild
- Build
if: always()
runs-on: docker
container:
volumes:
- /appli/docker/blog:/blog
defaults:
run:
shell: sh
env:
CONTAINER_NAME: blog_dev
steps:
- name: Launch Blog Test Deployment
run: |
cd /blog
echo "- Stopping existing ${CONTAINER_NAME}..."
docker compose down ${CONTAINER_NAME}
echo "- Starting ${CONTAINER_NAME}..."
BLOG_TEST_BRANCH=${{ gitea.ref_name }} \
docker compose up -d ${CONTAINER_NAME}
echo "- Waiting for ${CONTAINER_NAME} to become healthy..."
timeout=300
elapsed=0
while true; do
status=$(docker inspect \
--format='{{.State.Health.Status}}' \
${CONTAINER_NAME})
echo "Health status: ${status}"
case "$status" in
healthy)
echo "✅ ${CONTAINER_NAME} is healthy"
break
;;
unhealthy)
echo "❌ ${CONTAINER_NAME} is unhealthy"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
;;
*)
;;
esac
if [ "$elapsed" -ge "$timeout" ]; then
echo "❌ Timed out waiting for ${CONTAINER_NAME}"
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
exit 1
fi
sleep 2
elapsed=$((elapsed + 2))
done
echo "- Displaying container logs"
docker compose logs ${CONTAINER_NAME}
Test:
needs: Deploy-Test
runs-on: ubuntu
env:
URL: "https://blog-dev.vezpi.com/en/"
steps:
- name: Check HTTP Response
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
echo "HTTP response code: $code"
if [ "$code" -ne 200 ]; then
echo "❌ Service is not healthy (HTTP $code)"
exit 1
else
echo "✅ Service is healthy"
fi
-6
View File
@@ -1,9 +1,3 @@
[submodule "themes/hugo-coder"]
path = themes/hugo-coder
url = https://github.com/luizdepra/hugo-coder.git
[submodule "themes/PaperMod"]
path = themes/PaperMod
url = https://github.com/adityatelange/hugo-PaperMod.git
[submodule "themes/stack"] [submodule "themes/stack"]
path = themes/stack path = themes/stack
url = https://github.com/CaiJimmy/hugo-theme-stack.git url = https://github.com/CaiJimmy/hugo-theme-stack.git
View File
-5
View File
@@ -1,5 +0,0 @@
+++
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
date = {{ .Date }}
draft = true
+++
Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-git"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M16 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12 8m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12 16m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12 15v-6" /><path d="M15 11l-2 -2" /><path d="M11 7l-1.9 -1.9" /><path d="M13.446 2.6l7.955 7.954a2.045 2.045 0 0 1 0 2.892l-7.955 7.955a2.045 2.045 0 0 1 -2.892 0l-7.955 -7.955a2.045 2.045 0 0 1 0 -2.892l7.955 -7.955a2.045 2.045 0 0 1 2.892 0z" /></svg>

Before

Width:  |  Height:  |  Size: 732 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-message-language"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 21v-13a3 3 0 0 1 3 -3h10a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-9l-4 4" /><path d="M10 14v-4a2 2 0 1 1 4 0v4" /><path d="M14 12h-4" /></svg>

After

Width:  |  Height:  |  Size: 462 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-moon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" /></svg>

After

Width:  |  Height:  |  Size: 402 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-refresh"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" /><path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" /></svg>

After

Width:  |  Height:  |  Size: 417 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-stopwatch"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M5 13a7 7 0 1 0 14 0a7 7 0 0 0 -14 0z" /><path d="M14.5 10.5l-2.5 2.5" /><path d="M17 8l1 -1" /><path d="M14 3h-4" /></svg>

After

Width:  |  Height:  |  Size: 442 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 90 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 90 KiB

+17
View File
@@ -0,0 +1,17 @@
.homepage-header {
text-align: center;
}
.lang-toggle-icon {
margin-left: 0;
svg {
width: 64px;
height: 24px;
}
}
.container {
.left-sidebar {
width: unset;
}
}
+6
View File
@@ -0,0 +1,6 @@
---
title: Bienvenue sur Vezpi Lab
description: Ici les derniers articles
---
Ce blog partage mes projets et expériences dans mon homelab.
Vous trouverez ci-dessous les derniers articles.
+6
View File
@@ -0,0 +1,6 @@
---
title: Welcome to Vezpi Lab
description: Here the latest articles
---
This blog shares project and experiments from my homelab.
Below you'll find the latest articles.
+3 -3
View File
@@ -9,12 +9,12 @@ menu:
params: params:
icon: user icon: user
--- ---
Salut ! Moi c'est Etienne, j'adore l'**automatisation** et je suis un amateur de projets **homelab**. Je suis un expert Linux et travaille comme **Senior Cloud DevOps Engineer** chez Capgemini. Salut ! Moi c'est Etienne, j'adore l'**automatisation** et je suis un amateur de projets **homelab**. Je suis un expert Linux et je travaille comme **Senior Cloud DevOps Engineer** chez Capgemini.
Motivé par la passion, j'aime explorer de nouvelles technologie, comprendre comment elles fonctionnement et les expérimenter chez moi, juste pour le plaisir. Mon lab est passé d'un simple espace de bidouille à un véritable terrain de jeu pour expérimenter la virtualisation, l'orchestration de conteneurs, le réseau, et bien plus encore. Motivé par la passion, j'aime explorer de nouvelles technologies, comprendre comment elles fonctionnent et les expérimenter chez moi, juste pour le plaisir. Mon lab est passé d'un simple espace de bidouille à un véritable terrain de jeu pour expérimenter la virtualisation, l'orchestration de conteneurs, le réseau, et bien plus encore.
Ce blog est ma façon de documenter ce que je construis, casse (volontairement !), répare et surtout, ce que j'**apprends**. C'est une référence personnelle, mais aussi un moyen de partager avec la communauté, de m’open source, au cas où quelqu'un d'autre suivrait le même chemin et trouverait mon expérience utile. Ce blog est ma façon de documenter ce que je construis, casse (volontairement !), répare et surtout, ce que j'**apprends**. C'est une référence personnelle, mais aussi un moyen de partager avec la communauté, de m’open source, au cas où quelqu'un d'autre suivrait le même chemin et trouverait mon expérience utile.
Même si je suis français, J'écris mes notes personnelles en anglais pour perfectionner l'utilisation de cette langue, mais j’essaye tout de même de les traduire dans ma langue maternelle. Même si je suis français, j'écris mes notes personnelles en anglais pour perfectionner l'utilisation de cette langue, mais j’essaie tout de même de les traduire dans ma langue maternelle.
Si vous travaillez sur un projet intéressant, si vous avez des questions ou si vous souhaitez proposer de nouvelles idées, **n'hésitez pas à me contacter** ! Si vous travaillez sur un projet intéressant, si vous avez des questions ou si vous souhaitez proposer de nouvelles idées, **n'hésitez pas à me contacter** !

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Before

Width:  |  Height:  |  Size: 568 KiB

After

Width:  |  Height:  |  Size: 568 KiB

+70 -162
View File
@@ -1,7 +1,7 @@
--- ---
title: Bienvenue dans mon Homelab title: Bienvenue dans mon Homelab
layout: page layout: page
description: L'histoire derrière mon projet de homelab, d'un Raspberry Pi à un mini datacenter, où j'expérimente Proxmox, Kubernetes, l'automatisation et plus encore. description: Mon homelab compact avec Proxmox, Ceph, TrueNAS et OPNsense, les services qui y tournent et mon projet de migration vers Kubernetes.
showToc: true showToc: true
menu: menu:
main: main:
@@ -10,212 +10,120 @@ menu:
params: params:
icon: flask icon: flask
--- ---
## Intro
Mon aventure homelab a commencé en 2013 avec un modeste Raspberry Pi, le tout premier modèle. J'avais besoin d'une machine bon marché pour mes premiers pas dans le monde de Linux. Elle m'a beaucoup aidé à m’initier dans cette technologie et m'a servi de NAS de base, merci Vezpibox (nom pourri, je sais). Mon homelab a commencé en 2013 avec le tout premier Raspberry Pi. Je voulais une machine bon marché pour apprendre Linux, et elle est devenue un petit NAS appelé Vezpibox. Le nom n'a pas particulièrement bien vieilli.
En 2015, je suis passé à un Raspberry Pi 2, à la recherche de meilleures performances pour exécuter plusieurs applications comme XBMC (l'ancien nom de Kodi), CouchPotato, SickBeard... 😇 D'autres Raspberry Pi ont suivi, puis un mini-PC en 2019, quand j'ai commencé à expérimenter la virtualisation et Docker à la maison. Ce serveur unique a fini par poser problème : c'était à la fois mon terrain de jeu et la machine qui faisait tourner les services utiles. Casser un environnement de test est une chose. Couper aussi les lumières ou Internet en est une autre.
En 2018, le besoin de plus de RAM m'a conduit à un Raspberry Pi 3, me permettant d'exécuter encore plus d'applications. Mes trois petites machines fonctionnaient harmonieusement ensemble, dans un bordel bien ordonné. Aujourd'hui, le lab comprend un cluster Proxmox à trois nœuds, du stockage distribué, un NAS séparé et une paire de firewalls redondants. La plupart des applications tournent encore avec Docker Compose. Kubernetes fonctionne aussi, mais la migration des applications est la suite du projet, pas quelque chose que j'ai déjà terminé.
Enfin, en 2019, mon nouveau travail m'a fait expérimenter la virtualisation, avec les machines virtuelles et surtout Docker. Je voulais essayer ça à la maison, et je suis passé a la vitesse supérieure avec un mini-PC compact mais assez puissant qui a posé les bases de mon homelab. *Dernière revue : octobre 2026.*
--- ## Un lab dans une armoire
## Pourquoi un Homelab ?
Je voulais mon propre terrain de jeu, un espace où je pouvais construire mais aussi casser des choses sans risques, apprendre à les réparer et mieux comprendre leur fonctionnement. L'idée de départ était de construire un mini datacenter dans un placard. L'espace, le bruit, la consommation électrique et le budget comptaient tous, alors le setup s'est construit autour de machines compactes plutôt que de serveurs rackables.
Mon unique serveur était génial, mais tester quoi que ce soit de risqué dessus était devenu problématique. Il exécutait des services critiques comme la domotique ou le DNS, lorsqu'il était en panne, tout était en panne. Le serveur était devenu indispensable, et croyez-moi, ne pas avoir de lumières ni d'internet était un incident majeur pour ma famille. Plus aussi fun. ![L'armoire du homelab ouverte et fermée, à côté de la cuisine. L'espace disponible fait partie de la conception, ce n'est pas une salle de serveurs extensible à volonté.](images/homelab-enclore-open-closed.png)
Le premier grand défi que je me suis lancé a été de créer un cluster Kubernetes. Bien sûr, j'aurais pu en exécuter un sur un seul nœud, mais à quoi bon un cluster avec un seul nœud ? On pourrait dire qu'utiliser Kubernetes pour contrôler mes volets est overkill, et vous auriez raison. Mais ce n'était pas le sujet. Le rack est un DeskPi RackMate T1. Il tient dans cette armoire étroite, avec des étagères et une multiprise pour utiliser l'espace disponible. Une fois la porte fermée, le lab disparaît dans l'appartement.
Je voulais aussi créer de nouvelles machines virtuelles à volonté, les reconstruire de zéro et appliquer les principes de l'Infrastructure as Code. J'aurais pu faire tout cela dans le cloud, mais je voulais un contrôle total. ![L'agencement initial du rack. Les légendes du routeur et des HDD correspondent à l'ancien setup ; l'architecture actuelle du firewall et du stockage est décrite plus bas.](images/homelab-rack-legend.png)
Au départ, mon objectif était d'assurer la haute disponibilité de mes services existants. Un seul serveur ne suffisait pas. J'avais donc besoin d'un deuxième nœud. Mais dans la plupart des configurations haute disponibilité, trois nœuds constituent le compromis idéal. Et c'est ainsi que j'ai pu construire ce qui allait devenir mon homelab. Le refroidissement a demandé un peu d'attention aussi. Lors de la construction initiale, j'ai ajouté deux ventilateurs d'extraction de 40 mm au-dessus du meuble, avec des conduits en PVC et de la mousse pour limiter les vibrations. Deux ventilateurs de 80 mm dans le rack et un contrôleur PWM ont aidé à équilibrer le flux d'air et le bruit. Dans une armoire au milieu d'un espace de vie, faire rentrer les machines ne résout que la moitié du problème.
--- ## Le matériel
## Conception du Lab
Tout d'abord, il me fallait définir les fonctions de mon homelab. Je souhaitais qu'il héberge mes services existants de manière fiable, mais cela ne suffisait pas, je voulais un véritable terrain de jeu, capable de simuler un environnement d'entreprise plus complexe. Les trois nœuds Proxmox sont des mini-PC différents :
### Blueprint
Cela impliquait : | Nœud | Matériel | CPU | RAM |
- **Haute disponibilité** : Trois nœuds pour garantir qu'aucun point de défaillance ne puisse tout interrompre. | --- | --- | --- | --- |
- **Stockage distribué** : Redondance des données entre les nœuds, non seulement pour garantir la disponibilité, mais aussi pour apprendre le fonctionnement des systèmes de stockage d'entreprise. | vertex | ASRock DeskMini A300 | Ryzen 3 2200G, 4 cœurs / 4 threads | 16 GB |
- **Segmentation du réseau** : Plusieurs VLAN pour imiter les topologies de réseau réelles, isoler les services et pratiquer la mise en réseau avancée. | apex | Minisforum HM50 | Ryzen 5 4500U, 6 cœurs / 6 threads | 32 GB |
### Contraintes | zenith | T-bao MN57 | Ryzen 7 5700U, 8 cœurs / 16 threads | 32 GB |
Bien sûr, la réalité ne correspond pas toujours aux ambitions. Voici ce à quoi je me suis heurté : Chacun dispose d'un SSD de 256 GB pour le système, les ISO et les templates, ainsi que d'un NVMe de 1 TB pour Ceph. Une interface 1 Gbps transporte le trafic LAN et management, et une interface 2.5 Gbps séparée est dédiée à Ceph.
- **Espace** : Mon lab devait tenir dans un petit espace de service cachée au milieu de mon appartement. Pas vraiment une salle de serveurs.
- **Bruit** : Le silence était crucial. Ce n'était pas un endroit caché dans un garage ou un sous-sol, mais en plein cœur de notre espace de vie.
- **Consommation électrique** : Fonctionnant 24/7, la consommation électrique devait être maîtrisée. Je ne pouvais pas me permettre de tripler ma facture d'électricité juste pour bricoler des machines virtuelles.
- **Budget** : Je n'allais pas dépenser des milliers d'euros pour du matériel professionnel. L'équilibre résidait dans la recherche d'un équipement d'occasion fiable et abordable.
- **Température** : Franchement, je n'y avais pas pensé… Les mini-PC ne chauffent pas beaucoup, mais le matériel réseau ? C'est une autre histoire. Leçon apprise.
En un mot, je souhaitais construire un mini datacenter dans un placard. Une quatrième machine, `granite`, est un Beelink ME mini avec un Intel N200 et 12 GB de RAM. Elle fait tourner TrueNAS indépendamment du cluster Proxmox. Cette séparation ne sert pas qu'au stockage.
--- ## Plateforme
## Présentation de l'Infrastructure ![Une sélection de VM dans le cluster Proxmox, avec TrueNAS à côté. Les VM OPNsense Master et Backup forment une paire HA répartie entre les deux plateformes d'hébergement.](images/homelab-hosting-overview.png)
Décomposons les composants de mon homelab. ### Proxmox et Ceph
### Rack
Que serait un datacenter sans rack ? Honnêtement, je ne pensais pas qu'un rack pourrait tenir dans mon espace limité, jusqu'à ce que je découvre le [DeskPi RackMate T1](https://deskpi.com/products/deskpi-rackmate-t1-2). [Proxmox VE 9]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}) fournit la couche de virtualisation sur les trois mini-PC. Ceph tourne sur les mêmes nœuds physiques, avec un NVMe par nœud et une réplication à trois copies sur le réseau dédié 2.5 Gbps. Il fournit le stockage partagé des VM et permet de déplacer les workloads entre les nœuds Proxmox.
Ce produit était parfait. Sa taille était idéale, sa qualité de fabrication impressionnante et sa conception modulaire m'a permis d'ajouter des accessoires supplémentaires, comme une multiprise et des étagères, pour compléter l'installation. C'est la base du lab, mais cela ne rend pas chaque application hautement disponible. Une VM peut toujours subir une panne interne, et une application peut casser dans une VM parfaitement saine. Les NVMe grand public et le réseau de stockage imposent aussi des limites concrètes aux performances.
### Serveurs
J'avais déjà un serveur qui constituait la pierre angulaire de mon homelab et je souhaitais le conserver. Cependant, il présentait deux inconvénients majeurs : ### TrueNAS
- **Interface réseau unique** : Je voulais au moins deux cartes réseau pour la segmentation et la redondance du réseau.
- **Matériel vieillissant** : Il avait plus de cinq ans et ses options de compatibilité devenaient limitées.
Pour la carte réseau manquante, j'ai envisagé un adaptateur USB, mais j'ai finalement trouvé une meilleure solution : utiliser le port M.2 interne, initialement prévu pour un module Wi-Fi, pour connecter un adaptateur 2,5 Gbit/s. C'était la solution idéale. [TrueNAS]({{< ref "post/18-create-nas-server-with-truenas" >}}) tourne sur `granite`, en dehors du cluster Proxmox. Son pool de stockage est un miroir de deux NVMe de 2 TB, avec des partages SMB pour les fichiers et NFSv4 pour les données applicatives. Les fichiers Nextcloud et les photos Immich vivent ici plutôt qu'à l'intérieur de leurs conteneurs.
Concernant le matériel, mon serveur actuel était équipé d'un Ryzen 3 2200G AM4 avec 16 Go de RAM DDR4. Pour garantir la cohérence et simplifier la compatibilité, j'ai décidé de conserver le socket AM4 pour tous les nœuds. Son rôle est différent de celui de Ceph : Ceph héberge les disques des VM, tandis que TrueNAS fournit les fichiers partagés et les photos. L'ancien conteneur NFS sur Vertex n'existe plus. TrueNAS héberge aussi la [VM OPNsense secondaire]({{< ref "post/19-migrate-passive-opnsense-node-to-truenas" >}}), avec son disque sur un zvol, pour garder ce firewall en dehors du domaine de panne de Proxmox et Ceph.
Les spécifications des deux nœuds supplémentaires étaient claires : un socket AM4 pour la cohérence, une faible consommation d'énergie, deux cartes réseau dont au moins une à 2,5 Gbit/s, et des options de stockage suffisantes, dont au moins un emplacement M.2 NVMe et une baie pour lecteur 2,5 pouces. L'AM4 étant un peu ancien, les modèles plus récents étaient exclus, ce qui était une bonne nouvelle pour mon budget, car j'ai pu acheter des mini-PC d'occasion. ### dockerVM
Voici les spec de mes nœuds : La plupart des applications tournent actuellement sur `dockerVM`, avec [une stack Docker Compose par application]({{< ref "post/16-how-I-deploy-application" >}}). Le disque de la VM est sur Ceph, tandis que les services qui ont besoin de données partagées montent les partages TrueNAS correspondants.
| **Node** | **Vertex** | **Apex** | **Zenith** | Docker reste la plateforme applicative du quotidien. C'est aussi un point de concentration : la plupart des services dépendent de cette seule VM, les mises à jour restent manuelles, et restaurer une application n'est pas la même chose que redémarrer sa VM ailleurs dans le cluster.
| --------- | ----------------------- | ----------------------- | ------------------------ |
| **Model** | ASRock DeskMini A300 | Minisforum HM50 | T-bao MN57 |
| **CPU** | AMD Ryzen 3 2200G 4C/4T | AMD Ryzen 5 4500U 6C/6T | AMD Ryzen 7 5700U 8C/16T |
| **TDP** | 65W | 15W | 15W |
| **RAM** | 16GB | 16GB | 32GB |
| **NIC** | 1Gbps (+ 2.5Gbps) | 1Gbps + 2.5Gbps | 1Gbps + 2.5Gbps |
| **M.2** | 2 | 1 | 1 |
| **2,5"** | 2 | 2 | 1 |
Chaque nœud a la même configuration de disque : un SSD de 256 Go dans la baie 2,5" pour le système d’exploitation et un disque NVMe de 1 To pour le stockage des données. ### Kubernetes
### Réseau
Pour le réseau, j’avais deux objectifs principaux : implémenter des VLAN pour la segmentation du réseau et gérer mon pare-feu pour un contrôle plus précis. Mes nœuds étant équipés de cartes réseau 2,5 Gbit/s, j’avais besoin de switchs capables de gérer ces débits, ainsi que de quelques ports Power over Ethernet (PoE) pour mon antenne Zigbee et ses futures fonctionnalités. Kubernetes est [la plateforme prévue pour prendre le relais de Compose]({{< ref "post/24-roadmap-migrate-docker-applications-kubernetes" >}}). Ses six VM tournent déjà sur Proxmox : trois nœuds control plane et trois workers, initialisés avec kubeadm et connectés avec Cilium. [Terraform provisionne les VM et Ansible les prépare]({{< ref "post/25-automate-kubernetes-vms-terraform-ansible" >}}) avant le bootstrap manuel du cluster.
Au départ, j’étais attiré par le matériel MikroTik, idéal pour apprendre, mais la disposition de leurs switchs ne correspondait pas vraiment à ma configuration. En revanche, la gamme UniFi d’Ubiquiti était la solution de facilité, avec son interface utilisateur élégante et son esthétique matérielle impressionnante. Les fondations fonctionnent, mais aucune application n'y a encore été déplacée. La gateway Traefik de Kubernetes et cert-manager restent à déployer, puis il faudra travailler sur le stockage et sa protection avant la migration progressive. GitOps viendra plus tard. L'instance Traefik qui dessert les applications Docker aujourd'hui est une installation distincte.
Pour le routeur, je ne voulais pas de passerelle UniFi. Je voulais quelque chose de plus personnalisable, avec lequel je pouvais bidouiller. Après quelques recherches, j’ai opté pour OPNsense plutôt que pfSense. Il paraît que c'est un peu plus adapté aux débutants, et jusqu'à présent, je ne l'ai pas regretté. ## Réseau
Voici la configuration réseau finale : ### UniFi pour le réseau filaire et le Wi-Fi
- **Routeur :** OPNsense fonctionnant sur un boîtier Topton sans ventilateur avec un processeur Intel N100, 16 Go de RAM et 4 ports 2,5 Gbit/s.
- **Swtich :** [UniFi Switch Lite 16 PoE](https://eu.store.ui.com/eu/en/category/switching-utility/products/usw-lite-16-poe), 8 ports PoE 1 Gbit/s et 8 ports non PoE.
- **Swtich :** [UniFi Flex Mini 2,5 G](https://eu.store.ui.com/eu/en/category/switching-utility/products/usw-flex-2-5g-5), 5 ports 2,5 Gbit/s, dont un port PoE entrant.
- **Point d'accès :** [UniFi U7 Pro Wall](https://eu.store.ui.com/eu/en/category/all-wifi/products/u7-pro-wall), Wi-Fi 7, 2,5 Gbit/s PoE+ entrant.
### Stockage
Bien que je n'aie pas besoin d'un stockage important, il me fallait une configuration flexible pour stocker les datas de mon homelab, ainsi que mes médias et documents personnels. Le réseau physique utilise un UniFi Switch Lite 16 PoE, un Flex Mini 2.5G dédié à Ceph et un point d'accès U7 Pro Wall. L'application UniFi Network tourne dans un conteneur sur `dockerVM` et gère ces équipements.
Chaque nœud Proxmox est équipé d'un SSD SATA de 256 Go pour le système d'exploitation, les fichiers ISO et les templates VM/LXC. Pour le stockage des datas, j'ai ajouté un disque NVMe de 1 To par nœud, qui constitue la base de mon cluster Ceph. Cela me permet d'obtenir un stockage distribué, redondant et performant pour les VM et les conteneurs, ce qui permet une migration à chaud et une haute disponibilité sur l'ensemble du cluster. Les [VLAN]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}) séparent les appareils des utilisateurs, les équipements IoT, le lab, la DMZ et le management. Des réseaux sont également dédiés au WAN, à la synchronisation des firewalls, au heartbeat Proxmox, à Ceph et à l'accès VPN. UniFi transporte le trafic ; OPNsense décide de ce qui peut passer entre les segments routés.
À l'origine, mon premier serveur était équipé de deux disques durs de 1 To installés en interne. Comme j'avais besoin d'un emplacement pour le SSD, je les ai déplacés hors du boîtier à l'aide d'adaptateurs USB vers SATA et les ai reconnectés au même nœud. Ces disques stockent mes photos, mes documents Nextcloud et mes sauvegardes, des données moins critiques pour les performances qui n'ont pas besoin de rester sur Ceph. Ils sont servis sur le réseau à l’aide d’un serveur NFS situé dans un conteneur LXC sur ce nœud. ### OPNsense pour le routage et le firewall
### Refroidissement
J'ai vite compris que mon équipement réseau transformait mon placard en mini-fournaise. Heureusement, j'ai commencé la construction en décembre, donc la chaleur n'était pas trop perceptible, mais avec l'été, elle allait forcément devenir un vrai problème. Les [deux VM firewall]({{< ref "post/15-migration-opnsense-proxmox-highly-available" >}}) sont `cerbere-head1`, le Master sur Proxmox, et `cerbere-head2`, le Backup sur TrueNAS. CARP assure la redondance des passerelles, pfSync synchronise l'état des connexions et XMLRPC synchronise la configuration.
Les options étaient limitées, impossible de convaincre ma femme que nos serveurs avaient besoin d'un système de refroidissement. De plus, il fallait que ce soit silencieux. Une combinaison difficile. Héberger le Backup sur TrueNAS permet de ne pas perdre les deux VM firewall quand le cluster Proxmox ou Ceph est arrêté. Cela améliore la résilience du firewall, sans prétendre que chaque switch, câble ou autre composant est lui aussi redondant.
La meilleure solution que j'ai trouvée a été de percer deux trous de 40 mm au-dessus du meuble de cuisine. J'ai fait passer des tuyaux en PVC dans le mur et installé deux petits ventilateurs, chacun recouvert de mousse pour minimiser les vibrations et le bruit. Dnsmasq fournit le DHCP et les noms locaux. Unbound assure la résolution DNS récursive avec les blocklists Hagezi, et WireGuard permet l'accès distant depuis mes appareils mobiles.
À l'intérieur du rack, j'ai également ajouté deux ventilateurs de 80 mm pour améliorer la circulation de l'air. Pour un fonctionnement silencieux, j'ai branché un contrôleur PWM pour réguler la vitesse des ventilateurs, trouvant ainsi un équilibre entre circulation d'air et silence. [HAProxy tourne sur OPNsense]({{< ref "post/23-install-haproxy-opnsense-replace-caddy" >}}) et distribue les connexions HTTPS entrantes. Les services hébergés dans Docker passent par Traefik sur `dockerVM` ; les interfaces d'infrastructure utilisent une branche reverse proxy HTTPS séparée sur OPNsense. Le plugin ACME d'OPNsense gère le renouvellement des certificats d'infrastructure sur le firewall principal.
### Photos
Voici à quoi ça ressemble : ## Applications
![Front view of my homelab with legend](img/homelab-rack-legend.png) Les applications ci-dessous tournent encore sur `dockerVM`. Certaines sont des services utilisés à la maison, tandis que d'autres servent au réseau, à l'automatisation ou au blog lui-même.
![Different views of my homelab with open and closed enclosure](img/homelab-enclore-open-closed.png) | Application | Ce que j'en fais |
| --- | --- |
| Home Assistant | Intégrer les appareils connectés et faire tourner la domotique. |
| Node-RED | Construire visuellement des flows d'automatisation avec Home Assistant, notamment pour le [contrôle de la climatisation Daikin]({{< ref "post/6-ac-automation-home-assistant-node-red" >}}). |
| InfluxDB | Stocker les données historiques de Home Assistant. |
| Nextcloud | Synchroniser des fichiers et collaborer, avec les données sur un partage TrueNAS. |
| Immich | Gérer les photos et vidéos, avec la photothèque sur TrueNAS. |
| Vaultwarden | Héberger un gestionnaire de mots de passe léger, compatible avec Bitwarden. |
| Jellyfin | Servir la bibliothèque multimédia. |
| ARR stack | Automatiser l'acquisition et l'organisation des médias avec Sonarr, Radarr, Prowlarr et les outils associés. |
| Gitea | Héberger les dépôts Git et exécuter les workflows CI/CD avec Gitea Actions. |
| Hugo blog | Générer ce site statique à partir du Markdown dans Obsidian, puis le servir avec Nginx. |
| Umami | Collecter les statistiques de fréquentation du blog. |
| Traefik | Acheminer les requêtes vers les applications Docker derrière OPNsense HAProxy et assurer la terminaison de leurs connexions HTTPS. |
| UniFi Network Application | Gérer les switchs et le point d'accès Wi-Fi. |
| [Semaphore UI]({{< ref "post/17-semaphore-ui-interface-ansible-terraform" >}}) | Lancer les automatisations Ansible et Terraform depuis une interface web. |
| Portainer | Inspecter et gérer les conteneurs Docker, les stacks et les logs. |
| [Ntfy]({{< ref "post/5-notification-system-gotify-vs-ntfy" >}}) | Envoyer des notifications push depuis les déploiements, les exécutions d'automatisations et les services multimédias. |
--- ## Documentation avec Obsidian
## Stack Logicielle
Une fois les fondations matérielles posées, l'étape suivante consistait à déterminer la partie software qui orchestrerait l'ensemble, véritable moteur de chaque expérience, déploiement et opportunité d'apprentissage. Obsidian est l'endroit où je conserve la documentation du lab. Les projets, les journaux de tâches, les références techniques et l'inventaire de l'infrastructure vivent dans le même vault, sous forme de fichiers Markdown locaux versionnés dans Gitea. J'y garde à la fois ce qui tourne et la manière dont c'est arrivé là, y compris les décisions et les dépannages derrière un changement.
### Hyperviseur
Au cœur de ma configuration se trouve un cluster Proxmox VE 8 à 3 nœuds, un hyperviseur basé sur KVM prenant également en charge les conteneurs LXC. Basé sur Debian, il offre des fonctionnalités essentielles telles que la migration à chaud, la haute disponibilité et l'intégration de Ceph, prêtes à l'emploi. C'est aussi là que j'écris ce blog. Les articles commencent dans le dossier `Blog/` du vault, et [Gitea Actions et Hugo transforment ces notes en site]({{< ref "post/2-blog-deployment-obisidan-hugo-gitea-actions" >}}), celui que vous lisez. Seul le contenu du blog est envoyé au site ; les notes de projet et l'inventaire restent dans le vault.
Pour l'instant, j'utilise principalement une seule VM et un seul conteneur LXC. La VM est en quelque sorte un clone de mon ancien serveur physique, hébergeant la plupart de mes applications sous forme de conteneurs Docker. Le conteneur LXC sert de simple jump server. Obsidian tourne lui-même en local, ce n'est pas un service supplémentaire sur `dockerVM`. Gitea héberge le dépôt du vault, tandis que Hugo génère le site public.
### Réseau
L'objectif de mon réseau était d'implémenter des VLAN pour la segmentation et de gérer directement les règles de pare-feu afin de simuler des configurations plus complexes. ## Toujours en chantier
#### Routeur et pare-feu
Au cœur de ce réseau se trouve **OPNsense**, fonctionnant dans un boîtier dédié sans ventilateur. Le routeur du FAI est en mode pont et transmet tout le trafic à OPNsense, qui gère toutes les fonctions de routage et de pare-feu. Le trafic inter-VLAN est restreint, des règles de pare-feu explicites sont obligatoires, et seul le VLAN de management a accès aux autres segments. Le setup est plus résilient que le serveur unique d'origine, mais il garde des limites évidentes. La plupart des applications dépendent de `dockerVM`, le NAS est une machine unique, et TrueNAS nécessite actuellement des redémarrages périodiques pour contourner une augmentation de l'utilisation mémoire non résolue. Le firewall secondaire vit sur cette machine : le problème ne concerne donc pas que le stockage des fichiers.
#### Réseau L2
Le réseau de couche 2 est géré par des **switchs UniFi**, choisis pour leur interface utilisateur épurée et leur simplicité. Le contrôleur UniFi, qui gère la configuration des appareils, fonctionne en tant que plugin sur OPNsense. Cela fait aussi partie du lab. Cette page en donne la vue d'ensemble ; les articles racontent comment les différents éléments sont arrivés là et ce qui change ensuite.
Le point d'accès diffuse deux SSID : un pour les ordinateurs et téléphones portables de ma famille (5 et 6 GHz) et l'autre uniquement en 2,4 GHz pour tout le reste (IoT, aspirateur, climatisation, imprimante, Chromecast, etc.).
Un switch UniFi 2,5 Gbit/s est dédié aux communications de Ceph, isolant le trafic de stockage pour éviter les interférences avec d'autres réseaux.
J'ai configuré **LACP** (agrégation de liens) entre le routeur et le commutateur principal à 1 Gbit/s, dans l'espoir de doubler la bande passante. En réalité : une session n'utilise qu'un seul lien, ce qui signifie qu'un téléchargement unique est toujours plafonné à 1 Gbit/s.
#### VLAN
Pour segmenter le trafic, j'ai divisé le réseau en plusieurs VLAN :
| Nom | ID | Rôle |
| --------- | ---- | ---------------------------- |
| User | 13 | Home network |
| IoT | 37 | IoT and untrusted equipments |
| DMZ | 55 | Internet facing |
| Lab | 66 | Lab network, trusted |
| Heartbeat | 77 | Proxmox cluster heartbeat |
| Mgmt | 88 | Management |
| Ceph | 99 | Ceph |
| VPN | 1337 | Wireguard network |
Chaque VLAN possède son propre pool DHCP géré par OPNsense, à l'exception des VLAN Heartbeat et Ceph.
#### DNS
Au sein d'OPNsense, le DNS est structuré en deux couches :
- ADguard Home : filtres de publicités et de traqueurs, sert chaque client du réseau sur le port DNS standard 53.
- Unbound DNS : DNS récursif, distribue uniquement le service DNS ADguard Home en interne.
#### Reverse Proxy
**Caddy** fonctionne comme plugin sur OPNsense et sert de point d'entrée principal pour le trafic web. Il achemine les requêtes en fonction des sous-domaines, gère automatiquement les certificats HTTPS et drop les accès aux services internes provenant du WAN.
La plupart des services sont toujours gérés par une instance **Traefik** exécutée sur ma VM. Dans ce cas, Caddy transfère simplement les requêtes HTTPS directement à Traefik.
Cette configuration de proxy à deux couches centralise la gestion des certificats SSL dans **Caddy** tout en préservant un routage interne flexible et dynamique avec **Traefik**.
#### VPN
Pour un accès distant sécurisé, j'ai configuré **WireGuard** sur OPNsense. Ce VPN léger fournit une connectivité chiffrée à mon lab où que je sois, permettant ainsi de gérer tous mes services sans les exposer directement à Internet.
#### Schéma Réseau
![Diagram of my home network ](img/homelab-network-schema.png)
### Application
Plongeons dans la partie fun ! Ce qui a commencé comme une modeste configuration destinée à répondre à quelques besoins personnels s'est rapidement transformé en un écosystème complet de services open source, chacun répondant à un besoin spécifique ou simplement à la curiosité.
Voici un aperçu de ce qui fonctionne actuellement dans mon homelab :
- **Home Assistant** : Plateforme centralisée pour la domotique, intégrant des appareils connectés et des routines.
- **Vaultwarden** : Alternative légère à Bitwarden pour gérer et synchroniser les mots de passe en toute sécurité.
- **Nextcloud** : Stockage cloud self-hosted.
- **Gitea** : Solution de dépôt Git pour gérer mon code et mes projets.
- **Blog** : Mon blog personnel basé sur Hugo, que vous lisez actuellement.
- **Immich** : Application de gestion de photos et de vidéos, similaire à Google Photos.
- **Jellyfin** : Serveur multimédia pour le streaming de films et de séries.
- **ARR Stack** : Outils d'acquisition multimédia automatisés. (Radarr, Sonarr, Torrent, etc.)
- **Duplicati** : Solution de sauvegarde chiffrée pour mes données et configurations importantes.
- **Prometheus** : Outil de surveillance et de collecte de métriques, utilisé avec Grafana pour les tableaux de bord.
- **Portainer** : Interface web pour la gestion des conteneurs et des stacks Docker.
- **Umami** : Analyses axées sur la confidentialité pour le suivi des visites sur mon blog.
- **phpIPAM** : Outil de gestion des adresses IP pour l'organisation de mes VLAN et sous-réseaux.
#### Docker
Docker a véritablement révolutionné mon aventure homelab. Avant les conteneurs, gérer plusieurs services sur un seul serveur était une bataille constante avec les dépendances et les conflits. Aujourd'hui, chaque service fonctionne parfaitement, géré par Docker Compose au sein d'une seule VM. Traefik gère dynamiquement le reverse proxy, simplifiant ainsi l'accès et les certificats SSL.
#### Kubernetes
Mon prochain grand défi est de faire passer l'orchestration des conteneurs au niveau supérieur. Si Docker Swarm pouvait répondre à ce besoin technique, mon objectif principal est d'acquérir une expérience pratique de Kubernetes, et il n'y a pas de meilleur moyen d'apprendre que de l'appliquer à des cas d'utilisation concrets.
---
## Derniers Mots
Merci d'avoir pris le temps de lire mon aventure homelab !
Construire et peaufiner cette configuration a été une formidable source d'apprentissage et de plaisir, et je suis toujours à la recherche de nouvelles façons de l'améliorer.
Si vous avez des idées, des commentaires, de meilleures solutions, ou si vous souhaitez simplement partager votre propre configuration, n'hésitez pas à me contacter. Envoyez-moi un message, challengez mes choix ou partagez votre histoire avec moi !
+70 -162
View File
@@ -1,7 +1,7 @@
--- ---
title: Welcome to my Homelab title: Welcome to my Homelab
layout: page layout: page
description: The story behind my homelab project, from a Raspberry Pi to a tiny datacenter, where I experiment with Proxmox, Kubernetes, automation and more. description: Inside my compact homelab, with Proxmox, Ceph, TrueNAS and OPNsense, the services it runs today and my ongoing Kubernetes migration project.
showToc: true showToc: true
menu: menu:
main: main:
@@ -10,212 +10,120 @@ menu:
params: params:
icon: flask icon: flask
--- ---
## Intro
My homelab journey began in 2013 with a humble Raspberry Pi, the very first model. I was needing a cheap machine for my first step into the world of Linux. It helped me a lot to dive into this technology and served me as a basic NAS, thank you Vezpibox (shitty name, I know) My homelab started in 2013 with the first Raspberry Pi. I wanted a cheap machine to learn Linux, and it became a basic NAS called Vezpibox. The name hasn't aged particularly well.
In 2015, I upgraded to a Raspberry Pi 2, seeking better performance to run multiple applications like XBMC (the old Kodi's name), CouchPotato, SickBeard... 😇 More Raspberry Pis followed, then a mini PC in 2019, when I started experimenting with virtualization and Docker at home. Eventually, that single server became a problem: it was both my playground and the machine keeping useful things running. Breaking a test environment is one thing. Taking the lights or the internet down with it is another.
By 2018, the need for more RAM led me to a Raspberry Pi 3, allowing me to run even more applications. My 3 little machines were running happily together, in a quite ordered mess. Today, the lab has a three-node Proxmox cluster, distributed storage, a separate NAS and a redundant firewall pair. Most applications still run in Docker Compose. Kubernetes is running too, but moving the applications is the next part of the project, not something I've already finished.
Finally, in 2019, my new job made me experiment the virtualization, with virtual machines and above all Docker. I wanted to try that at home, I took a significant step forward with a compact yet quite powerful headless mini PC that laid the foundation of my homelab. *Last reviewed: October 2026.*
--- ## A lab inside a cupboard
## Why a Homelab ?
I wanted my own playground, a space where I could build but also safely break things, learn to fix them, and gain a deeper understanding of how they work. The original idea was to build a tiny datacenter in a closet. Space, noise, power consumption and budget all mattered, so the setup grew around compact machines rather than rack servers.
My single server was great, but testing anything risky on it became a problem. It was running critical services like home automation or DNS, when it was down, everything was down. The server had become indispensable, and believe me, having no lights or internet is a major incident in my family. Not so fun anymore. ![The homelab enclosure open and closed, next to the kitchen. The available space is part of the design, not an unlimited server room.](images/homelab-enclore-open-closed.png)
The first big challenge I set for myself was building a Kubernetes cluster. Sure, I could run one on a single node, but what’s the point of a cluster with only one node? You could argue that running Kubernetes to control my shutters is overkill, and you’d be right. But that wasn’t the point. The rack is a DeskPi RackMate T1. It fits into the narrow enclosure, with shelves and a power strip to make use of the available space. With the door closed, the lab disappears into the apartment.
I also wanted to spawn new virtual machines at will, rebuild them from scratch, and apply Infrastructure as Code principles. I could have done all of that in the cloud, but I wanted full control. ![The original rack layout. The router and HDD labels show the earlier setup; the current firewall and storage architecture is described below.](images/homelab-rack-legend.png)
Initially, my goal was to provide high availability for my existing services. One server wasn’t enough. So, I wanted a second node. But in most HA setups, three nodes are the sweet spot. And just like that, I was on my way to building what would become my homelab. Cooling needed some attention too. During the original build, I added two 40 mm extraction fans above the cabinet, with PVC ducts and foam to limit vibration. Two 80 mm fans inside the rack and a PWM controller helped balance airflow and noise. In a cupboard in the middle of a living space, fitting the machines is only half the problem.
--- ## The hardware
## Shaping the Lab
First, I needed to define what my homelab was actually supposed to do. I wanted it to host my existing services reliably, but that wasn’t enough, I wanted a true playground, capable of simulating a more complex enterprise environment. The three Proxmox nodes are different mini PCs:
### Blueprint
That meant: | Node | Hardware | CPU | RAM |
- **High Availability:** Three nodes to ensure that no single point of failure would bring everything down. | --- | --- | --- | --- |
- **Distributed Storage:** Data redundancy across nodes, not just for uptime but also to learn how enterprise-grade storage systems work. | vertex | ASRock DeskMini A300 | Ryzen 3 2200G, 4 cores / 4 threads | 16 GB |
- **Network Segmentation:** Multiple VLANs to mimic real-world network topologies, isolate services, and practice advanced networking. | apex | Minisforum HM50 | Ryzen 5 4500U, 6 cores / 6 threads | 32 GB |
### Constraints | zenith | T-bao MN57 | Ryzen 7 5700U, 8 cores / 16 threads | 32 GB |
Of course, reality doesn’t always align with ambitions. Here’s what I was up against: Each has a 256 GB SSD for the operating system, ISOs and templates, plus a 1 TB NVMe drive for Ceph. A 1 Gbps interface carries LAN and management traffic, and a separate 2.5 Gbps interface is dedicated to Ceph.
- **Space:** My lab needed to fit in a small, hidden service enclosure in the middle of my apartment. Not exactly a server room.
- **Noise:** Silence was crucial. This wasn’t going to be tucked away in a garage or basement, it was right in the middle of our living space.
- **Power Draw:** Running 24/7, the power consumption had to be kept in check. I couldn’t afford to triple my electric bill just to tinker with VMs.
- **Budget:** I wasn’t going to drop thousands on enterprise-grade hardware. The balance was finding reliable, second-hand gear that wouldn’t break the bank.
- **Temperature**: I’m not gonna lie, I hadn't thought of it... Mini PCs don’t generate much heat, but network gear? That’s a different story. Lesson learned.
In a nutshell, I wanted to build a tiny datacenter in a closet. A fourth machine, `granite`, is a Beelink ME mini with an Intel N200 and 12 GB of RAM. It runs TrueNAS separately from the Proxmox cluster. That separation matters for more than storage.
--- ## Platform
## Infrastructure Overview
Let’s break down the components that make up my homelab. ![Selected VMs inside the Proxmox cluster, with TrueNAS alongside it. The OPNsense Master and Backup VMs form one HA pair across the two hosting platforms.](images/homelab-hosting-overview.png)
### Rack
What is a datacenter without a rack? Honestly, I didn’t think one would fit in my limited space, until I discovered the [DeskPi RackMate T1](https://deskpi.com/products/deskpi-rackmate-t1-2). ### Proxmox and Ceph
This beauty was the perfect match. The size was spot-on, the build quality impressive, and the modular design allowed me to add some extra accessories, like a power strip and shelves, to complete the setup. [Proxmox VE 9]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}) provides the virtualization layer across the three mini PCs. Ceph runs on the same physical nodes, using one NVMe drive per node and three-way replication over the dedicated 2.5 Gbps network. It provides shared VM storage and allows workloads to move between Proxmox nodes.
### Servers
I already had one server that served as the cornerstone of my homelab, and I wanted to keep it. But it had two major drawbacks: That is the foundation for the lab, but it does not make every application highly available. A VM can still fail internally, and an application can still break inside a perfectly healthy VM. Consumer NVMe drives and the storage network also put practical limits on performance.
- **Single Network Interface:** I wanted at least two NICs for network segmentation and redundancy.
- **Aging Hardware:** It was over five years old, and its compatibility options were becoming limited.
For the missing NIC, I considered a USB adapter but then stumbled upon a better solution: using the internal M.2 port, originally meant for a WiFi module, to connect a 2.5Gbps adapter. It was a perfect fit. ### TrueNAS
Regarding hardware, my existing server was powered by an AM4 Ryzen 3 2200G with 16GB of RAM DDR4. To keep things consistent and simplify compatibility, I decided to stick with the AM4 socket for all nodes. [TrueNAS]({{< ref "post/18-create-nas-server-with-truenas" >}}) runs on `granite`, outside the Proxmox cluster. Its storage pool is a mirror of two 2 TB NVMe drives, with SMB file sharing and NFSv4 shares for application data. Nextcloud files and Immich photos live here rather than inside their containers.
The specifications for the two additional nodes were clear: an AM4 socket for consistency, low power consumption, dual NICs with at least one 2.5Gbps, and sufficient storage options, at least one M.2 NVMe slot and a 2.5" drive bay. Since AM4 is somewhat dated, newer models were off the table, a good news for my budget, as I was able to buy second-hand mini PCs. This is a different storage job from Ceph: Ceph holds VM disks, while TrueNAS provides shared files and photos. The old NFS container on Vertex is gone. TrueNAS also hosts the [backup OPNsense VM]({{< ref "post/19-migrate-passive-opnsense-node-to-truenas" >}}), with its disk on a zvol, keeping that firewall outside the Proxmox and Ceph failure domain.
Here is the specs of my nodes: ### dockerVM
| **Node** | **Vertex** | **Apex** | **Zenith** | Most applications currently run on `dockerVM`, with [one Docker Compose stack per application]({{< ref "post/16-how-I-deploy-application" >}}). Its VM disk lives on Ceph, while services that need shared data mount the relevant TrueNAS shares.
| --------- | ----------------------- | ----------------------- | ------------------------ |
| **Model** | ASRock DeskMini A300 | Minisforum HM50 | T-bao MN57 |
| **CPU** | AMD Ryzen 3 2200G 4C/4T | AMD Ryzen 5 4500U 6C/6T | AMD Ryzen 7 5700U 8C/16T |
| **TDP** | 65W | 15W | 15W |
| **RAM** | 16GB | 16GB | 32GB |
| **NIC** | 1Gbps (+ 2.5Gbps) | 1Gbps + 2.5Gbps | 1Gbps + 2.5Gbps |
| **M.2** | 2 | 1 | 1 |
| **2,5"** | 2 | 2 | 1 |
Each node follows the same disk layout: a 256GB SSD in the 2.5" bay for the operating system and a 1TB NVMe drive for data storage. Docker remains the everyday application platform. It is also a concentration point: most services depend on this one VM, updates are still manual, and recovering an application is not the same thing as restarting its VM elsewhere in the cluster.
### Network
For the network, I had two main objectives: implement VLANs for network segmentation and manage my firewall for more granular control. Since my nodes were equipped with 2.5Gbps NICs, I needed switches that could handle those speeds, and a few Power over Ethernet (PoE) ports for my Zigbee antenna and what could come after. ### Kubernetes
Initially, I was drawn to MikroTik hardware, great for learning, but their switch layouts didn’t quite align with my setup. On the other hand, Ubiquiti's UniFi line was the easy route with their with a sleek UI and impressive hardware aesthetics. Kubernetes is the [intended replacement for the Compose application platform]({{< ref "post/24-roadmap-migrate-docker-applications-kubernetes" >}}). Its six VMs already run on Proxmox: three control-plane nodes and three workers, bootstrapped with kubeadm and connected with Cilium. [Terraform provisions the VMs and Ansible prepares them]({{< ref "post/25-automate-kubernetes-vms-terraform-ansible" >}}) before the manual cluster bootstrap.
For the router, I opted against the UniFi gateway. I wanted something more customizable, something I could get my hands dirty with. After some research, I settled on OPNsense over pfSense, it was said to be a bit more beginner-friendly, and so far, I haven’t regretted it. The foundation is running, but no applications have moved there yet. The Kubernetes Traefik gateway and cert-manager are still to be deployed, followed by storage and protection work before the gradual migration. GitOps comes later. The Traefik instance serving Docker applications today is a separate installation.
Here is the final network setup: ## Network
- **Router:** OPNsense running on a fanless Topton box with an Intel N100, 16GB RAM, and 4x 2.5Gbps ports.
- **Switch:** [UniFi Switch Lite 16 PoE](https://eu.store.ui.com/eu/en/category/switching-utility/products/usw-lite-16-poe), 8x 1Gbps PoE ports and 8x non-PoE ports.
- **Switch:** [UniFi Flex Mini 2.5G](https://eu.store.ui.com/eu/en/category/switching-utility/products/usw-flex-2-5g-5), 5x 2.5Gbps ports, with one PoE-in port.
- **Access Point:** [UniFi U7 Pro Wall](https://eu.store.ui.com/eu/en/category/all-wifi/products/u7-pro-wall), Wi-Fi 7, 2.5Gbps PoE+ in.
### Storage
While I don't have massive storage requirement, I still needed a flexible setup to either store my homelab workload and my personal media and documents. ### UniFi for switching and Wi-Fi
Each Proxmox node is equipped with a **256GB SATA SSD** for the operating system, ISO files, and VM/LXC templates. For the workload storage, I added a **1TB NVMe drive** per node, which forms the basis of my **Ceph cluster**. This gives me distributed, redundant, and high-performance storage for VMs and containers, which allows live migration and high availability across the cluster. The physical network uses a UniFi Switch Lite 16 PoE, a Flex Mini 2.5G dedicated to Ceph, and a U7 Pro Wall access point. The UniFi Network Application runs as a container on `dockerVM` and manages those devices.
Originally, my first server had two **1TB HDDs** installed internally. Because I needed a slot for the SSD, I moved them outside the case using **USB-to-SATA adapters** and reconnected them to the same node. These drives store my photos, Nextcloud documents and backups, less performance-critical data that doesn’t need to sit on Ceph. They are served on the network using a NFS server sitting in a LXC container on that node. [VLANs]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}) separate user devices, IoT equipment, the lab, the DMZ and management. There are also dedicated networks for the WAN, firewall synchronization, Proxmox heartbeat, Ceph and VPN access. UniFi carries the traffic; OPNsense decides what can cross between the routed segments.
### Cooling
I quickly learned that my network gear was turning my closet into a mini furnace. Fortunately, I started the build in December, so the heat wasn’t too noticeable, but come summer, it was bound to become a real problem. ### OPNsense for routing and firewalling
Options were limited, there was no way I was going to convince my wife that our servers needed a cooling system. Plus, it had to be silent. Not an easy combo. The [two firewall VMs]({{< ref "post/15-migration-opnsense-proxmox-highly-available" >}}) are `cerbere-head1`, the Master on Proxmox, and `cerbere-head2`, the Backup on TrueNAS. CARP provides gateway redundancy, pfSync synchronizes connection state, and XMLRPC synchronizes configuration.
The best solution I came up with was to drill two 40mm holes above the kitchen cabinet. I ran PVC pipes through the wall and installed two small fans, each cushioned with foam to minimize vibrations and keep noise down. Hosting the Backup on TrueNAS means that taking the Proxmox or Ceph cluster down does not take both firewall VMs with it. This improves the firewall's resilience, without pretending that every switch, cable or other component is redundant too.
Inside the rack, I also added two 80mm fans to help with airflow. To keep everything quiet, I hooked up a PWM controller to regulate fan speeds, striking a balance between airflow and silence. Dnsmasq provides DHCP and local naming. Unbound handles recursive DNS with Hagezi blocklists, and WireGuard provides remote access for my mobile devices.
### Photos
Here what is look like: [HAProxy runs on OPNsense]({{< ref "post/23-install-haproxy-opnsense-replace-caddy" >}}) and dispatches incoming HTTPS connections. Docker-hosted services go through Traefik on `dockerVM`; infrastructure interfaces use a separate HTTPS reverse-proxy branch on OPNsense. The OPNsense ACME plugin handles infrastructure certificate renewal on the primary firewall.
![Front view of my homelab with legend](img/homelab-rack-legend.png) ## Applications
![Different views of my homelab with open and closed enclosure](img/homelab-enclore-open-closed.png) The applications below still run on `dockerVM`. Some are services used at home, while others support the network, automation or the blog itself.
| Application | What I use it for |
| --- | --- |
| Home Assistant | Integrating connected devices and running home automation. |
| Node-RED | Visual automation flows alongside Home Assistant, including [Daikin AC control]({{< ref "post/6-ac-automation-home-assistant-node-red" >}}). |
| InfluxDB | Storing historical Home Assistant data. |
| Nextcloud | File synchronization and collaboration, with its data on a TrueNAS share. |
| Immich | Managing photos and videos, with the photo library on TrueNAS. |
| Vaultwarden | Hosting a lightweight Bitwarden-compatible password manager. |
| Jellyfin | Serving the media library. |
| ARR stack | Automating media acquisition and organization with Sonarr, Radarr, Prowlarr and related tools. |
| Gitea | Hosting Git repositories and running CI/CD workflows with Gitea Actions. |
| Hugo blog | Generating this static website from Markdown in Obsidian, then serving it through Nginx. |
| Umami | Collecting web analytics for the blog. |
| Traefik | Routing requests to Docker applications behind OPNsense HAProxy and terminating their HTTPS connections. |
| UniFi Network Application | Managing the switches and Wi-Fi access point. |
| [Semaphore UI]({{< ref "post/17-semaphore-ui-interface-ansible-terraform" >}}) | Launching Ansible and Terraform automation from a web interface. |
| Portainer | Inspecting and managing the Docker containers, stacks and logs. |
| [Ntfy]({{< ref "post/5-notification-system-gotify-vs-ntfy" >}}) | Delivering push notifications from deployments, automation runs and media services. |
--- ## Documentation with Obsidian
## Software Stack
With the hardware foundation set, the next step was to decide what software would orchestrate everything, the real engine behind every experiment, deployment, and learning opportunity. Obsidian is where I keep the lab's documentation. Projects, task logs, technical references and the infrastructure inventory live in the same vault, as local Markdown files versioned in Gitea. That gives me somewhere to record both what is running and how it got there, including the decisions and troubleshooting behind a change.
### Hypervisor
At the core of my setup is a 3-node Proxmox VE 8 cluster, a KVM-based hypervisor that also supports LXC containers. Built on Debian, it provides essential features like live migration, HA, and seamless Ceph integration right out of the box. It is also where I write this blog. The articles start in the vault's `Blog/` folder, and [Gitea Actions and Hugo turn those notes into the site]({{< ref "post/2-blog-deployment-obisidan-hugo-gitea-actions" >}}) you are reading. Only the blog content is sent to the website; the project notes and inventory stay in the vault.
For now, I’m primarily running just one VM and one LXC container. The VM is essentially a clone of my old physical server, hosting most of my applications as Docker containers. The LXC container serves as a simple jump server. Obsidian itself runs locally, rather than as another service on `dockerVM`. Gitea hosts the vault repository, while Hugo generates the public website.
### Network
The objective for my network was to implement VLANs for segmentation and manage firewall rules directly to simulate more complex setups. ## Still a work in progress
#### Router and Firewall The setup is more resilient than the original single server, but it still has obvious limits. Most applications depend on `dockerVM`, the NAS is a single host, and TrueNAS currently needs periodic restarts to work around unresolved memory growth. The firewall backup lives on that host, so the issue matters beyond file storage.
At the heart of this network is **OPNsense**, running on a dedicated fanless box. The ISP router is in bridge mode, passing all traffic to OPNsense, which handles all routing and firewall duties. Inter-VLAN traffic is restricted, explicit firewall rules are mandatory, only the management VLAN having access to other segments. Those are part of the lab too. This page is the overview; the articles document how the pieces got here and what changes next.
#### L2 Network
Layer 2 networking is managed by **UniFi switches**, chosen for their sleek UI and simplicity. The UniFi controller, which manages the devices configuration, runs as a plugin on OPNsense.
The access point is broadcasting 2 SSIDs, one for my family's laptops and cellulars (5 and 6Ghz) and the other only in 2.4Ghz for everything else (IoT, vacuum, AC, printer, Chromecast, etc.)
A 2.5Gbps UniFi switch is dedicated to Ceph storage communications, isolating storage traffic to prevent interference with other networks.
I set up **LACP** (Link Aggregation) between the router and the main switch at 1Gbps, hoping to double bandwidth. Reality check: a single session will only use one link, meaning that a single download will still cap at 1Gbps.
#### VLANs
To segment traffic, I divided the network into several VLANs:
| Name | ID | Purpose |
| --------- | ---- | ---------------------------- |
| User | 13 | Home network |
| IoT | 37 | IoT and untrusted equipments |
| DMZ | 55 | Internet facing |
| Lab | 66 | Lab network, trusted |
| Heartbeat | 77 | Proxmox cluster heartbeat |
| Mgmt | 88 | Management |
| Ceph | 99 | Ceph |
| VPN | 1337 | Wireguard network |
Each VLAN has its own DHCP pool managed by OPNsense, excepted the Heartbeat and Ceph ones.
#### DNS
DNS is structured in two layers within OPNsense:
- ADguard Home: ads and trackers filters, serves every client on the network over plain DNS on port 53
- Unbound DNS: recursive DNS, serves only the ADguard Home DNS service locally
#### Reverse Proxy
**Caddy** runs as a plugin on OPNsense and acts as the main entry point for web traffic. It routes requests based on subdomains and automatically handles HTTPS certificates and drops internal service access coming from the WAN.
Most services are still managed by a **Traefik** instance running on my VM. In those cases, Caddy simply forwards HTTPS requests directly to Traefik.
This two-layer proxy setup centralizes SSL certificate management in **Caddy** while preserving flexible and dynamic routing internally with **Traefik**.
#### VPN
For secure remote access, I configured **WireGuard** on OPNsense. This lightweight VPN provides encrypted connectivity to my lab from anywhere, allowing management of all my services without exposing them all directly to the internet.
#### Network Diagram
![Diagram of my home network ](img/homelab-network-schema.png)
### Application
Let's dive into the fun part! What started as a modest setup meant to serve a few personal needs quickly turned into a full ecosystem of open source services, each solving a specific need or just satisfying curiosity.
Here’s an overview of what’s currently running in my homelab:
- **Home Assistant**: Central hub for home automation, integrating smart devices and routines.
- **Vaultwarden**: Lightweight alternative to Bitwarden for managing and syncing passwords securely.
- **Nextcloud**: Self-hosted cloud storage.
- **Gitea**: Git repository solution for managing my code and projects.
- **Blog**: My Hugo-based personal blog, which you are reading now.
- **Immich** – Photo and video management app, similar to Google Photos.
- **Jellyfin**: Media server for streaming movies and shows.
- **ARR Stack**: Automated media acquisition tools. (Radarr, Sonarr, Torrent, etc.)
- **Duplicati**: Encrypted backup solution for my important data and configs.
- **Prometheus**: Monitoring and metrics collection tool, used with Grafana for dashboards.
- **Portainer**: Web interface for managing Docker containers and stacks.
- **Umami**: Privacy-focused analytics for tracking visits on my blog.
- **phpIPAM**: IP address management tool for keeping my VLANs and subnets organized.
#### Docker
Docker was the real game-changer in my self-hosted journey. Before containers, managing multiple services on a single server felt like a constant battle with dependencies and conflicts. Now, every service runs neatly, managed with Docker Compose inside a single VM. Traefik dynamically handles reverse proxy, simplifying access and SSL certificates.
#### Kubernetes
My next big challenge is to take container orchestration to the next level. While Docker Swarm could meet the technical need, my primary goal is to gain hands-on experience with Kubernetes, and there’s no better way to learn than by applying it to real-world use cases.
---
## Final Words
Thank you for taking the time to read through my homelab journey!
Building and refining this setup has been a great source of learning and fun, and I’m always looking for new ways to improve it.
If you’ve got ideas, feedback, better solutions, or just want to share your own setup, I’d love to hear from you. Drop me a message, challenge my choices, or inspire me with your story!
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
title: Recherche title: Recherche
slug: recherche slug: search
layout: search layout: search
outputs: outputs:
- html - html
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

@@ -9,6 +9,7 @@ tags:
- cloud-init - cloud-init
categories: categories:
- homelab - homelab
image: cover-1.webp
--- ---
## Intro ## Intro
@@ -32,7 +33,7 @@ Tout d'abord, nous devons télécharger une image compatible cloud-init. Bien qu
Trouvez des images compatibles cloud dans le [Guide des images OpenStack](https://docs.openstack.org/image-guide/obtain-images.html). Trouvez des images compatibles cloud dans le [Guide des images OpenStack](https://docs.openstack.org/image-guide/obtain-images.html).
Dans Proxmox, accédez à **Storage > ISO Images > Upload** pour uploader l'image téléchargée. Dans Proxmox, accédez à **Storage > ISO Images > Upload** pour uploader l'image téléchargée.
![Download window for ISO images in Proxmox](img/proxmox-download-iso-img.png) ![Fenêtre de téléchargement pour images ISO dans Proxmox](images/proxmox-download-iso-img.png)
## Créer la VM ## Créer la VM
Ensuite, on crée une VM en utilisant la ligne de commande (CLI) depuis le nœud Proxmox avec la commande suivantes : Ensuite, on crée une VM en utilisant la ligne de commande (CLI) depuis le nœud Proxmox avec la commande suivantes :
@@ -9,6 +9,7 @@ tags:
- cloud-init - cloud-init
categories: categories:
- homelab - homelab
image: cover-1.webp
--- ---
## Intro ## Intro
@@ -32,7 +33,7 @@ First, we need to download an image with cloud-init support. Although Rocky Linu
Find cloud-ready images from the [OpenStack Image Guide](https://docs.openstack.org/image-guide/obtain-images.html). Find cloud-ready images from the [OpenStack Image Guide](https://docs.openstack.org/image-guide/obtain-images.html).
In Proxmox, navigate to **Storage > ISO Images > Upload** to upload the downloaded image. In Proxmox, navigate to **Storage > ISO Images > Upload** to upload the downloaded image.
![Download window for ISO images in Proxmox](img/proxmox-download-iso-img.png) ![Download window for ISO images in Proxmox](images/proxmox-download-iso-img.png)
## Create the VM ## Create the VM
Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

@@ -0,0 +1,225 @@
---
slug: opnsense-crash-disk-panic
title: Mon Routeur OPNsense Crash, de la Panique à la Renaissance
description: L'histoire sur comment j’ai survécu à un crash OPNsense à cause d'une disque défaillant et pourquoi un fichier XML a tout changé.
date: 2025-08-24
draft: false
tags:
- opnsense
categories:
- homelab
image: cover-10.webp
---
## Intro
Cette semaine, j’ai vécu mon premier vrai problème dans mon homelab, qui a fait tomber tout mon réseau à la maison.
Mon routeur OPNsense a crash et, après plusieurs tentatives de récupération ratées, j’ai finalement dû le réinstaller from scratch. Heureusement, presque toute la configuration est revenue grâce à un simple fichier XML. Dans cette histoire, je vais raconter ce qui s’est passé, ce que j’ai fait pour m’en sortir, et aussi ce que je n’aurais pas dû faire.
Ce genre d’exercice est la pire chose que vous souhaitez voir arriver, parce que ce n’est jamais amusant de voir tout exploser. Mais c’est de loin la meilleure façon d’apprendre.
## Le Calme Avant la Tempête
Ma box OPNsense tournait parfaitement depuis des mois. Routeur, pare-feu, DNS, DHCP, VLANs, VPN, reverse proxy et même contrôleur UniFi : toutes les pièces de mon homelab passe par elle. Mais pas seulement, elle fournit aussi Internet à la maison.
![Le schéma réseau de mon Homelab](images/homelab-network-schema.png)
Cette box est le cœur de mon réseau, sans elle, je ne peux quasiment rien faire. J’ai détaillé son fonctionnement dans ma section [Homelab]({{< ref "page/homelab" >}}). Tout “fonctionnait juste”, et je ne m’en inquiétait pas. J’étais confiant, sa sauvegarde vivait uniquement à l’intérieur de la machine…
Peut-être trop confiant.
## Le Redémarrage Inattendu
Sans prévenir, la box a redémarré toute seule, juste avant minuit. Par chance, je passais à côté de mon rack en allant me coucher. J’ai su qu’elle avait redémarré car j’ai entendu son petit bip de démarrage.
Je me suis demandé pourquoi le routeur avait redémarré sans mon accord. Dans mon lit, j’ai rapidement vérifié si Internet fonctionnait : oui. Mais aucun de mes services n’était disponible, ni la domotique, ni ce blog. J’étais fatigué, je réglerais ça le lendemain…
Au matin, en regardant les logs, j’ai trouvé le coupable :
```
panic: double fault
```
Un kernel panic. Mon routeur avait littéralement planté au niveau matériel.
## Premières Tentatives de Dépannage
Au début, l’impact semblait mineur. Un seul service ne redémarrait pas : Caddy, mon reverse proxy. Ce qui expliquait pourquoi mes services n’étaient pas accessibles.
En fouillant dans les logs, j’ai trouvé l’erreur :
```
caching certificate: decoding certificate metadata: unexpected end of JSON input
```
Un des certificats mis en cache avait été corrompu pendant le crash. En supprimant son dossier de cache, Caddy est reparti et, d’un coup, tous mes services HTTPS étaient de retour.
Je pensais avoir esquivé la balle. Je n’ai pas cherché plus loin sur la cause réelle : les logs du kernel étaient pollués par une interface qui “flappait”, j’ai cru à un simple bug. À la place, je me suis lancé dans une mise à jour, ma première erreur.
Mon instance OPNsense était en version 25.1, et la 25.7 venait de sortir. Allons-y gaiement !
La mise à jour s’est déroulée correctement, mais quelque chose clochait. En cherchant de nouvelles updates, j’ai vu une corruption dans `pkg`, la base de données du gestionnaire de paquets :
```
pkg: sqlite error while executing iterator in file pkgdb_iterator.c:1110: database disk image is malformed
```
🚨 Mon alarme interne s'est déclenchée. J’ai pensé aux sauvegardes et j’ai immédiatement téléchargé la dernière :
![Sauvegarde de configuration dans OPNsense](images/opnsense-download-backup.png)
En cliquant sur le bouton `Download configuration`, j’ai récupéré le `config.xml` en cours d’utilisation. Je pensais que ça suffirait.
## Corruption du Système de Fichiers
J’ai tenté de réparer la base `pkg` de la pire façon possible : j’ai sauvegardé le dossier `/var/db/pkg` puis essayé de refaire un `bootstrap` :
```bash
cp -a /var/db/pkg /var/db/pkg.bak
pkg bootstrap -f
```
```
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from https://pkg.opnsense.org/FreeBSD:14:amd64/25.7/latest, please wait...
[...]
pkg-static: Fail to extract /usr/local/lib/libpkg.a from package: Write error
Failed to install the following 1 package(s): /tmp//pkg.pkg.scQnQs
[...]
A pre-built version of pkg could not be found for your system.
```
J’ai vu un `Write error`. Je soupçonnais un problème disque. J’ai lancé `fsck` et reçu un flot d’incohérences :
```bash
fsck -n
```
```
[...]
INCORRECT BLOCK COUNT I=13221121 (208384 should be 208192)
INCORRECT BLOCK COUNT I=20112491 (8 should be 0)
INCORRECT BLOCK COUNT I=20352874 (570432 should be 569856)
[...]
FREE BLK COUNT(S) WRONG IN SUPERBLK
[...]
SUMMARY INFORMATION BAD
[...]
BLK(S) MISSING IN BIT MAPS
[...]
***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****
```
Le système de fichiers root était en mauvais état.
N’ayant que SSH et pas de console, j’ai forcé un `fsck` au prochain redémarrage :
```bash
sysrc fsck_y_enable="YES"
sysrc background_fsck="NO"
reboot
```
Au redémarrage, le système a été réparé suffisamment pour relancer `pkg bootstrap`. Mais la moitié des paquets système avaient disparu. Ma mise à jour précédente sur un disque corrompu m’avait laissé avec un système bancal, à moitié installé, à moitié manquant.
## Quand ça empire
J’ai découvert l’utilitaire `opnsense-bootstrap`, censé remettre le système à plat :
- Suppression de tous les paquets installés
- Téléchargement et installation d’un nouveau noyau/base 25.7
- Réinstallation des paquets standards
Parfait !
```
opnsense-bootstrap
```
```
This utility will attempt to turn this installation into the latest OPNsense 25.7 release. All packages will be deleted, the base system and kernel will be replaced, and if all went well the system will automatically reboot. Proceed with this action? [y/N]:
```
J’ai dit `y`. Ça commencé bien, puis… plus rien. Plus de signal. Plus d’Internet. Je croyais que ce bootstrap allait me sauver. En fait, il m’a enterré.
🙈 Oups.
Après un moment, j'ai tenté de le redémarré, mais impossible de me reconnecter en SSH. Pas le choix, j'ai du sortir le routeur du rack, le poser sur mon bureau, brancher écran et clavier et voir ce qui se passait.
## Repartir de zéro
C’était mauvais signe :
```
Fatal error: Uncaught Error: Class "OPNsense\Core\Config" not found
in /usr/local/etc/inc/config.inc:143
```
Et les logs du bootstrap étaient pires :
```
bad dir ino … mangled entry
Input/output error
```
Le disque était pas en forme. Je ne pouvais plus rien sauver. Il était temps de repartir de zéro. Heureusement, j’avais une sauvegarde… non ?
J’ai téléchargé l’ISO OPNsense 25.7, créé une clé USB bootable, et réinstallé par-dessus, en laissant les paramètres par défaut.
## Le sauveur : `config.xml`
OPNsense garde toute sa configuration dans un seul fichier : `/conf/config.xml`. Ce fichier a été ma bouée de sauvetage.
J'ai copié le `config.xml` sauvegardé avant dans ma clé USB. Quand je l'ai connectée sur la machine nouvellement installée, j'ai remplacé le fichier :
```bash
mount -t msdosfs /dev/da0s1 /mnt
cp /mnt/config.xml /conf/config.xml
```
J’ai remis le routeur dans le rack, croisé les doigts… *bip !* 🎉
Le DHCP m’a donné une adresse, bon signe. Je pouvais accéder à l’interface web, super. Ma configuration était là, à peu près tout sauf les plugins, comme prévu. Je ne peux pas les installer immédiatement, car ils nécessitent une autre mise à jour. Mettons à jour !
Ce fichier XML à lui seul m'a permis de reconstruire mon routeur sans perdre la raison.
Sans DNS (AdGuard non installé), j’ai temporairement pointé le DNS pour le système vers `1.1.1.1`.
## Le Dernier Souffle
Lors de la mise à jour suivante, rebelote : erreurs, reboot, crash. La machine de nouveau plus accessible...
Je pouvais officiellement déclarer mon disque NVMe mort.
🪦 Repose en paix, merci pour tes loyaux services.
Par chance, j’avais un NVMe Kingston 512 Go encore neuf, livré avec cette machine. Je ne l'avais jamais utilisé car j'avais préféré réutiliser celui à l'intérieur de mon serveur *Vertex*.
J’ai refait l’installation d'OPNsense dessus, et cette fois tout a fonctionné : passage en 25.7.1 et réinstallation des plugins officiels que j'utilisais.
Pour les plugins custom (AdGuard Home et UniFi), il a fallu ajouter le repo tiers dans `/usr/local/etc/pkg/repos/mimugmail.conf` (documentation [ici](https://www.routerperformance.net/opnsense-repo/))
```json
mimugmail: {
url: "https://opn-repo.routerperformance.net/repo/${ABI}",
priority: 5,
enabled: yes
}
```
Après un dernier reboot, le routeur était presque prêt, mais je n'avais toujours pas de DNS. C'était à cause de AdGuard Home qui n'était pas configuré
⚠️ La configuration des plugins tiers ne sont pas sauvegardés dans `config.xml`.
Reconfigurer AdGuard Home n'était pas bien compliqué, finalement mon DNS fonctionne et t out était revenu à la normale… sauf le contrôleur UniFi.
## Leçons Apprises à la Dure
- **Les sauvegardes comptent** : Je me retrouve toujours à penser que les sauvegardes ne sont pas fondamentales... jusqu'à ce qu'on ait besoin de restaurer et qu'il est trop tard.
- **Gardez-les sauvegardes hors de la machine** : j’ai eu de la chance de récupérer le `config.xml` avant que mon disque me lâche. J'aurais vraiment passer un mauvais moment à tout restaurer entièrement.
- **Vérifier la santé après un crash** : ne pas ignorer un kernel panic.
- **Erreurs I/O = alerte rouge** : j’ai perdu des heures à batailler avec un disque condamné.
- **Les plugins non-officiels ne sont pas sauvegardés** : La configuration d'OPNsense et de ces plugins officiels sont sauvegardés, ce n'est pas le cas pour les autres.
- **Mon routeur est un SPOF** (*Un point de défaillance unique*) : Dans mon homelab, je voulais avoir le maximum d'éléments hautement disponible, il me faut trouver une meilleure solution.
## Aller de l’Avant
Je dois sérieusement repenser ma stratégie de sauvegarde. J’ai toujours repoussé, jusqu’à ce qu’il soit trop tard. Ça faisait longtemps que je n’avais pas subi une panne matérielle. Quand ça arrive, ça pique.
Au départ, je pensais qu’un routeur sur son propre hardware était plus sûr. J’avais tort. Je vais réfléchir à une virtualisation sous Proxmox pour l’avoir en haute dispo. Un beau projet en perspective !
## Conclusion
Mon routeur OPNsense est passé d’un simple redémarrage aléatoire à un disque mort, avec un vrai rollercoaster de dépannage. Au final, je suis presque content que ça soit arrivé : j’ai appris bien plus qu’avec une mise à jour sans accroc.
Si vous utilisez OPNsense (ou n’importe quel routeur), retenez ça :
**Gardez une sauvegarde hors de la machine.**
Parce que quand ça casse, et ça finira par casser, c’est ce petit fichier XML qui peut sauver tout votre homelab.
Restez safe, faites des sauvegardes.
@@ -0,0 +1,226 @@
---
slug: opnsense-crash-disk-panic
title: My OPNsense Router Crash, from Panic to Reborn
description: The story of how I survived an OPNsense crash with a failing disk and why one backup XML made all the difference.
date: 2025-08-24
draft: false
tags:
- opnsense
categories:
- homelab
image: cover-10.webp
---
## Intro
This week, I experienced my first real problem on my homelab, which caused my whole home network to go down.
My OPNsense router crashed and, after several failed recovery attempts, I finally had to reinstall it from scratch. Luckily, almost all of the configuration came back thanks to a single XML file. In that story, I will tell you what happened, what I did to recover and what I shouldn't have done.
This kind of exercise is the worst thing you want to happen because it's never funny to have everything go boom, but this is by far the best way to learn.
## The Calm Before the Storm
My OPNsense box had been running smoothly for months. Router, firewall, DNS, DHCP, VLANs, VPN, reverse proxy and even UniFi controller: all the pieces of my homelab run through it. but not only, it is also serving internet at home.
![My Homelab network diagram](images/homelab-network-schema.png)
This box is the heart of my network, without it, I can hardly do anything. I have detailed how this is working in my [Homelab]({{< ref "page/homelab" >}}) section. It was “just working,” and I wasn’t worried about it. I felt confident, its backup was living only inside the machine...
Maybe too confident.
## The Unexpected Reboot
Out of nowhere, the box rebooted by itself just before midnight. By chance, I was just passing by my rack on my way to bed. I knew it had rebooted because I heard its little startup beep.
I wondered why the router restarted without my will. In my bed, I quickly checked if internet was working, and it was. But none of my services were available, my home automation or even this blog. I was tired, I would fix that the next day...
In the morning, looking at the logs, I found the culprit:
```
panic: double fault
```
A kernel panic. My router had literally crashed at the hardware level.
## First Troubleshooting Attempts
At first, the impact seemed minor. Only one service wasn’t coming back up: Caddy, my reverse proxy. That was making sense if my services weren't available.
Digging into the logs, I found the error:
```
caching certificate: decoding certificate metadata: unexpected end of JSON input
```
It turned out that one of the cached certificates had been corrupted during the crash. Deleting its cache folder fixed Caddy, and suddenly all my HTTPS services were back online.
I thought I had dodged the bullet. I didn't investigate much on the root cause analysis: the kernel logs were polluted by one of the interfaces flapping, I thought it was just a bug. Instead, I went ahead and checked for updates, my first mistake.
My OPNsense instance was in version 25.1, and the newer 25.7 was available. Let's upgrade it, yay!
The upgrade rolled out successfully, but something was wrong. When I tried to look for any update, I saw a corruption in `pkg`, the package manager database:
```
pkg: sqlite error while executing iterator in file pkgdb_iterator.c:1110: database disk image is malformed
```
🚨 My internal alarm sensor triggered, I wondered about backups, I immediately decided to download the latest backup:
![Backup configuration in OPNsense](images/opnsense-download-backup.png)
Clicking the `Download configuration` button, I downloaded the current `config.xml` in use my the instance, I though it was enough.
## Filesystem Corruption
I decided to recover the pkg database the worst possible way, I backed up the `/var/db/pkg` folder and I tried to `bootstrap` it:
```bash
cp -a /var/db/pkg /var/db/pkg.bak
pkg bootstrap -f
```
```
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from https://pkg.opnsense.org/FreeBSD:14:amd64/25.7/latest, please wait...
[...]
pkg-static: Fail to extract /usr/local/lib/libpkg.a from package: Write error
Failed to install the following 1 package(s): /tmp//pkg.pkg.scQnQs
[...]
A pre-built version of pkg could not be found for your system.
```
I saw a `Write error`, I suspect a filesystem problem, I run a check on `fsck`, the output was a flood of inconsistencies:
```bash
fsck -n
```
```
[...]
INCORRECT BLOCK COUNT I=13221121 (208384 should be 208192)
INCORRECT BLOCK COUNT I=20112491 (8 should be 0)
INCORRECT BLOCK COUNT I=20352874 (570432 should be 569856)
[...]
FREE BLK COUNT(S) WRONG IN SUPERBLK
[...]
SUMMARY INFORMATION BAD
[...]
BLK(S) MISSING IN BIT MAPS
[...]
***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****
```
The root filesystem was in bad shape.
Since I only had SSH at this point and no console access, I set up a forced `fsck` for next reboot:
```bash
sysrc fsck_y_enable="YES"
sysrc background_fsck="NO"
reboot
```
On the next boot, the filesystem was repaired enough to let me bootstrap `pkg` again, but most of the system packages were gone. My earlier upgrade while the disk was dirty had left me with a half-installed, half-missing software.
## When Things Got Worse
I discovered the utility `opnsense-bootstrap`, which promises to reinstall all packages and reset the system to a clean release, exactly what I was looking for:
- Remove all installed packages.
- Fresh 25.7 base system and kernel will be downloaded and installed.
- All standard OPNsense packages will be reinstalled.
Wonderful!
```
opnsense-bootstrap
```
```
This utility will attempt to turn this installation into the latest OPNsense 25.7 release. All packages will be deleted, the base system and kernel will be replaced, and if all went well the system will automatically reboot. Proceed with this action? [y/N]:
```
I pressed `y`. This started well, but then... no more signal -> no more internet. I thought this bootstrap would save me. Instead, it buried me.
🙈 Oops.
After a while, I tried to reboot, but impossible to connect back via SSH. No other solution, I had to remove the router from the rack, put it on my desk and plug it a screen and a keyboard to see what is going on.
## Starting Over the Hard Way
This was bad:
```
Fatal error: Uncaught Error: Class "OPNsense\Core\Config" not found
in /usr/local/etc/inc/config.inc:143
```
Checking the bootstrap logs, this was even worse:
```
bad dir ino … mangled entry
Input/output error
```
The disk is in a bad shape, at this point, I couldn’t save the install anymore. Time to start from scratch. Luckily, I had a backup… right?
I downloaded the latest OPNsense ISO (v25.7) and put it into a USB stick. I reinstall OPNsense and overwrite the current installation, I kept everything as default.
## The Lifesaver: `config.xml`
OPNsense keeps the whole configuration in a single file: `/conf/config.xml`. That file was my lifeline.
I copied the `config.xml`file saved earlier into the USB stick. When plugged into the fresh OPNsense box, I overwrite the file:
```bash
mount -t msdosfs /dev/da0s1 /mnt
cp /mnt/config.xml /conf/config.xml
```
I placed the router back in the rack, powered it on and crossed my fingers... *beep!* 🎉
The DHCP gave me an address, good start. I could reach its URL, awesome. My configuration is here, almost everything but the plugins, as expected. I can't install them right away because they need another update, let's update it!
This single XML file is the reason I could rebuild my router without losing my sanity
DNS is KO because the AdGuard Home plugin is not installed, I temporary set the system DNS to `1.1.1.1`
## The Last Breath
During that upgrade, the system threw errors again… and then rebooted itself. Another crash, not turning back on...
I can officially say that my NVMe drive is dead.
🪦 Rest in peace, thank you for your great services.
Luckily, I had a spare 512GB Kingston NVMe that came with that box. I never used it because I preferred to reuse the one inside my *Vertex* server.
I redo the same steps to reinstall OPNsense on that disk and this time everything worked: I could finally update OPNsense to 25.7.1 and reinstall all the official plugins that I was using.
To install custom plugins (AdGuard Home and Unifi), I had to add the custom repository in `/usr/local/etc/pkg/repos/mimugmail.conf` (documentation [here](https://www.routerperformance.net/opnsense-repo/))
```json
mimugmail: {
url: "https://opn-repo.routerperformance.net/repo/${ABI}",
priority: 5,
enabled: yes
}
```
After a final reboot, the router is almost ready, but I still don't have DNS services. This is because AdGuard Home is not configured.
⚠️ Custom plugin configuration is not saved within the backup in `config.xml`.
Reconfigure AdGuard Home is pretty straight forward, finally my DNS is working and everything is back to nominal... except the UniFi controller.
## Lessons Learned the Hard Way
- **Backups matter**: I always found myself thinking backups are not relevant... until you need to restore and it's too late.
- **Keep backups off the box**: I was lucky to get the `config.xml` before my disk die, I would have a really hard time to fully recover.
- **Healthcheck after a crash**: Do not ignore a kernel panic.
- **I/O errors = red flag**: I should have stopped trying to repair. I lost hours fighting a dead disk.
- **Custom plugin configs aren’t include**d: OPNsense configuration and its official plugin are saved into the backups, this is not the case for the others.
- **My router is a SPOF** (*single point of failure*): In my homelab, I wanted to have most of my elements highly available, I need to find a better solution.
## Moving Forward
I really need to think on my backup strategy. I'm too lazy and always keep it for later, until it is too late. It's been a long time since I've been struck by a hardware failure. When it strikes, it hurts.
Initially I wanted my router to be in its own hardware because I thought it was safe, I was damn wrong. I will think on a solution to virtualize OPNsense in Proxmox to have it highly available, a great project in perspective!
## Conclusion
My OPNsense router went from a random reboot to a dead disk, with a rollercoaster of troubleshooting. In the end, I'm almost happy with what happened, it taught me more than any smooth upgrade ever could.
If you run OPNsense (or any router), remember this:
**Keep a backup off the box.**
Because when things go wrong, and eventually they will, that one little XML file can save your homelab.
Stay safe, make backups.
Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,149 @@
---
slug: proxmox-cluster-networking-sdn
title: Simplifier la gestion des VLAN dans Proxmox VE avec le SDN
description: Découvrez comment centraliser la configuration des VLAN dans Proxmox VE grâce aux zones SDN et aux VNets, pour un réseau plus simple et cohérent.
date: 2025-09-12
draft: false
tags:
- proxmox
categories:
- homelab
image: cover-11.webp
---
## Intro
Quand j’ai construit mon cluster **Proxmox VE 8** pour la première fois, le réseau n’était pas ma priorité. Je voulais simplement remplacer rapidement un vieux serveur physique, alors j’ai donné la même configuration de base à chacun de mes trois nœuds, créé le cluster et commencé à créer des VM :
![Configuration réseau d’un nœud Proxmox](images/proxmox-node-network-configuration.png)
Cela a bien fonctionné pendant un moment. Mais comme je prévois de virtualiser mon routeur **OPNsense**, j’ai besoin de quelque chose de plus structuré et cohérent. C’est là que la fonctionnalité **S**oftware-**D**efined **N**etworking (SDN) de Proxmox entre en jeu.
---
## Mon Réseau Homelab
Par défaut, chaque nœud Proxmox dispose de sa propre zone locale, appelée `localnetwork`, qui contient le pont Linux par défaut (`vmbr0`) comme VNet :
![Zones `localnetwork` par défaut dans Proxmox](images/proxmox-default-localnetwork-zone.png)
C’est suffisant pour des configurations isolées, mais rien n’est coordonné au niveau du cluster.
Mon objectif est simple : déclarer les VLAN que j’utilise déjà dans mon réseau, afin de pouvoir y rattacher des VM facilement depuis n’importe quel nœud.
Voici la liste des VLAN que j’utilise actuellement :
| Nom | ID | Usage |
| --------- | ---- | ------------------------------ |
| Mgmt | 1 | Administration |
| User | 13 | Réseau domestique |
| IoT | 37 | IoT et équipements non fiables |
| DMZ | 55 | Services exposés à Internet |
| Lab | 66 | Réseau de lab |
| Heartbeat | 77 | Heartbeat du cluster Proxmox |
| Ceph | 99 | Stockage Ceph |
| VPN | 1337 | Réseau WireGuard |
---
## Aperçu du SDN Proxmox
Le Software-Defined Networking de Proxmox permet de définir des zones et réseaux virtuels à l’échelle du cluster. Au lieu de répéter la configuration des VLAN sur chaque nœud, le SDN offre une vue centralisée et assure la cohérence.
En interne, Proxmox repose essentiellement sur les fonctionnalités réseau standard de Linux, ce qui évite d’ajouter des dépendances externes et garantit la stabilité.
Les configurations SDN sont stockées dans `/etc/pve/sdn` et répliquées sur l’ensemble du cluster. Les changements sont appliqués de manière atomique (on prépare les modifications puis on clique sur `Apply`), ce qui rend les déploiements plus sûrs.
### Zones
Une **Zone** définit un domaine réseau séparé. Les zones peuvent couvrir certains nœuds et contenir des **VNets**.
Proxmox prend en charge plusieurs types de zones :
- **Simple** : pont isolé (bridge) avec routage L3/NAT
- **VLAN** : segmentation classique via VLAN
- **QinQ** : empilement de VLAN (IEEE 802.1ad)
- **VXLAN** : réseau L2 via encapsulation UDP
- **EVPN** : VXLAN avec BGP pour du routage L3 dynamique
Comme mon réseau domestique utilise déjà des VLAN, j’ai créé une **zone VLAN** appelée `homelan`, en utilisant `vmbr0` comme pont et en l’appliquant à tout le cluster :
![Création d’une zone VLAN dans Proxmox SDN](images/proxmox-create-vlan-zone-homelan.png)
### VNets
Un **VNet** est un réseau virtuel à l’intérieur d’une zone. Dans une zone VLAN, chaque VNet correspond à un ID VLAN spécifique.
J’ai commencé par créer `vlan55` dans la zone `homelan` pour mon réseau DMZ :
![Création d’un VNet pour le VLAN 55 dans la zone homelan](images/proxmox-create-vlan-vnet-homelan.png)
Puis j’ai ajouté les VNets correspondant à la plupart de mes VLAN, puisque je prévois de les rattacher à une VM OPNsense :
![Tous mes VLANs créés dans le Proxmox SDN](images/proxmox-sdn-all-vlan-homelan.png)
Enfin, j’ai appliqué la configuration dans **Datacenter → SDN** :
![Application de la configuration SDN dans Proxmox](images/proxmox-apply-sdn-homelan-configuration.png)
---
## Test de la Configuration Réseau
Dans une vieille VM que je n'utilise plus, je remplace l'actuel `vmbr0` avec le VLAN tag 66 par mon nouveau VNet `vlan66`:
![Changement du pont réseau dans une VM](images/proxmox-change-vm-nic-vlan-vnet.png)
Après l'avoir démarrée, la VM obtient une IP du DHCP d'OPNsense sur ce VLAN, ce qui est super. J'essaye également de ping une autre machine et ça fonctionne :
![Ping d’une autre machine dans le même VLAN](images/proxmox-console-ping-vm-vlan-66.png)
---
## Mise à jour de Cloud-Init et Terraform
Pour aller plus loin, j’ai mis à jour le pont réseau utilisé dans mon **template cloud-init**, dont j'avais détaillé la création dans [cet article]({{< ref "post/1-proxmox-cloud-init-vm-template" >}}).
Comme avec la VM précédente, j’ai remplacé `vmbr0` et le tag VLAN 66 par le nouveau VNet `vlan66`.
J’ai aussi adapté mon code **Terraform** pour refléter ce changement :
![Mise à jour du code Terraform pour vlan66](images/terraform-code-update-vlan66.png)
Ensuite, j’ai validé qu’aucune régression n’était introduite en déployant une VM de test :
```bash
terraform apply -var 'vm_name=vm-test-vnet'
```
```plaintext
data.proxmox_virtual_environment_vms.template: Reading...
data.proxmox_virtual_environment_vms.template: Read complete after 0s [id=23b17aea-d9f7-4f28-847f-41bb013262ea]
[...]
Plan: 2 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ vm_ip = (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
proxmox_virtual_environment_file.cloud_config: Creating...
proxmox_virtual_environment_file.cloud_config: Creation complete after 1s [id=local:snippets/vm.cloud-config.yaml]
proxmox_virtual_environment_vm.vm: Creating...
proxmox_virtual_environment_vm.vm: Still creating... [10s elapsed]
[...]
proxmox_virtual_environment_vm.vm: Still creating... [3m0s elapsed]
proxmox_virtual_environment_vm.vm: Creation complete after 3m9s [id=119]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
vm_ip = "192.168.66.181"
```
La création s’est déroulée sans problème, tout est bon :
![VM déployée par Terraform sur vlan66](images/proxmox-terraform-test-deploy-vlan66.png)
---
## Conclusion
La mise en place du SDN Proxmox avec une **zone VLAN** est simple et très pratique. Au lieu de définir manuellement un VLAN sur chaque VM, je sélectionne désormais directement le bon VNet, et tout reste cohérent dans le cluster.
| Étape | Avant SDN | Après SDN |
| -------------------- | ----------------------------- | ----------------------------------- |
| Rattacher une VM | `vmbr0` + tag VLAN manuel | Sélection du VNet approprié |
| VLANs sur les nœuds | Config répété sur chaque nœud | Centralisé via le SDN du cluster |
| Gestion des adresses | Manuel ou via DHCP uniquement | IPAM optionnel via sous-réseaux SDN |
Mon cluster est maintenant prêt à héberger mon **routeur OPNsense**, et cette base ouvre la voie à d’autres expérimentations, comme les overlays VXLAN ou l’EVPN avec BGP.
À suivre pour la prochaine étape !
@@ -0,0 +1,149 @@
---
slug: proxmox-cluster-networking-sdn
title: Simplifying VLAN Management in Proxmox VE with SDN
description: Learn how to centralize VLAN configuration in Proxmox VE using SDN zones and VNets, making VM networking easier and more consistent.
date: 2025-09-12
draft: false
tags:
- proxmox
categories:
- homelab
image: cover-11.webp
---
## Intro
When I first built my **Proxmox VE 8** cluster, networking wasn’t my main concern. I just wanted to replace an old physical server quickly, so I gave each of my three nodes the same basic config, created the cluster, and started running VMs:
![Proxmox node network configuration](images/proxmox-node-network-configuration.png)
That worked fine for a while. But as I plan to virtualize my **OPNsense** router, I need something more structured and consistent. This is where Proxmox **S**oftware-**D**efined **N**etworking (SDN) feature comes in.
---
## My Homelab Network
By default, every Proxmox node comes with its own local zone, called `localnetwork`, which contains the default Linux bridge (`vmbr0`) as a VNet:
![Proxmox default `localnetwork` zones](images/proxmox-default-localnetwork-zone.png)
That’s fine for isolated setups, but at the cluster level nothing is coordinated.
What I want is simple: declare the VLANs I already use in my network, so I can attach VMs to them easily from any node.
Here’s the list of VLANs I use today:
| Name | ID | Purpose |
| --------- | ---- | ---------------------------- |
| Mgmt | 1 | Management |
| User | 13 | Home network |
| IoT | 37 | IoT and untrusted equipments |
| DMZ | 55 | Internet facing |
| Lab | 66 | Lab network |
| Heartbeat | 77 | Proxmox cluster heartbeat |
| Ceph | 99 | Ceph storage |
| VPN | 1337 | Wireguard network |
---
## Proxmox SDN Overview
Proxmox Software-Defined Networking makes it possible to define cluster-wide virtual zones and networks. Instead of repeating VLAN configs on every node, SDN gives you a central view and ensures consistency.
Under the hood, Proxmox mostly uses standard Linux networking, avoiding extra dependencies and keeping things stable.
SDN configurations are stored in `/etc/pve/sdn`, which is replicated across the cluster. Changes are applied atomically (you prepare them, then hit `Apply` once), making rollouts safer.
### Zones
A **Zone** defines a separate networking domain. Zones can span specific nodes and contain **VNets**.
Proxmox supports several zone types:
- **Simple**: Isolated Bridge. A simple layer 3 routing bridge (NAT)
- **VLAN**: Virtual LANs are the classic method of subdividing a LAN
- **QinQ**: Stacked VLAN (IEEE 802.1ad)
- **VXLAN**: Layer 2 VXLAN network via a UDP tunnel
- **EVPN**: VXLAN with BGP to establish Layer 3 routing
Since my home network already relies on VLANs, I created a **VLAN Zone** named `homelan`, using `vmbr0` as the bridge and applying it cluster-wide:
![Create a VLAN zone in the Proxmox SDN](images/proxmox-create-vlan-zone-homelan.png)
### VNets
A **VNet** is a virtual network inside a zone. In a VLAN zone, each VNet corresponds to a specific VLAN ID.
I started by creating `vlan55` in the `homelan` zone for my DMZ network:
![Create a VNet for VLAN 55 in the homelan zone](images/proxmox-create-vlan-vnet-homelan.png)
Then I added VNets for most of my VLANs, since I plan to attach them to an OPNsense VM:
![All my VLANs created in the Proxmox SDN](images/proxmox-sdn-all-vlan-homelan.png)
Finally, I applied the configuration in **Datacenter → SDN**:
![Apply SDN configuration in Proxmox](images/proxmox-apply-sdn-homelan-configuration.png)
---
## Test the Network Configuration
In a old VM which I don't use anymore, I replace the current `vmbr0` with VLAN tag 66 to my new VNet `vlan66`:
![Change the network bridge in a VM](images/proxmox-change-vm-nic-vlan-vnet.png)
After starting it, the VM gets an IP from the DHCP on OPNsense on that VLAN, which sounds good. I also try to ping another machine and it works:
![Ping another machine in the same VLAN](images/proxmox-console-ping-vm-vlan-66.png)
---
## Update Cloud-Init Template and Terraform
To go further, I update the bridge used in my **cloud-init** template, which I detailed the creation in that [post]({{< ref "post/1-proxmox-cloud-init-vm-template" >}}). Pretty much the same thing I've done with the VM, I replace the current `vmbr0` with VLAN tag 66 with my new VNet `vlan66`.
I also update the **Terrafom** code to take this change into account:
![Terraform code change for the vlan66](images/terraform-code-update-vlan66.png)
I quicky check if I don't have regression and can still deploy a VM with Terraform:
```bash
terraform apply -var 'vm_name=vm-test-vnet'
```
```plaintext
data.proxmox_virtual_environment_vms.template: Reading...
data.proxmox_virtual_environment_vms.template: Read complete after 0s [id=23b17aea-d9f7-4f28-847f-41bb013262ea]
[...]
Plan: 2 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ vm_ip = (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
proxmox_virtual_environment_file.cloud_config: Creating...
proxmox_virtual_environment_file.cloud_config: Creation complete after 1s [id=local:snippets/vm.cloud-config.yaml]
proxmox_virtual_environment_vm.vm: Creating...
proxmox_virtual_environment_vm.vm: Still creating... [10s elapsed]
[...]
proxmox_virtual_environment_vm.vm: Still creating... [3m0s elapsed]
proxmox_virtual_environment_vm.vm: Creation complete after 3m9s [id=119]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
vm_ip = "192.168.66.181"
```
The VM is deploying without any issue, everything is OK:
![VM hardware in Proxmox deployed by Terraform](images/proxmox-terraform-test-deploy-vlan66.png)
---
## Conclusion
Setting up Proxmox SDN with a **VLAN zone** turned out to be straightforward and very useful. Instead of tagging VLANs manually per VM, I now just pick the right VNet, and everything stays consistent across the cluster.
| Step | Before SDN | After SDN |
| ----------------- | ------------------------------- | ------------------------------ |
| Attach VM to VLAN | `vmbr0` + set VLAN tag manually | Select the right VNet directly |
| VLANs on nodes | Repeated config per node | Centralized in cluster SDN |
| IP management | Manual or DHCP only | Optional IPAM via SDN subnets |
This prepares my cluster to host my **OPNsense router**, and it also sets the stage for future experiments, like trying out VXLAN overlays or EVPN with BGP.
See you next time for the next step!
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

@@ -0,0 +1,282 @@
---
slug: opnsense-virtualization-highly-available
title: Construire un Cluster OPNsense Hautement Disponible sur Proxmox VE
description: Une preuve de concept montrant comment virtualiser OPNsense sur Proxmox VE, configurer la haute disponibilité avec CARP et pfSync, et gérer une seule IP WAN.
date: 2025-09-29
draft: false
tags:
- opnsense
- proxmox
- high-availability
categories:
- homelab
image: cover-12.webp
---
## Intro
J’ai récemment rencontré mon premier vrai problème, ma box **OPNsense** physique a planté à cause d’un _kernel panic_. J’ai détaillé ce qu'il s'est passé dans [cet article]({{< ref "post/10-opnsense-crash-disk-panic" >}}).
Cette panne m’a fait repenser mon installation. Un seul pare-feu est un point de défaillance unique, donc pour améliorer la résilience j’ai décidé de prendre une nouvelle approche : **virtualiser OPNsense**.
Évidemment, faire tourner une seule VM ne suffirait pas. Pour obtenir une vraie redondance, il me faut deux instances OPNsense en **Haute Disponibilité**, l’une active et l’autre en attente.
Avant de déployer ça sur mon réseau, j’ai voulu valider l’idée dans mon homelab. Dans cet article, je vais détailler la preuve de concept : déployer deux VM OPNsense dans un cluster **Proxmox VE** et les configurer pour fournir un pare-feu hautement disponible.
---
## Infrastructure Actuelle
Au sommet de mon installation, mon modem FAI, une _Freebox_ en mode bridge, relié directement à l’interface `igc0` de ma box OPNsense, servant d’interface **WAN**. Sur `igc1`, le **LAN** est connecté à mon switch principal via un port trunk, avec le VLAN 1 comme VLAN natif pour mon réseau de management.
Ce switch relie également mes trois nœuds Proxmox, chacun sur un port trunk avec le même VLAN natif. Chaque nœud dispose de deux cartes réseau : une pour le trafic général, et l’autre dédiée au réseau de stockage Ceph, connecté à un switch séparé de 2,5 Gbps.
Depuis le crash d’OPNsense, j’ai simplifié l’architecture en supprimant le lien LACP, qui n’apportait pas de réelle valeur :
![Schéma réseau du homelab actuel](images/homelan-current-physical-layout.png)
Jusqu’à récemment, le réseau Proxmox de mon cluster était très basique : chaque nœud était configuré individuellement sans véritable logique commune. Cela a changé après la découverte du SDN Proxmox, qui m’a permis de centraliser les définitions de VLAN sur l’ensemble du cluster. J’ai décrit cette étape dans [cet article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}).
---
## Preuve de Concept
Place au lab. Voici les étapes principales :
1. Ajouter quelques VLANs dans mon homelab
2. Créer un faux routeur FAI
3. Construire deux VMs OPNsense
4. Configurer la haute disponibilité
5. Tester la bascule
![Schéma du POC pour OPNsense en haute disponibilité](images/poc-opnsense-diagram.png)
### Ajouter des VLANs dans mon homelab
Pour cette expérimentation, je crée trois nouveaux VLANs :
- **VLAN 101** : _POC WAN_
- **VLAN 102** : _POC LAN_
- **VLAN 103** : _POC pfSync_
Dans l’interface Proxmox, je vais dans `Datacenter` > `SDN` > `VNets` et je clique sur `Create` :
![Création des VLANs POC dans le SDN Proxmox](images/proxmox-sdn-create-poc-vlans.png)
Une fois les trois VLANs créés, j’applique la configuration.
J’ajoute ensuite ces trois VLANs dans mon contrôleur UniFi. Ici, seul l’ID et le nom sont nécessaires, le contrôleur se charge de les propager via les trunks connectés à mes nœuds Proxmox VE.
### Créer une VM “Fausse Box FAI”
Pour simuler mon modem FAI actuel, j’ai créé une VM appelée `fake-freebox`. Cette VM route le trafic entre les réseaux _POC WAN_ et _Lab_, et fait tourner un serveur DHCP qui ne délivre qu’un seul bail, exactement comme ma vraie Freebox en mode bridge.
Cette VM dispose de 2 cartes réseau, que je configure avec Netplan :
- `eth0` (_POC WAN_ VLAN 101) : adresse IP statique `10.101.0.254/24`
- `enp6s19` (Lab VLAN 66) : adresse IP obtenue en DHCP depuis mon routeur OPNsense actuel, en amont
```yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 10.101.0.254/24
enp6s19:
dhcp4: true
```
J’active ensuite le routage IP pour permettre à cette VM de router le trafic :
```bash
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```
Puis je configure du masquage (NAT) afin que les paquets sortant via le réseau Lab ne soient pas rejetés par mon OPNsense actuel :
```bash
sudo iptables -t nat -A POSTROUTING -o enp6s19 -j MASQUERADE
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
```
J’installe `dnsmasq` comme serveur DHCP léger :
```bash
sudo apt install dnsmasq -y
```
Dans `/etc/dnsmasq.conf`, je configure un bail unique (`10.101.0.150`) et je pointe le DNS vers mon OPNsense actuel, sur le VLAN _Lab_ :
```
interface=eth0
bind-interfaces
dhcp-range=10.101.0.150,10.101.0.150,255.255.255.0,12h
dhcp-option=3,10.101.0.254 # default gateway = this VM
dhcp-option=6,192.168.66.1 # DNS server
```
Je redémarre le service `dnsmasq` pour appliquer la configuration :
```bash
sudo systemctl restart dnsmasq
```
La VM `fake-freebox` est maintenant prête à fournir du DHCP sur le VLAN 101, avec un seul bail disponible.
### Construire les VMs OPNsense
Je commence par télécharger l’ISO d’OPNsense et je l’upload sur un de mes nœuds Proxmox :
![Upload de l’ISO OPNsense dans Proxmox](images/proxmox-upload-opnsense-iso.png)
#### Création de la VM
Je crée la première VM `poc-opnsense-1` avec les paramètres suivants :
- Type d’OS : Linux (même si OPNsense est basé sur FreeBSD)
- Type de machine : `q35`
- BIOS : `OVMF (UEFI)`, stockage EFI sur mon pool Ceph
- Disque : 20 Go sur Ceph
- CPU/RAM : 2 vCPU, 2 Go de RAM
- Cartes réseau :
1. VLAN 101 (_POC WAN_)
2. VLAN 102 (_POC LAN_)
3. VLAN 103 (_POC pfSync_)
![Paramètres de la VM OPNsense dans Proxmox](images/proxmox-create-poc-vm-opnsense.png)
ℹ️ Avant de la démarrer, je clone cette VM pour préparer la seconde : `poc-opnsense-2`
Au premier démarrage, je tombe sur une erreur “access denied”. Pour corriger, j’entre dans le BIOS, **Device Manager > Secure Boot Configuration**, je décoche _Attempt Secure Boot_ et je redémarre :
![Désactiver Secure Boot dans le BIOS de Proxmox](images/proxmox-disable-secure-boot-option.png)
#### Installation d’OPNsense
La VM démarre sur l’ISO, je ne touche à rien jusqu’à l’écran de login :
![Écran de login OPNsense en mode LiveCD](images/opnsense-vm-installation-welcome.png)
Je me connecte avec `installer` / `opnsense` et je lance l’installateur. Je sélectionne le disque QEMU de 20 Go comme destination et je démarre l’installation :
![Barre de progression de l’installation OPNsense](images/opnsense-vm-installation-progress-bar.png)
Une fois terminé, je retire l’ISO du lecteur et je redémarre la machine.
#### Configuration de Base d’OPNsense
Au redémarrage, je me connecte avec `root` / `opnsense` et j’arrive au menu CLI :
![Menu CLI après une installation fraîche d’OPNsense](images/opnsense-vm-installation-cli-menu.png)
Avec l’option 1, je réassigne les interfaces :
![Configuration des interfaces dans OPNsense via le CLI](images/opnsense-vm-installation-assign-interfaces.png)
L’interface WAN récupère bien `10.101.0.150/24` depuis la `fake-freebox`. Je configure le LAN sur `10.102.0.2/24` et j’ajoute un pool DHCP de `10.102.0.10` à `10.102.0.99` :
![Interface WAN OPNsense recevant une IP depuis la VM `fake-freebox`](images/opnsense-vm-installation-interfaces-configured.png)
✅ La première VM est prête, je reproduis l’opération pour la seconde OPNsense `poc-opnsense-2`, qui aura l’IP `10.102.0.3`.
### Configurer OPNsense en Haute Disponibilité
Avec les deux VMs OPNsense opérationnelles, il est temps de passer à la configuration via le WebGUI. Pour y accéder, j’ai connecté une VM Windows au VLAN _POC LAN_ et ouvert l’IP de l’OPNsense sur le port 443 :
![OPNsense WebGUI depuis une VM Windows](images/opnsense-vm-webgui-from-poc-lan.png)
#### Ajouter l’Interface pfSync
La troisième carte réseau (`vtnet2`) est assignée à l’interface _pfSync_. Ce réseau dédié permet aux deux firewalls de synchroniser leurs états via le VLAN _POC pfSync_ :
![Ajouter l’interface pfSync dans OPNsense](images/opnsense-vm-assign-pfsync-interface.png)
J’active l’interface sur chaque instance et je leur attribue une IP statique :
- **poc-opnsense-1** : `10.103.0.2/24`
- **poc-opnsense-2** : `10.103.0.3/24`
Puis, j’ajoute une règle firewall sur chaque nœud pour autoriser tout le trafic provenant de ce réseau sur l’interface _pfSync_ :
![Règle firewall pour autoriser tout le trafic pfSync](images/opnsense-vm-firewall-allow-pfsync.png)
#### Configurer la Haute Disponibilité
Direction `System` > `High Availability` > `Settings`.
- Sur le master (`poc-opnsense-1`), je configure les `General Settings` et les `Synchronization Settings`.
- Sur le backup (`poc-opnsense-2`), seuls les `General Settings` suffisent (on ne veut pas qu’il écrase la config du master).
![Paramètres de Haute Disponibilité dans OPNsense](images/opnsense-vm-high-availability-settings.png)
Une fois appliqué, je vérifie la synchro dans l’onglet `Status` :
![Statut de la Haute Disponibilité OPNsense](images/opnsense-vm-high-availability-status.png)
#### Créer une IP Virtuelle
Pour fournir une passerelle partagée aux clients, je crée une IP virtuelle (VIP) en **CARP** (Common Address Redundancy Protocol) sur l’interface LAN. L’IP est portée par le nœud actif et bascule automatiquement en cas de failover.
Menu : `Interfaces` > `Virtual IPs` > `Settings` :
![Création d’une VIP CARP dans OPNsense](images/opnsense-vm-create-vip-carp.png)
Je réplique ensuite la config depuis `System > High Availability > Status` avec le bouton `Synchronize and reconfigure all`.
Sur `Interfaces > Virtual IPs > Status`, le master affiche la VIP en `MASTER` et le backup en `BACKUP`.
#### Reconfigurer le DHCP
Pour la HA, il faut adapter le DHCP. Comme **Dnsmasq** ne supporte pas la synchro des baux, chaque instance doit répondre indépendamment.
Sur le master :
- `Services` > `Dnsmasq DNS & DHCP` > `General` : cocher `Disable HA sync`
- `DHCP ranges` : cocher aussi `Disable HA sync`
- `DHCP options` : ajouter l’option `router [3]` avec la valeur `10.102.0.1` (VIP LAN)
- `DHCP options` : cloner la règle pour `dns-server [6]` vers la même VIP.
![Options DHCP dans Dnsmasq](images/opnsense-vm-dnsmasq-add-option.png)
Sur le backup :
- `Services` > `Dnsmasq DNS & DHCP` > `General` : cocher `Disable HA sync`
- Régler `DHCP reply delay` à `5` secondes (laisser la priorité au master)
- `DHCP ranges` : définir un autre pool, plus petit (`10.102.0.200 -> 220`).
Ainsi, seules les **options** DHCP sont synchronisées, les plages restant distinctes.
#### Interface WAN
Mon modem FAI n’attribue qu’une seule IP en DHCP, je ne veux pas que mes 2 VMs entrent en compétition. Pour gérer ça :
1. Dans Proxmox, je copie l’adresse MAC de `net0` (WAN) de `poc-opnsense-1` et je l’applique à `poc-opnsense-2`. Ainsi, le bail DHCP est partagé.
⚠️ Si les deux VMs activent la même MAC en même temps, cela provoque des conflits ARP et peut casser le réseau. Seul le MASTER doit activer son WAN.
2. Un hook event CARP procure la possibilité de lancer des scripts. J’ai déployé ce [script Gist](https://gist.github.com/spali/2da4f23e488219504b2ada12ac59a7dc#file-10-wancarp) dans `/usr/local/etc/rc.syshook.d/carp/10-wan` sur les deux nœuds. Ce script active le WAN uniquement sur le MASTER.
```php
#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
if ($type != 'MASTER' && $type != 'BACKUP') {
log_error("Carp '$type' event unknown from source '{$subsystem}'");
exit(1);
}
if (!strstr($subsystem, '@')) {
log_error("Carp '$type' event triggered from wrong source '{$subsystem}'");
exit(1);
}
$ifkey = 'wan';
if ($type === "MASTER") {
log_error("enable interface '$ifkey' due CARP event '$type'");
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_error("disable interface '$ifkey' due CARP event '$type'");
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
}
```
### Tester le Failover
Passons aux tests !
OPNsense propose un _CARP Maintenance Mode_. Avec le master actif, seul lui avait son WAN monté. En activant le mode maintenance, les rôles basculent : le master devient backup, son WAN est désactivé et celui du backup est activé :
![Mode maintenance CARP dans OPNsense](images/opnsense-vm-carp-status.png)
Pendant mes pings vers l’extérieur, aucune perte de paquets au moment du basculement.
Ensuite, j’ai simulé un crash en éteignant le master. Le backup a pris le relais de façon transparente, seulement un paquet perdu, et grâce à la synchro des états, même ma session SSH est restée ouverte. 🎉
## Conclusion
Cette preuve de concept démontre qu’il est possible de faire tourner **OPNsense en haute dispo sous Proxmox VE**, même avec une seule IP WAN. Les briques nécessaires :
- Segmentation VLAN
- Réseau dédié pfSync
- IP virtuelle partagée (CARP)
- Script pour gérer l’interface WAN
Le résultat est à la hauteur : failover transparent, synchro des états, et connexions actives qui survivent à un crash. Le point le plus délicat reste la gestion du bail WAN, mais le hook CARP règle ce problème.
🚀 Prochaine étape : préparer un nouveau cluster OPNsense HA sur Proxmox en vue de remplacer complètement ma box physique actuel. Restez à l'écoute !
@@ -0,0 +1,284 @@
---
slug: opnsense-virtualization-highly-available
title: Build a Highly Available OPNsense Cluster on Proxmox VE
description: A proof of concept showing how to virtualize OPNsense on Proxmox VE, configure high availability with CARP and pfSync and handle a single WAN IP.
date: 2025-09-29
draft: false
tags:
- opnsense
- proxmox
- high-availability
categories:
- homelab
image: cover-12.webp
---
## Intro
I recently encountered my first real problem, my physical **OPNsense** box crashed because of a kernel panic, I've detailed what happened in that [post]({{< ref "post/10-opnsense-crash-disk-panic" >}}).
That failure made me rethink my setup. A unique firewall is a single point of failure, so to improve resilience I decided to take a new approach: **virtualize OPNsense**.
Of course, just running one VM wouldn’t be enough. To get real redundancy, I need two OPNsense instances in **High Availability**, with one active and the other standing by.
Before rolling this out in my network, I wanted to demonstrate the idea in my homelab. In this post, I’ll walk through the proof of concept: deploying two OPNsense VMs inside a **Proxmox VE** cluster and configuring them to provide a highly available firewall.
---
## Current Infrastructure
On top of my setup, my ISP modem, a *Freebox* in bridge mode, connects directly to the `igc0` interface of my OPNsense box, serving as the **WAN**. On `igc1`, the **LAN** is linked to my main switch using a trunk port, with VLAN 1 as the native VLAN for my management network.
The switch also connects my three Proxmox nodes, each on trunk ports with the same native VLAN. Every node has two NICs: one for general networking and the other dedicated to the Ceph storage network, which runs through a separate 2.5 Gbps switch.
Since the OPNsense crash, I’ve simplified things by removing the LACP link, it wasn’t adding real value:
![Current homelab network diagram](images/homelan-current-physical-layout.png)
Until recently, Proxmox networking on my cluster was very basic: each node was configured individually with no real overlay logic. That changed after I explored Proxmox SDN, where I centralized VLAN definitions across the cluster. I described that step in [this article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}).
---
## Proof of Concept
Time to move into the lab. Here are the main steps:
1. Add some VLANs in my Homelab
2. Create Fake ISP router
3. Build two OPNsense VMs
4. Configure high availability
5. Test failover
![Diagram of the POC for OPNsense high availability](images/poc-opnsense-diagram.png)
### Add VLANs in my Homelab
For this experiment, I create 3 new VLANs:
- **VLAN 101**: *POC WAN*
- **VLAN 102**: *POC LAN*
- **VLAN 103**: *POC pfSync*
In the Proxmox UI, I navigate to `Datacenter` > `SDN` > `VNets` and I click `Create`:
![Create POC VLANs in the Proxmox SDN](images/proxmox-sdn-create-poc-vlans.png)
Once the 3 new VLAN have been created, I apply the configuration.
Additionally, I add these 3 VLANs in my UniFi Controller. Here only the VLAN ID and name are needed, since the controller will propagate them through the trunks connected to my Proxmox VE nodes.
### Create “Fake ISP Box“ VM
To simulate my current ISP modem, I built a VM named `fake-freebox`. This VM routes traffic between the *POC WAN* and *Lab* networks and runs a DHCP server that serves only one lease, just like my real Freebox in bridge mode.
This VM has 2 NICs, I configure Netplan with:
- `eth0` (*POC WAN* VLAN 101): static IP address `10.101.0.254/24`
- enp6s19 (Lab VLAN 66): DHCP address given by my current OPNsense router, in upstream
```yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 10.101.0.254/24
enp6s19:
dhcp4: true
```
I enable packet forward to allow this VM to route traffic:
```bash
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```
Then I set up masquerading so packets leaving through the lab network wouldn’t be dropped by my current OPNsense:
```bash
sudo iptables -t nat -A POSTROUTING -o enp6s19 -j MASQUERADE
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
```
I install `dnsmasq` as a lightweight DHCP server:
```bash
sudo apt install dnsmasq -y
```
In `/etc/dnsmasq.conf`, I configure to serve exactly one lease (`10.101.0.150`) with DNS pointing to my current OPNsense router, in the *Lab* VLAN:
```
interface=eth0
bind-interfaces
dhcp-range=10.101.0.150,10.101.0.150,255.255.255.0,12h
dhcp-option=3,10.101.0.254 # default gateway = this VM
dhcp-option=6,192.168.66.1 # DNS server
```
I restart the `dnsmasq` service to apply the configuration:
```bash
sudo systemctl restart dnsmasq
```
The `fake-freebox` VM is now ready to serve DHCP on VLAN 101 and serve only one lease.
### Build OPNsense VMs
First I download the OPNsense ISO and upload it to one of my Proxmox nodes:
![Upload the OPNsense ISO into Proxmox](images/proxmox-upload-opnsense-iso.png)
#### VM Creation
I create the first VM `poc-opnsense-1`, with the following settings:
- OS type: Linux (even though OPNsense is FreeBSD-based)
- Machine type: `q35`
- BIOS: `OVMF (UEFI)`, EFI storage on my Ceph pool
- Disk: 20 GiB also on Ceph
- CPU/RAM: 2 vCPU, 2 GiB RAM
- NICs:
1. VLAN 101 (POC WAN)
2. VLAN 102 (POC LAN)
3. VLAN 103 (POC pfSync)
![OPNsense VM settings in Proxmox](images/proxmox-create-poc-vm-opnsense.png)
ℹ️ Before booting it, I clone this VM to prepare the second one: `poc-opnsense-2`
On first boot, I hit an “access denied” error. To fix this, I enter the BIOS, go to **Device Manager > Secure Boot Configuration**, uncheck _Attempt Secure Boot_, and restart the VM:
![Disable Secure Boot in Proxmox BIOS](images/proxmox-disable-secure-boot-option.png)
#### OPNsense Installation
The VM boots on the ISO, I touch nothing until I get into the login screen:
![OPNsense CLI login screen in LiveCD](images/opnsense-vm-installation-welcome.png)
I log in as `installer` / `opnsense` and launch the installer. I select the QEMU hard disk of 20GB as destination and launch the installation:
![OPNsense installation progress bar](images/opnsense-vm-installation-progress-bar.png)
Once the installation is finished, I remove the ISO from the drive and restart the machine.
#### OPNsense Basic Configuration
After reboot, I log in as `root` / `opnsense` and get into the CLI menu:
![OPNsense CLI login screen after fresh installation](images/opnsense-vm-installation-cli-menu.png)
Using option 1, I reassigned interfaces:
![OPNsense interface configuration using CLI](images/opnsense-vm-installation-assign-interfaces.png)
The WAN interface successfully pulled `10.101.0.150/24` from the `fake-freebox`. I set the LAN interface to `10.102.0.2/24` and configured a DHCP pool from `10.102.0.10` to `10.102.0.99`:
![OPNsense WAN interface getting IP from `fake-freebox` VM](images/opnsense-vm-installation-interfaces-configured.png)
✅ The first VM is ready, I start over for the second OPNsense VM, `poc-opnsense-2` which will have the IP `10.102.0.3`
### Configure OPNsense Highly Available
With both OPNsense VMs operational, it’s time to configure them from the WebGUI. To access the interface, I connected a Windows VM into the _POC LAN_ VLAN and browsed to the OPNsense IP on port 443:
![OPNsense WebGUI from Windows VM](images/opnsense-vm-webgui-from-poc-lan.png)
#### Add pfSync Interface
The third NIC (`vtnet2`) is assigned to the _pfSync_ interface. This dedicated network allows the two firewalls to synchronize states on the VLAN *POC pfSync*:
![Add pfSync interface in OPNsense](images/opnsense-vm-assign-pfsync-interface.png)
I enable the interface on each instance and configure it with a static IP address:
- **poc-opnsense-1**: `10.103.0.2/24`
- **poc-opnsense-2**: `10.103.0.3/24`
Then, I add a firewall rule on each node to allow all traffic coming from this network on that *pfSync* interface:
![Create new firewall rule on pfSync interface to allow any traffic in that network](images/opnsense-vm-firewall-allow-pfsync.png)
#### Setup High Availability
Next, in `System` > `High Availability` > `Settings`.
- On the master (`poc-opnsense-1`), I configure both the `General Settings` and the `Synchronization Settings`.
- On the backup (`poc-opnsense-2`), only `General Settings` are needed, you don't want your backup overwrite the master config.
![OPNsense High Availability settings](images/opnsense-vm-high-availability-settings.png)
Once applied, I verify synchronization on the `Status` page:
![OPNsense High Availability status](images/opnsense-vm-high-availability-status.png)
#### Create Virtual IP Address
To provide a shared gateway for clients, I create a CARP Virtual IP (VIP) on the LAN interface. It is using the Common Address Redundancy Protocol. This IP is claimed by the active node and automatically fails over.
Navigate to `Interfaces` > `Virtual IPs` > `Settings`:
![Create CARP virtual IP in OPNsense](images/opnsense-vm-create-vip-carp.png)
To replicate the config, I go to `System > High Availability > Status` and click the button next to `Synchronize and reconfigure all`.
On the `Interfaces > Virtual IPs > Status` page, the master show the VIP as `MASTER`, while the backup report `BACKUP`.
#### Reconfigure DHCP
For HA, I need to adjust the DHCP setup. Since **Dnsmasq** does not support lease synchronization, both instances must serve leases independently.
On the master:
- `Services` > `Dnsmasq DNS & DHCP` > `General`: tick the `Disable HA sync` box.
- `DHCP ranges`: also tick the `Disable HA sync` box
- `DHCP options`: add the option `router [3]` with the value `10.102.0.1` (LAN VIP)
- `DHCP options`: clone the rule for `router [6]` pointing to the same VIP.
![Edit DHCP options for Dnsmasq in OPNsense](images/opnsense-vm-dnsmasq-add-option.png)
On the backup:
- `Services` > `Dnsmasq DNS & DHCP` > `General`: also tick the `Disable HA sync` box
- Set `DHCP reply delay` to `5` seconds, to give master priority to answer.
- `DHCP ranges`: Use a different pool, smaller (`10.102.0.200` -> `220`)
- but I also set the value `5` to `DHCP reply delay`. This would give enough time to the master node to provide a DHCP lease before the backup node. In `DHCP ranges`, I edit the current one and give a smaller pool, different than the master's. Here I also tick the `Disable HA sync` box.
This way, only DHCP options sync between nodes, while lease ranges stay separate.
#### WAN Interface
My ISP modem only provides a single DHCP lease, I don't want my 2 VMs compete to claim it. To handle this:
1. In Proxmox, I copy the MAC of the `net0` (WAN) interface from `poc-opnsense-1` and applied it to `poc-opnsense-2`. This way, the DHCP lease could be shared among the nodes.
⚠️ If both VMs bring up the same MAC, it can cause ARP conflicts and break connectivity, only the MASTER should keep its WAN active.
2. CARP event hook provides the possibility to run scripts, I deployed this [Gist script](https://gist.github.com/spali/2da4f23e488219504b2ada12ac59a7dc#file-10-wancarp) in `/usr/local/etc/rc.syshook.d/carp/10-wan` on both nodes. This ensures the WAN is active only on the MASTER, avoiding conflicts.
```php
#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
if ($type != 'MASTER' && $type != 'BACKUP') {
log_error("Carp '$type' event unknown from source '{$subsystem}'");
exit(1);
}
if (!strstr($subsystem, '@')) {
log_error("Carp '$type' event triggered from wrong source '{$subsystem}'");
exit(1);
}
$ifkey = 'wan';
if ($type === "MASTER") {
log_error("enable interface '$ifkey' due CARP event '$type'");
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_error("disable interface '$ifkey' due CARP event '$type'");
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
}
```
### Test Failover
Time for the real test!
OPNsense provides a _CARP Maintenance Mode_. With the master active, WAN was enabled only on that node. Entering maintenance mode flipped the roles: the master became backup, its WAN disabled, while the backup enabled its WAN:
![OPNsense CARP maintenance mode](images/opnsense-vm-carp-status.png)
While pinging outside the network, I observed zero packet loss during the failover.
Finally, I simulated a crash by powering off the master. The backup took over seamlessly, I saw only one dropped packet, and thanks to state synchronization, even my SSH session stayed alive. 🎉
## Conclusion
This proof of concept showed that running **OPNsense in high availability on Proxmox VE** is possible, even with a single WAN IP address. To achieve this, I needed these components:
- VLAN segmentation.
- Dedicated pfSync network.
- Shared virtual IP.
- Script to manage the WAN interface.
The setup behave exactly as expected, seamless failover, synchronized firewall states, and even live sessions surviving a node crash. The most delicate part was handling the WAN lease, since my ISP modem only provides one IP, but the CARP hook script solved that challenge.
🚀 The next milestone will be to prepare a new OPNsense HA cluster with the aim to completely replace my current physical box. Stay tuned!
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

@@ -0,0 +1,589 @@
---
slug: opnsense-ha-full-configuration
title: OPNsense HA dans Proxmox, ma Configuration Homelab Complète
description: "Configuration complète d'un cluster OPNsense HA dans Proxmox : interfaces et VIP, pare‑feu, DHCP Dnsmasq, DNS Unbound, VPN WireGuard et reverse proxy Caddy."
date: 2025-10-23
draft: false
tags:
- opnsense
- high-availability
- proxmox
- unbound-dns
- caddy
- wireguard
- dnsmasq
categories:
- homelab
image: cover-13.webp
---
## Intro
Dans mon précédent [article]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) j'ai mis en place un PoC pour valider la construction d'un cluster de deux VM **OPNsense** dans **Proxmox VE** afin de rendre le pare‑feu hautement disponible.
Maintenant je prépare la mise en œuvre dans mon homelab, cet article documente ma configuration réelle du cluster OPNsense, depuis de nouvelles installations jusqu'à la HA, le DNS, le DHCP, le VPN et le reverse proxy.
### Contexte
Avant d'entrer dans la configuration d'OPNsense, un peu de contexte pour comprendre les choix que j'ai faits.
Dans mon cluster Proxmox VE, j'ai créé 2 VM et installé OPNsense. L'objectif est de remplacer ma unique machine physique par ce cluster. Chaque VM possède 7 NICs pour les réseaux suivants :
- **vmbr0** : _Mgmt_
- **vlan20** : _WAN_
- **vlan13** : _User_
- **vlan37** : _IoT_
- **vlan44** : _pfSync_
- **vlan55** : _DMZ_
- **vlan66** : _Lab_
Initialement je pensais simplement restaurer ma configuration actuelle sur la VM fraîchement installée. Mais j'ai réalisé que je n'avais pas vraiment documenté comment j'avais assemblé les éléments la première fois. C'est le moment parfait pour remettre les choses en ordre.
⚠️ Je ne peux disposer que d'une seule IP WAN, partagée entre les nœuds, fournie par le DHCP de ma box opérateur. Pour cette raison je n'aurai pas de VIP pour le WAN et je dois trouver une solution pour partager cette unique IP.
J'espère que, dans le prochain article, si ce projet arrive sur mon réseau de production, je couvrirais aussi la création des VM dans Proxmox et la façon dont je prépare la migration de ma box OPNsense physique vers ce cluster HA en VM. Allons‑y !
---
## Système
### Général
Je commence par les bases, dans `System` > `Settings` > `General` :
- **Hostname** : `cerbere-head1` (`cerbere-head2` pour la seconde).
- **Domain** : `mgmt.vezpi.com`.
- **Time zone** : `Europe/Paris`.
- **Language** : `English`.
- **Theme** : `opnsense-dark`.
- **Prefer IPv4 over IPv6** : cocher la case pour préférer IPv4.
### Utilisateurs
Ensuite, dans `System` > `Access` > `Users`, je crée un nouvel utilisateur plutôt que d'utiliser `root`, l'ajoute au groupe `admins`, et retire `root` de ce groupe.
### Administration
Dans `System` > `Settings` > `Administration`, je modifie plusieurs éléments :
- **Web GUI**
- **TCP port** : de `443` à `4443`, pour libérer le port 443 pour le reverse proxy à venir.
- **HTTP Redirect** : Désactivé, pour libérer le port 80 pour le reverse proxy.
- **Alternate Hostnames** : `cerbere.vezpi.com` qui sera l'URL pour atteindre le pare‑feu via le reverse proxy.
- **Access log** : Activé.
- **Secure Shell**
- **Secure Shell Server** : Activé.
- **Root Login** : Désactivé.
- **Authentication Method :** Autoriser la connexion par mot de passe (pas de login `root`).
- **Listen Interfaces** : _Mgmt_
- **Authentication**
- **Sudo** : `No password`.
Une fois que je clique sur `Save`, je suis le lien fourni pour atteindre la WebGUI sur le port `4443`.
### Mises à Jour
Il est temps de mettre à jour, dans `System` > `Firmware` > `Status`, je vérifie les mises à jour du firmware et les applique (nécessite un redémarrage).
### QEMU Guest Agent
Une fois mis à jour et redémarré, je vais dans `System` > `Firmware` > `Plugins`, je coche l'option pour afficher les plugins communautaires. J'installe que le **QEMU Guest Agent**, `os-qemu-guest-agent`, pour permettre la communication entre la VM et l'hôte Proxmox.
Cela nécessite un arrêt. Dans Proxmox, j'active le `QEMU Guest Agent` dans les options de la VM :
![Options d'une VM Proxmox avec QEMU Guest Agent activé](images/proxmox-opnsense-enable-qemu-guest-agent.png)
Finalement je redémarre la VM. Une fois démarrée, depuis la WebGUI de Proxmox, je peux voir les IPs de la VM ce qui confirme que le guest agent fonctionne.
---
## Interfaces
Sur les deux pare‑feu, j'assigne les NIC restantes à de nouvelles interfaces en ajoutant une description. Les VMs ont 7 interfaces, je compare attentivement les adresses MAC pour éviter de mélanger les interfaces :
![Assignement des interfaces dans OPNsense](images/opnsense-assign-interfaces.png)
Au final, la configuration des interfaces ressemble à ceci :
| Interface | Mode | `cerbere-head1` | `cerbere-head2` |
| --------- | ----------- | --------------- | --------------- |
| *Mgmt* | Static IPv4 | 192.168.88.2/24 | 192.168.88.3/24 |
| *WAN* | DHCPv4/6 | Enabled | Disabled |
| *User* | Static IPv4 | 192.168.13.2/24 | 192.168.13.3/24 |
| *IoT* | Static IPv4 | 192.168.37.2/24 | 192.168.37.3/24 |
| *pfSync* | Static IPv4 | 192.168.44.1/30 | 192.168.44.2/30 |
| *DMZ* | Static IPv4 | 192.168.55.2/24 | 192.168.55.3/24 |
| *Lab* | Static IPv4 | 192.168.66.2/24 | 192.168.66.3/24 |
Je ne configure pas encore les Virtual IPs, je m'en occuperai une fois la haute disponibilité mise en place.
---
## Haute Disponibilité
### Règle Pare-feu pour pfSync
À partir d'ici nous pouvons associer les deux instances pour créer un cluster. La dernière chose que je dois faire est d'autoriser la communication sur l'interface _pfSync_. Par défaut, aucune communication n'est autorisée sur les nouvelles interfaces.
Dans `Firewall` > `Rules` > `pfSync`, je crée une nouvelle règle sur chaque pare‑feu :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | *pfSync* |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | any |
| **Source** | *pfSync* net |
| **Destination** | *pfSync* net |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | OPNsense |
| **Description** | pfSync |
### Configurer la HA
OPNsense HA utilise pfSync pour la synchronisation des états du pare‑feu (en temps réel) et XMLRPC Sync pour pousser la configuration et les services du master → backup (sens unique).
La HA est configurée dans `System` > `High Availability` > `Settings`
#### Master
- **General Settings**
- **Synchronize all states via**: _pfSync_
- **Synchronize Peer IP**: `192.168.44.2`, l'IP du nœud backup
- **Configuration Synchronization Settings (XMLRPC Sync)**
- **Synchronize Config**: `192.168.44.2`
- **Remote System Username**: `<username>`
- **Remote System Password**: `<password>`
- **Services to synchronize (XMLRPC Sync)**
- **Services**: Select All
#### Backup
- **General Settings**
- **Synchronize all states via**: _pfSync_
- **Synchronize Peer IP**: `192.168.44.1`, l'IP du nœud master
⚠️ Ne remplissez pas les champs XMLRPC Sync sur le nœud backup, ils doivent uniquement être remplis sur le master.
### Statut de la HA
Dans `System` > `High Availability` > `Status`, je peux vérifier si la synchronisation fonctionne. Sur cette page je peux répliquer un ou tous les services du master vers le nœud backup :
![Page de statut de la haute disponibilité dans OPNsense](images/opnsense-high-availability-status.png)
---
## IPs Virtuelles
Maintenant que la HA est configurée, je peux attribuer à mes réseaux une IP virtuelle partagée entre mes nœuds. Dans `Interfaces` > `Virtual IPs` > `Settings`, je crée un VIP pour chacun de mes réseaux en utilisant **CARP** (Common Address Redundancy Protocol). L'objectif est de réutiliser les adresses IP utilisées par mon instance OPNsense actuelle, mais comme elle route encore mon réseau, j'utilise des IP différentes pour la phase de configuration :
![Liste des IPs virtuelles dans OPNsense](images/opnsense-interface-virtual-ips.png)
ℹ️ OPNsense permet CARP par défaut, aucune règle de pare‑feu spéciale requise
---
## Script de Bascule CARP
Dans ma configuration, je n'ai qu'une seule adresse WAN fournie par le DHCP de ma box opérateur. OPNsense ne propose pas nativement de moyen de gérer ce scénario. Pour s'en occuper, j'implémente la même astuce que j'ai utilisée dans le [PoC]({{< ref "post/12-opnsense-virtualization-highly-available" >}}).
### Copier l'Adresse MAC
Je copie la MAC de l'interface `net1` de `cerbere-head1` et la colle sur la même interface de `cerbere-head2`. Ainsi, le bail DHCP pour l'adresse WAN peut être partagé entre les nœuds.
⚠️ Attention : Avoir deux machines sur le réseau avec la même MAC peut provoquer des conflits ARP et casser la connectivité. Une seule VM doit garder son interface active.
### Script d'Evènement CARP
Sous le capot, dans OPNsense, un événement CARP déclenche certains scripts (lorsque le master meurt). Ils sont situés dans `/usr/local/etc/rc.syshook.d/carp/`.
Pour gérer l'interface WAN sur chaque nœud, j'implémente ce script PHP `10-wan` sur les deux nœuds, via SSH (n'oubliez pas de le rendre exécutable). Selon leur rôle (master ou backup), il activera ou désactivera leur interface WAN :
```php
#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
if ($type != 'MASTER' && $type != 'BACKUP') {
log_error("Carp '$type' event unknown from source '{$subsystem}'");
exit(1);
}
if (!strstr($subsystem, '@')) {
log_error("Carp '$type' event triggered from wrong source '{$subsystem}'");
exit(1);
}
$ifkey = 'wan';
if ($type === "MASTER") {
log_error("enable interface '$ifkey' due CARP event '$type'");
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_error("disable interface '$ifkey' due CARP event '$type'");
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
}
```
Dans `Interfaces` > `Virtual IPs` > `Status`, je peux forcer un événement CARP en entrant en `Persistent maintenance mode`. Le déclenchement permet de tester ce script, qui désactive l'interface WAN sur le master tout en l'activant sur le backup.
---
## Pare-feu
Configurons la fonctionnalité principale d'OPNsense, le pare‑feu. Je ne veux pas multiplier les règles inutilement. Je n'ai besoin de configurer que le master, grâce à la réplication.
### Groupes d'Interface
Globalement j'ai 2 types de réseaux : ceux en qui j'ai confiance et ceux en qui je n'ai pas confiance. Dans cette optique, je vais créer deux zones.
En règle générale, mes réseaux non fiables n'ont accès qu'au DNS et à Internet. Les réseaux fiables peuvent atteindre les autres VLANs.
Pour commencer, dans `Firewall` > `Groups`, je crée 2 zones pour regrouper mes interfaces :
- **Trusted** : _Mgmt_, _User_
- **Untrusted** : _IoT_, _DMZ_, _Lab_
### Network Aliases
Ensuite, dans `Firewall` > `Aliases`, je crée un alias `InternalNetworks` pour regrouper tous mes réseaux internes :
![Création d'alias pour les réseaux locaux dansOPNsense](images/opnsense-create-alias-internalnetworks.png)
### Règles de Pare-feu Rules
Pour tous mes réseaux, je veux autoriser les requêtes DNS vers le DNS local. Dans `Firewall` > `Rules` > `Floating`, créons la première règle
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted, Untrusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP/UDP |
| **Source** | InternalNetworks |
| **Destination** | This Firewall |
| **Destination port range** | from: DNS - to: DNS |
| **Log** | Log packets |
| **Category** | DNS |
| **Description** | DNS query |
Ensuite je veux autoriser les connexions vers Internet. Au même endroit je crée une seconde règle :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted, Untrusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4+IPv6 |
| **Protocol** | any |
| **Source** | InternalNetworks |
| **Destination / Invert** | Invert the sense of the match |
| **Destination** | InternalNetworks |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | Internet |
| **Description** | Internet |
Enfin, je veux autoriser tout depuis mes réseaux fiables. Dans `Firewall` > `Rules` > `Trusted`, je crée la règle :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4+IPv6 |
| **Protocol** | any |
| **Source** | Trusted net |
| **Destination** | any |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | Trusted |
| **Description** | Trusted |
Parfait, avec ces 3 règles, je couvre les bases. Les règles restantes serviront à autoriser certains équipements à atteindre d'autres services. Par exemple, mon instance Home Assistant veut se connecter à ma TV, les deux sont sur des VLANs différents, donc j'ai besoin d'une règle pour l'autoriser :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Lab |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP |
| **Source** | 192.168.66.50/32 |
| **Destination** | 192.168.37.30/32 |
| **Destination port range** | from: 3000 - to: 3001 |
| **Log** | Log packets |
| **Category** | Home Assistant |
| **Description** | Home assistant to TV |
---
## DHCP
Pour le DHCP, je choisis **Dnsmasq**. Dans mon installation actuelle j'utilise ISC DHCPv4, mais comme il est maintenant déprécié, je préfère le remplacer. Dnsmasq agira aussi comme DNS, mais seulement pour mes zones locales.
Dnsmasq ne synchronise pas les baux. Pour éviter les conflits, les deux nœuds servent le DHCP mais avec un délai de réponse décalé et des plages différentes. Le master couvre le pool principal, le backup un petit pool de secours.
### Configuration Générale de Dnsmasq
Dans `Services` > `Dnsmasq DNS & DHCP` > `General`, je configure le pare‑feu master comme suit :
- **Default**
- **Enable**: Oui
- **Interface**: *Mgmt*, *User*, *IoT*, *DMZ* et *Lab*
- **DNS**
- **Listen port**: 53053
- **DNS Query Forwarding**
- **Do not forward to system defined DNS servers**: Activé
- **DHCP**
- **DHCP FQDN**: Activé
- **DHCP local domain**: Activé
- **DHCP authoritative**: Activé
- **DHCP reply delay**: 0
- **DHCP register firewall rules**: Activé
- **Disable HA sync**: Activé
Sur le nœud backup, je le configure de la même manière, la seule différence sera le **DHCP reply delay** que je règle à **10**. Cela donne au master le temps de répondre aux requêtes DHCP avant que le backup n'intervienne.
### Plages DHCP
Ensuite je configure les plages DHCP. Les deux pare‑feu auront des plages différentes, le nœud backup aura des plages plus petites (10 baux devraient suffire). Sur le master, elles sont configurées comme suit :
![Plages DHCP de Dnsmasq dans OPNsense](images/opnsense-dnsmasq-dhcp-ranges.png)
### Options DHCP
Puis je définis quelques options DHCP pour chaque domaine : le `router`, le `dns-server` et le `domain-name`. Je pointe les adresses IP vers la VIP de l'interface :
![Options DHCP de Dnsmasq dans OPNsense](images/opnsense-dnsmasq-dhcp-options.png)
### Hôtes
Enfin, dans l'onglet `Hosts`, je définis des mappings DHCP statiques mais aussi des IP statiques non gérées par le DHCP, pour qu'elles soient enregistrées dans le DNS :
![Hôtes DHCP de Dnsmasq dans OPNsense](images/opnsense-dnsmasq-dhcp-hosts.png)
---
## DNS
Pour le DNS, j'utilise **Unbound**. C'est un résolveur DNS récursif, validant et cacheur intégré à OPNsense, qui peut :
- Résoudre les requêtes depuis les serveurs racine.
- Mettre en cache les résultats pour des réponses plus rapides.
- Vérifier l'authenticité des domaines avec DNSSEC.
- Bloquer des domaines via une liste noire.
- Ajouter des enregistrements personnalisés.
Unbound est le résolveur récursif, pour les zones locales j'effectue un forward vers Dnsmasq.
### Paramètres Généraux d'Unbound
Configurons-le, dans `Services` > `Unbound DNS` > `General` :
![Paramètres généraux d'Unbound DNS dans OPNsense](images/opnsense-unbound-general-settings.png)
### Liste de Blocage DNS
Ensuite je configure la blocklist dans `Services` > `Unbound DNS` > `Blocklist`. Je l'active et sélectionne la liste `[hagezi] Multi PRO mini`. Initialement j'utilisais AdGuard Home, mais je veux donner une chance à cette fonctionnalité de blocklist.
Pour maintenir le service à jour, dans `System` > `Settings` > `Cron`, j'ajoute mon premier job qui s'exécute chaque nuit à 2h pour `Update Unbound DNSBLs`.
### Transfert de Requêtes
Enfin je configure le transfert de requêtes pour mes domaines locaux vers Dnsmasq. Dans `Services` > `Unbound DNS` > `Query Forwarding`, j'ajoute chacun de mes domaines locaux avec leurs reverse lookups (enregistrements PTR) :
![Configuration du transfert de requêtes d'Unbound DNS dans OPNsense](images/opnsense-unbound-dns-query-forwarding.png)
---
## VPN
Quand je ne suis pas chez moi, je veux toujours pouvoir atteindre mes services et profiter de mon bloqueur DNS. Pour cela je configure un VPN avec **WireGuard**. C'est rapide, sécurisé et simple à mettre en place.
### Configuration de l'Instance WireGuard
Dans `VPN` > `WireGuard` > `Instances`, je crée une nouvelle instance :
- **Enabled**: Oui
- **Name**: *Homelan*
- **Public/Private keys**: Paire de clés générée
- **Listen port**: `61337`
- **Tunnel address**: `10.13.37.1/24`
- **Depend on (CARP)**: on *lan* (vhid 1)
Une fois configuré, j'active WireGuard et j'applique la configuration.
### Configuration d'un Peer
Ensuite, dans l'onglet `Peer generator`, je remplis les champs pour mon premier appareil :
- **Endpoint** : `vezpi.com`
- **Name** : _S25Ultra_
- **DNS Servers** : `10.13.37.1`
Avant de cliquer sur `Store and generate next`, depuis mon appareil je configure le peer en capturant le QR code. Enfin je peux sauvegarder ce peer et recommencer pour les suivants.
### Créer l'Interface VPN
Cette étape n'est pas obligatoire, mais facilite la gestion des règles de pare‑feu. Sur les deux pare‑feu, dans `Interfaces` > `Assignments`, j'assigne l'interface `wg0 (WireGuard - Homelan)` et la nomme _VPN_.
Puis dans `Interfaces` > `VPN`, j'active cette interface.
Enfin, dans `Firewall` > `Groups`, j'ajoute cette interface au groupe _Trusted_.
### Règle de Pare-feu
Pour autoriser les connexions depuis l'extérieur, je dois créer une règle de pare‑feu sur l'interface WAN :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | WAN |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | UDP |
| **Source** | any |
| **Destination** | WAN address |
| **Destination port range** | from: 61337 - to: 61337 |
| **Log** | Log packets |
| **Category** | VPN |
| **Description** | WireGuard |
---
## Reverse Proxy
La fonctionnalité suivante dont j’ai besoin est un **reverse proxy**, pour rediriger les requêtes HTTPS entrantes vers mes services, comme ce blog par exemple.
Pour cela, j’utilise **Caddy**. Il écoute sur les ports 80 et 443, c’est la raison pour laquelle j’ai déplacé l’interface WebGUI d’OPNsense vers d’autres ports au début.
Ce service n’est pas installé par défaut, il faut ajouter un plugin.
Sur les deux pare-feux, dans `System` > `Firmware` > `Plugins`, je coche l’option pour afficher les plugins communautaires et j’installe **`os-caddy`**.
### Paramètres Généraux de Caddy
Je rafraîchis ensuite la page et, sur le nœud maître, je vais dans `Services` > `Caddy` > `General Settings` :
- **Enable Caddy** : Oui
- **Enable Layer4 Proxy** : Oui
- **ACME** : `<adresse email>`
- **Auto HTTPS** : On (default)
Il existe deux types de redirections : le `Reverse Proxy` et le `Layer4 Proxy`. Le premier est réservé au HTTPS, où Caddy gère le chiffrement SSL lui-même.
### Reverse Proxy
Dans `Services` > `Caddy` > `Reverse Proxy`, je définis les services directement gérés par Caddy.
Ces services ne doivent pas être accessibles à tout le monde.
Dans l’onglet **Access**, je crée une liste appelée `Internal`, qui regroupe mes réseaux autorisés, notamment le LAN et le VPN.
Puis, dans l’onglet `Domains`, j’ajoute mes domaines. Par exemple, c’est ici que je définis `cerbere.vezpi.com`, l’URL pour accéder à mon interface WebGUI OPNsense :
- **Enable** : Oui
- **Frontend**
- **Protocol** : `https://`
- **Domain** : `cerbere.vezpi.com`
- **Port** : laisser vide
- **Certificate** : Auto HTTPS
- **HTTP-01 Challenge Redirection** : `192.168.44.2` (pour la haute disponibilité)
- **Description** : OPNsense
- **Access**
- **Access List** : `Internal`
- **HTTP Access Log** : Activé
Enfin, dans l’onglet `Handlers`, je définis la destination vers laquelle ces domaines doivent être redirigés. Pour `cerbere.vezpi.com`,
j’ajoute :
- **Enabled** : Oui
- **Frontend**
- **Domain** : `https://cerbere.vezpi.com`
- **Subdomain** : None
- **Handler**
- **Path** : any
- **Access**
- **Access List** : None
- **Directive**
- **Directive** : `reverse_proxy`
- **Upstream**
- **Protocol** : `https://`
- **Upstream Domain** : `127.0.0.1`
- **Upstream Port** : `4443`
- **TLS Insecure Skip Verify** : Activé
- **Description** : OPNsense
### Layer4 Proxy
La plupart de mes services sont déjà derrière un autre reverse proxy sur mon réseau, **Traefik**. Pour lui permettre de gérer directement ses domaines, je les redirige à l’aide de `Layer4 Routes`. Cela évite que Caddy termine le SSL, le flux HTTPS reste donc intact.
Dans `Services` > `Caddy` > `Layer4 Proxy`, je crée 3 routes.
La première concerne les services exposés sur Internet, comme ce blog ou mon instance Gitea :
- **Enabled** : Oui
- **Sequence** : 1
- **Layer 4**
- **Routing Type** : listener_wrappers
- **Layer 7**
- **Matchers** : TLS (SNI Client Hello)
- **Domain** : `blog.vezpi.com` `git.vezpi.com`
- **Terminate SSL** : No
- **Upstream**
- **Upstream Domain** : `192.168.66.50`
- **Upstream Port** : `443`
- **Proxy Protocol** : `v2` (si supporté par l’upstream)
- **Description** : External Traefik HTTPS dockerVM
La deuxième route est dédiée aux services internes uniquement. Elle est configurée de manière similaire, mais avec une liste de contrôle d’accès :
- **Sequence** : 2
- **Access**
- **Remote IP** : `192.168.13.0/24` `192.168.88.0/24` `10.13.37.0/24`
La troisième route gère les challenge HTTP de Traefik pour Let's Encrypt :
- **Sequence** : 3
- **Layer 7**
- **Matchers** : HTTP (Host Header)
- **Domain** : `blog.vezpi.com` `git.vezpi.com` etc.
- **Upstream**
- **Upstream Port** : 80
- **Proxy Protocol** : Off (default)
### Règles du pare-feu
Enfin, je dois autoriser les connexions sur ces ports sur le pare-feu.
Je crée donc une règle pour le HTTPS (et une autre pour le HTTP) :
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | WAN |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP |
| **Source** | any |
| **Destination** | WAN address |
| **Destination port range** | from: HTTPS - to: HTTPS |
| **Log** | Log packets |
| **Category** | Caddy |
| **Description** | Caddy HTTPS |
---
## Répéteur mDNS
Le dernier service que je souhaite configurer dans OPNsense est un répéteur mDNS. Il est utile pour certains appareils qui annoncent leur présence sur le réseau, lorsqu’ils ne sont pas sur le même VLAN, comme mon imprimante ou mon Chromecast. Le répéteur mDNS reçoit les annonces d’une interface et les transmet sur une autre.
Ce service n’est pas installé par défaut. Sur les deux pare-feux, dans `System` > `Firmware` > `Plugins`, je coche l’option pour afficher les plugins communautaires et j’installe **`os-mdns-repeater`**.
Ensuite, dans `Services` > `mDNS Repeater`, la configuration est très simple :
- **Enable** : Oui
- **Enable CARP Failover** : Oui
- **Listen Interfaces** : _IoT_, _User_
---
## Synchronisation des services
La dernière étape consiste à synchroniser tous les services entre le maître et le nœud de secours du cluster. D’abord, dans `System` > `High Availability` > `Status`, je clique sur le bouton **Synchronize and reconfigure all**.
Puis, je veux m’assurer que les futurs changements soient synchronisés même si j’oublie de les répliquer. Dans `System` > `Settings` > `Cron`, j’ajoute une tâche planifiée chaque nuit pour **HA update and reconfigure backup**.
---
## Conclusion
🚀 Mon cluster **OPNsense** est désormais configuré et prêt à être mis en production !
J’espère que cette configuration complète d’OPNsense pour mon propre réseau t’aidera à construire la tienne.
La prochaine étape sera de planifier la migration depuis mon ancienne box OPNsense vers ces deux pare-feu en haute disponibilité.
Cette nouvelle infrastructure renforcera la sécurité de mes opérations tout en éliminant le SPOF (Single Point Of Failure) de mon réseau.
À très vite pour te raconter comment cette opération s’est déroulée !
@@ -0,0 +1,580 @@
---
slug: opnsense-ha-full-configuration
title: OPNsense HA in Proxmox, my Full Homelab Configuration
description: Step-by-step OPNsense HA cluster full configuration in Proxmox, interfaces and VIP, firewall, Dnsmasq DHCP, Unbound DNS, WireGuard VPN and Caddy reverse proxy.
date: 2025-10-23
draft: false
tags:
- opnsense
- high-availability
- proxmox
- unbound-dns
- caddy
- wireguard
- dnsmasq
categories:
- homelab
image: cover-13.webp
---
## Intro
In my previous [article]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) I set up a PoC to validate building a cluster of two **OPNsense** VMs in **Proxmox VE** to make the firewall highly available.
Now I'm preparing to make that real in my homelab, this post documents my real OPNsense cluster configuration, from fresh installs to HA, DNS, DHCP, VPN and reverse proxy.
### Context
Before diving into the OPNsense configuration, a little bit of context to understand the choices I made.
In my Proxmox VE cluster, I've created 2 VMs and installed OPNsense. The goal is to replace my single physical box by this cluster. Each VM have 7 NICs for the following networks:
- **vmbr0**: *Mgmt*
- **vlan20**: *WAN*
- **vlan13**: *User*
- **vlan37**: *IoT*
- **vlan44**: *pfSync*
- **vlan55**: *DMZ*
- **vlan66**: *Lab*
Initially I was thinking of just restoring my current configuration on the VM freshly installed. But then I realized that I didn't really documented how I put the pieces together the first time. This is the perfect moment to put things right.
⚠️ I can only have a single WAN IP, shared between the nodes, served by the DHCP of my ISP box. For this reason I won't have a VIP for the WAN and I have to find a solution to share this single IP.
Hopefully in the next post, if this project lands on my production network, I will also cover the VM creation on Proxmox and how I'm preparing this migration from my physical OPNsense box to this highly available cluster in VMs. Let's dive in!
---
## System
### General
I start with the basics, in `System` > `Settings` > `General`:
- **Hostname**: `cerbere-head1` (`cerbere-head2` for the second one).
- **Domain**: `mgmt.vezpi.com`.
- **Time zone**: `Europe/Paris`.
- **Language**: `English`.
- **Theme**: `opnsense-dark`.
- **Prefer IPv4 over IPv6**: tick the box to prefer IPv4.
### Users
Then, in `System` > `Access` > `Users`, I create a new user rather than using `root`, add it to the `admins` group, and remove `root` from that group.
### Administration
In `System` > `Settings` > `Administration`, I change several things:
- **Web GUI**
- **TCP port**: from `443` to `4443`, to free port 443 for the reverse proxy coming next.
- **HTTP Redirect**: Disabled, to free port 80 for the reverse proxy
- **Alternate Hostnames**: `cerbere.vezpi.com` which will be the URL to reach the firewall by the reverse proxy.
- **Access log**: Enabled.
- **Secure Shell**
- **Secure Shell Server**: Enabled.
- **Root Login**: Disabled.
- **Authentication Method:** Permit password login (no `root` login).
- **Listen Interfaces**: *Mgmt*
- **Authentication**
- **Sudo**: `No password`.
Once I click `Save`, I follow the link given to reach the WebGUI on port `4443`.
### Updates
Time for updates, in `System` > `Firmware` > `Status`, I check for firmware updates and apply them (requires reboot).
### QEMU Guest Agent
Once updated and rebooted, I go to `System` > `Firmware` > `Plugins`, I tick the box to show community plugins. I install the **QEMU Guest Agent**, `os-qemu-guest-agent`, to allow communication between the VM and the Proxmox host.
This requires a shutdown. On Proxmox, I enable the `QEMU Guest Agent` in the VM options:
Proxmox VM options with QEMU Guest Agent enabled
Finally I restart the VM. Once started, from the Proxmox WebGUI, I can see the IPs of the VM which confirms the guest agent is working.
---
## Interfaces
On both firewalls, I assign the remaining NICs to new interfaces adding a description. The VMs have 7 interfaces, I carefully compare MAC addresses to avoid mixing interfaces:
![Assign interfaces menu in OPNsense](images/opnsense-assign-interfaces.png)
In the end, the interfaces configuration looks like this:
| Interface | Mode | `cerbere-head1` | `cerbere-head2` |
| --------- | ----------- | --------------- | --------------- |
| *Mgmt* | Static IPv4 | 192.168.88.2/24 | 192.168.88.3/24 |
| *WAN* | DHCPv4/6 | Enabled | Disabled |
| *User* | Static IPv4 | 192.168.13.2/24 | 192.168.13.3/24 |
| *IoT* | Static IPv4 | 192.168.37.2/24 | 192.168.37.3/24 |
| *pfSync* | Static IPv4 | 192.168.44.1/30 | 192.168.44.2/30 |
| *DMZ* | Static IPv4 | 192.168.55.2/24 | 192.168.55.3/24 |
| *Lab* | Static IPv4 | 192.168.66.2/24 | 192.168.66.3/24 |
I don't configure Virtual IPs yet, I'll manage that once high availability has been setup.
---
## High Availability
### Firewall Rule for pfSync
From here we can associate both instances to create a cluster. The last thing I need to do, is to allow the communication on the *pfSync* interface. By default, no communication is allowed on the new interfaces.
From `Firewall` > `Rules` > `pfSync`, I create a new rule on each firewall:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | *pfSync* |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | any |
| **Source** | *pfSync* net |
| **Destination** | *pfSync* net |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | OPNsense |
| **Description** | pfSync |
### Configure HA
OPNsense HA uses pfSync for firewall state synchronization (real-time) and XMLRPC Sync to push config and services from master → backup (one-way).
The HA is setup in `System` > `High Availability` > `Settings`
#### Master
- **General Settings**
- **Synchronize all states via**: *pfSync*
- **Synchronize Peer IP**: `192.168.44.2`, the backup node IP
- **Configuration Synchronization Settings (XMLRPC Sync)**
- **Synchronize Config**: `192.168.44.2`
- **Remote System Username**: `<username>`
- **Remote System Password**: `<password>`
- **Services to synchronize (XMLRPC Sync)**
- **Services**: Select All
#### Backup (`cerbere-head2`):
- **General Settings**
- **Synchronize all states via**: *pfSync*
- **Synchronize Peer IP**: `192.168.44.1`, the master node IP
⚠️ Do not fill the XMLRPC Sync fields on the backup node, only to be filled on the master.
### HA Status
In the section `System` > `High Availability` > `Status`, I can verify if the synchronization is working. On this page I can replicate any or all services from my master to my backup node:
![OPNsense high availability status page](images/opnsense-high-availability-status.png)
---
## Virtual IPs
Now that HA is configured, I can give my networks a virtual IP shared across my nodes. In `Interfaces` > `Virtual IPs` > `Settings`, I create one VIP for each of my networks using **CARP** (Common Address Redundancy Protocol). The target is to reuse the IP addresses used by my current OPNsense instance, but as it is still routing my network, I use different IPs for the configuration phase:
![OPNsense virtual IPs list](images/opnsense-interface-virtual-ips.png)
ℹ️ OPNsense allows CARP by default, no special firewall rule required
---
## CARP Failover Script
In my setup, I only have a single WAN IP address which is served by the DHCP of my ISP box. OPNsense does not provide natively a way to handle this scenario. To manage it, I implement the same trick I used in the [PoC]({{< ref "post/12-opnsense-virtualization-highly-available" >}}).
### Copy MAC Address
I copy the MAC of the `net1` interface of `cerbere-head1` and paste it to the same interface for `cerbere-head2`. Doing so, the DHCP lease for the WAN IP address can be shared among the nodes.
⚠️ Warning: Having two machines on the network with the same MAC can cause ARP conflicts and break connectivity. Only one VM should keep its interface active.
### CARP Event Script
Under the hood, in OPNsense, a CARP event triggers some scripts (when the master dies). These are located in `/usr/local/etc/rc.syshook.d/carp/`.
To manage WAN interface on each node, I implement this PHP script `10-wan` on both nodes, using SSH (do not forget to make it executable). Depending on their role (master or backup), this will enable or disable their WAN interface:
```php
#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
if ($type != 'MASTER' && $type != 'BACKUP') {
log_error("Carp '$type' event unknown from source '{$subsystem}'");
exit(1);
}
if (!strstr($subsystem, '@')) {
log_error("Carp '$type' event triggered from wrong source '{$subsystem}'");
exit(1);
}
$ifkey = 'wan';
if ($type === "MASTER") {
log_error("enable interface '$ifkey' due CARP event '$type'");
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_error("disable interface '$ifkey' due CARP event '$type'");
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
}
```
In `Interfaces` > `Virtual IPs` > `Status`, I can force a CARP event by entering into `Persistent maintenance mode`. Triggering this allow me to test this script, which disable the WAN interface on the master while enabling it on the backup.
---
## Firewall
Let's configure the core feature of OPNsense, the firewall. I don't want to go too crazy with the rules. I only need to configure the master, thanks to the replication.
### Interface Groups
Basically I have 2 kinds of networks, those which I trust, and those which I don't. From this standpoint, I will create two zones.
Globally, my untrusted networks only have access to DNS and the internet. Trusted networks can reach other VLANs.
To begin, in `Firewall` > `Groups`, I create 2 zones to regroup my interfaces:
- **Trusted**: *Mgmt*, *User*
- **Untrusted**: *IoT*, *DMZ*, *Lab*
### Network Aliases
Next, in `Firewall` > `Aliases`, I create an alias `InternalNetworks` to regroup all my internal networks:
![OPNsense alias creation for internal networks ](images/opnsense-create-alias-internalnetworks.png)
### Firewall Rules
For all my networks, I want to allow DNS queries on the local DNS. In `Firewall` > `Rules` > `Floating`, let's create the first rule:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted, Untrusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP/UDP |
| **Source** | InternalNetworks |
| **Destination** | This Firewall |
| **Destination port range** | from: DNS - to: DNS |
| **Log** | Log packets |
| **Category** | DNS |
| **Description** | DNS query |
Next I want to allow connections towards the internet. At the same place I create a second rule:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted, Untrusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4+IPv6 |
| **Protocol** | any |
| **Source** | InternalNetworks |
| **Destination / Invert** | Invert the sense of the match |
| **Destination** | InternalNetworks |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | Internet |
| **Description** | Internet |
Finally, I want to allow anything from my trusted networks. In `Firewall` > `Rules` > `Trusted`, I create the rule:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Trusted |
| **Direction** | in |
| **TCP/IP Version** | IPv4+IPv6 |
| **Protocol** | any |
| **Source** | Trusted net |
| **Destination** | any |
| **Destination port range** | from: any - to: any |
| **Log** | Log packets |
| **Category** | Trusted |
| **Description** | Trusted |
Great, with these 3 rules, I cover the basics. The remaining rules would be to allow specific equipment to reach out to something else. For example my home assistant instance want to connect to my TV, both are on different VLAN, hence I need a rule to allow it:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | Lab |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP |
| **Source** | 192.168.66.50/32 |
| **Destination** | 192.168.37.30/32 |
| **Destination port range** | from: 3000 - to: 3001 |
| **Log** | Log packets |
| **Category** | Home Assistant |
| **Description** | Home assistant to TV |
---
## DHCP
For the DHCP, I choose **Dnsmasq**. In my current installation I use ISC DHCPv4, but as it is now deprecated, I prefer to replace it. Dnsmasq will also act as DNS, but only for my local zones.
Dnsmasq doesn't sync leases. To avoid conflicts, both nodes serve DHCP but with staggered reply delay and different ranges. The master covers the main pool, the backup a small fallback pool
### Dnsmasq General Configuration
In `Services` > `Dnsmasq DNS & DHCP` > `General`, I configure the master firewall as follow:
- **Default**
- **Enable**: Yes
- **Interface**: *Mgmt*, *User*, *IoT*, *DMZ* and *Lab*
- **DNS**
- **Listen port**: 53053
- **DNS Query Forwarding**
- **Do not forward to system defined DNS servers**: Enabled
- **DHCP**
- **DHCP FQDN**: Enabled
- **DHCP local domain**: Enabled
- **DHCP authoritative**: Enabled
- **DHCP reply delay**: 0
- **DHCP register firewall rules**: Enabled
- **Disable HA sync**: Enabled
On the backup node, I configure it the same, the only difference will be the **DHCP reply delay** which I set to **10**. This gives the master time to answer DHCP requests before the backup responds.
### DHCP Ranges
Next I configure the DHCP ranges. Both firewalls will have different ranges, the backup node will have smaller ones (only 10 leases should be enough). On the master, they are configured as follow:
![OPNsense DHCP ranges in Dnsmasq](images/opnsense-dnsmasq-dhcp-ranges.png)
### DHCP Options
Then I set some DHCP options for each domain: the `router`, the `dns-server` and the `domain-name`. I'm pointing the IP addresses to the interface's VIP:
![OPNsense DHCP options in Dnsmasq](images/opnsense-dnsmasq-dhcp-options.png)
### Hosts
Finally in in the `Hosts` tab, I define static DHCP mappings but also static IP not managed by the DHCP, to have them registered in the DNS:
![OPNsense DHCP hosts in Dnsmasq](images/opnsense-dnsmasq-dhcp-hosts.png)
---
## DNS
For the DNS, I use **Unbound**. It is a validating, recursive, caching DNS resolver built into OPNsense, which can:
- Resolve queries from the root servers.
- Cache results for faster responses.
- Check domain authenticity with DNSSEC.
- Block domains based on a blacklist.
- Add custom records.
Unbound is the recursive resolver, for local zones I forward queries to Dnsmasq.
### Unbound General Settings
Let's configure it, in `Services` > `Unbound DNS` > `General`:
![OPNsense Unbound DNS general settings](images/opnsense-unbound-general-settings.png)
### DNS Blocklist
Then I configure the blocklist in `Services` > `Unbound DNS` > `Blocklist`. I enable it and select the `[hagezi] Multi PRO mini` list. Initially I was using AdGuard Home, but I want to give this blocklist feature a chance.
To maintain the service up to date, in `System` > `Settings` > `Cron`, I add my first job that runs every night at 2AM to `Update Unbound DNSBLs`.
### Query Forwarding
Finally I configure query forwarding for my local domains to Dnsmasq. In `Services` > `Unbound DNS` > `Query Forwarding`, I add each of my local domains with their reverse lookup (PTR record):
![OPNsense Unbound DNS query forwarding configuration](images/opnsense-unbound-dns-query-forwarding.png)
---
## VPN
When I'm not home, I still want to be able to reach my services and enjoy my DNS ad blocker. For that I'm setting up a VPN, with **WireGuard**. It's fast, secure and easy to set up.
### WireGuard Instance Setup
In `VPN` > `WireGuard` > `Instances`, I create a new one:
- **Enabled**: Yes
- **Name**: *Homelan*
- **Public/Private keys**: Key-pair generated
- **Listen port**: `61337`
- **Tunnel address**: `10.13.37.1/24`
- **Depend on (CARP)**: on *lan* (vhid 1)
Once configured, I enable WireGuard and apply the configuration.
### Peer Setup
Next in the `Peer generator` tab, I fulfill the empty fields for my first device:
- **Endpoint**: `vezpi.com`
- **Name**: *S25Ultra*
- **DNS Servers**: `10.13.37.1`
Before clicking `Store and generate next`, from my device, I configure the peer by capturing the QR code. Finally I can save that peer and start over for new ones.
### Create VPN Interface
This step is not required, but ease the configuration management for firewall rules. On both firewall, in `Interfaces` > `Assignments`, I assign the `wg0 (WireGuard - Homelan)` interface and name it *VPN*.
Then in `Interfaces` > `VPN`, I enable this interface.
Finally, in `Firewall` > `Groups`, I add this interface in the *Trusted* group.
### Firewall Rule
To allow connections from outside, I need to create a firewall rule on the WAN interface:
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | WAN |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | UDP |
| **Source** | any |
| **Destination** | WAN address |
| **Destination port range** | from: 61337 - to: 61337 |
| **Log** | Log packets |
| **Category** | VPN |
| **Description** | WireGuard |
---
## Reverse Proxy
The next feature I need is a reverse proxy, to redirect incoming HTTPS requests to reach my services, such as this blog. For that I use **Caddy**. It will listen on port 80/443, that's why I moved the WebGUI off these ports at the beginning.
This service is not installed by default, I need to add a plugin. On both firewalls, In `System` > `Firmware` > `Plugins`, I tick the box to show community plugins and install `os-caddy`.
### Caddy General Settings
I refresh the page and, on the master, in `Services` > `Caddy` > `General Settings`:
- **Enable Caddy**: Yes
- **Enable Layer4 Proxy**: Yes
- **ACME**: `<email address>`
- **Auto HTTPS**: On (default)
There are two types of redirections, the `Reverse Proxy` and the `Layer4 Proxy`. The first one is for HTTPS only, where Caddy will manage the SSL.
### Reverse Proxy
In `Services` > `Caddy` > `Reverse Proxy`, I define the services directly managed by Caddy.
These services should not be exposed to everyone. In the `Access` tab, I create a list, called `Internal`, of allowed networks, including my LAN and VPN networks.
Then in the `Domains` tab, I add my domains. For example, this is here I define `cerbere.vezpi.com`, my URL to reach my OPNsense WebGUI:
- **Enable**: Yes
- **Frontend**
- **Protocol**: `https://`
- **Domain**: `cerbere.vezpi.com`
- **Port**: leave empty
- **Certificate**: Auto HTTPS
- **HTTP-01 Challenge Redirection**: `192.168.44.2`, for high availability setup
- **Description**: OPNsense
- **Access**
- **Access List**: `Internal`
- **HTTP Access Log**: Enabled
Finally in the `Handlers` tab, I define to which upstream these domains are forwarded to. For `cerbere.vezpi.com` I define this:
- **Enabled**: Yes
- **Frontend**
- **Domain**: `https://cerbere.vezpi.com`
- **Subdomain**: None
- **Handler**
- **Path**: any
- **Access**
- **Access List**: None
- **Directive**
- **Directive**: `reverse_proxy`
- **Upstream**
- **Protocol**: `https://`
- **Upstream Domain**: `127.0.0.1`
- **Upstream Port**: `4443`
- **TLS Insecure Skip Verify**: Enabled
- **Description**: OPNSense
### Layer4 Proxy
Most of my services are behind another reverse proxy on my network, Traefik. To let it manage normally its domains, I forward them using `Layer4 Routes`. It prevents Caddy to terminate SSL, the HTTPS stream is left intact.
In `Services` > `Caddy` > `Layer4 Proxy`, I create 3 routes.
The first one is for internet exposed services, like this blog or my Gitea instance:
- Enabled: Yes
- Sequence: 1
- Layer 4
- Routing Type: listener_wrappers
- Layer 7
- Matchers: TLS (SNI Client Hello)
- Domain: `blog.vezpi.com` `git.vezpi.com`
- Terminate SSL: No
- Upstream
- Upstream Domain: `192.168.66.50`
- Upstream Port: `443`
- Proxy Protocol: `v2`, if your upstream supports it
- Description: External Traefik HTTPS dockerVM
The second one is for internal only services. It is configured pretty much the same but using an access list:
- Sequence: 2
- Access
- Remote IP: `192.168.13.0/24` `192.168.88.0/24` `10.13.37.0/24`
The third one is for Traefik HTTP challenges for Let's Encrypt:
- Sequence: 3
- Layer 7
- Matchers: HTTP (Host Header)
- Domain: `blog.vezpi.com` `git.vezpi.com` etc.
- Upstream:
- Upstream Port: 80
- Proxy Protocol: Off (default)
### Firewall Rules
Finally, I need to allow connection of these ports on the firewall, I create one rule for HTTPS (and another for HTTP):
| Field | Value |
| -------------------------- | ------------------------------------- |
| **Action** | Pass |
| **Quick** | Apply the action immediately on match |
| **Interface** | WAN |
| **Direction** | in |
| **TCP/IP Version** | IPv4 |
| **Protocol** | TCP |
| **Source** | any |
| **Destination** | WAN address |
| **Destination port range** | from: HTTPS - to: HTTPS |
| **Log** | Log packets |
| **Category** | Caddy |
| **Description** | Caddy HTTPS |
---
## mDNS Repeater
The last service I want to setup in OPNsense is a mDNS repeater. This is useful for some devices to announce themselves on the network, when not on the same VLAN, such as my printer or my Chromecast. The mDNS repeater get the message from an interface to forward it to another one.
This service is also not installed by default. On both firewalls, In `System` > `Firmware` > `Plugins`, I tick the box to show community plugins and install `os-mdns-repeater`.
Then in `Services` > `mDNS Repeater`, the configuration is pretty straight forward:
- Enable: Yes
- Enable CARP Failover: Yes
- Listen Interfaces: *IoT*, *User*
---
## Service Synchronization
The final step is to synchronize all the services between the master and the backup node in the cluster. First in `System` > `High Availability` > `Status`, I click the button to `Synchronize and reconfigure all`.
Then I want to make sure that future changes are synchronized if I omit to replicate them myself. In `System` > `Settings` > `Cron`, I add a new job that runs every night to `HA update and reconfigure backup`.
---
## Conclusion
🚀 My **OPNsense** cluster is now configured and ready to go live!
I hope this OPNsense full configuration for my own network, help you with your own setup.
The next phase is to plan the migration from my current OPNsense box to these two highly available firewalls. This new infrastructure would secure my future operations on the firewall, while removing this SPOF (Single Point Of Failure) of my network.
See you next time to tell how this operation went!
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

@@ -0,0 +1,425 @@
---
slug: proxmox-cluster-upgrade-8-to-9-ceph
title: Mise à niveau de mon cluster Proxmox VE HA 3 nœuds de 8 vers 9 basé sur Ceph
description: Mise à niveau pas à pas de mon cluster Proxmox VE 3 nœuds en haute disponibilité, de 8 vers 9, basé sur Ceph, sans aucune interruption.
date: 2025-11-04
draft: false
tags:
- proxmox
- high-availability
- ceph
categories:
- homelab
image: cover-14.webp
---
## Intro
Mon **cluster Proxmox VE** a presque un an maintenant, et je n’ai pas tenu les nœuds complètement à jour. Il est temps de m’en occuper et de le passer en Proxmox VE **9**.
Je recherche principalement les nouvelles règles d’affinité HA, mais voici les changements utiles apportés par cette version :
- Debian 13 "Trixie".
- Snapshots pour le stockage LVM partagé thick-provisioned.
- Fonctionnalité SDN fabrics.
- Interface mobile améliorée.
- Règles d’affinité dans le cluster HA.
Le cluster est composée de 3 nœuds, hautement disponible, avec une configuration hyper‑convergée, utilisant Ceph pour le stockage distribué.
Dans cet article, je décris les étapes de mise à niveau de mon cluster Proxmox VE, de la version 8 vers 9, tout en gardant les ressources actives. [Documentation officielle](https://pve.proxmox.com/wiki/Upgrade_from_8_to_9).
---
## Prérequis
Avant de se lancer dans la mise à niveau, passons en revue les prérequis :
1. Tous les nœuds mis à jour vers la dernière version Proxmox VE `8.4`.
2. Cluster Ceph mis à niveau vers Squid (`19.2`).
3. Proxmox Backup Server mis à jour vers la version 4.
4. Accès fiable au nœud.
5. Cluster en bonne santé.
6. Sauvegarde de toutes les VM et CT.
7. Au moins 5 Go libres sur `/`.
Remarques sur mon environnement :
- Les nœuds PVE sont en `8.3.2`, donc une mise à jour mineure vers 8.4 est d’abord requise.
- Ceph tourne sous Reef (`18.2.4`) et sera mis à niveau vers Squid après PVE 8.4.
- Je n’utilise pas PBS dans mon homelab, donc je peux sauter cette étape.
- J’ai plus de 10 Go disponibles sur `/` sur mes nœuds, c’est suffisant.
- Je n’ai qu’un accès console SSH, si un nœud ne répond plus je pourrais avoir besoin d’un accès physique.
- Une VM a un passthrough CPU (APU). Le passthrough empêche la migration à chaud, donc je supprime ce mapping avant la mise à niveau.
- Mettre les OSD Ceph en `noout` pendant la mise à niveau pour éviter le rebalancing automatique :
```bash
ceph osd set noout
```
### Mettre à Jour Proxmox VE vers 8.4.14
Le plan est simple, pour tous les nœuds, un par un :
1. Activer le mode maintenance
```bash
ha-manager crm-command node-maintenance enable $(hostname)
```
2. Mettre à jour le nœud
```bash
apt-get update
apt-get dist-upgrade -y
```
À la fin de la mise à jour, on me propose de retirer booloader, ce que j’exécute :
```plaintext
Removable bootloader found at '/boot/efi/EFI/BOOT/BOOTX64.efi', but GRUB packages not set up to update it!
Run the following command:
echo 'grub-efi-amd64 grub2/force_efi_extra_removable boolean true' | debconf-set-selections -v -u
Then reinstall GRUB with 'apt install --reinstall grub-efi-amd64'
```
3. Redémarrer la machine
```bash
reboot
```
4. Désactiver le mode maintenance
```bash
ha-manager crm-command node-maintenance disable $(hostname)
```
Entre chaque nœud, j’attends que le statut Ceph soit clean, sans alertes.
✅ À la fin, le cluster Proxmox VE est mis à jour vers `8.4.14`
### Mettre à Niveau Ceph de Reef vers Squid
Je peux maintenant passer à la mise à niveau de Ceph, la documentation Proxmox pour cette procédure est [ici](https://pve.proxmox.com/wiki/Ceph_Reef_to_Squid).
Mettre à jour les sources de paquets Ceph sur chaque nœud :
```bash
sed -i 's/reef/squid/' /etc/apt/sources.list.d/ceph.list
```
Mettre à niveau les paquets Ceph :
```
apt update
apt full-upgrade -y
```
Après la mise à niveau sur le premier nœud, la version Ceph affiche maintenant `19.2.3`, je peux voir mes OSD apparaître comme obsolètes, les moniteurs nécessitent soit une mise à niveau soit un redémarrage :
![État du stockage Ceph dans Proxmox après la mise à jour des paquets Ceph du premier nœud](images/proxmox-ceph-version-upgrade.png)
Je poursuis et mets à niveau les paquets sur les 2 autres nœuds.
J’ai un moniteur sur chaque nœud, donc je dois redémarrer chaque moniteur, un nœud à la fois :
```bash
systemctl restart ceph-mon.target
```
Je vérifie le statut Ceph entre chaque redémarrage :
```bash
ceph status
```
Une fois tous les moniteurs redémarrés, ils rapportent la dernière version, avec `ceph mon dump` :
- Avant : `min_mon_release 18 (reef)`
- Après : `min_mon_release 19 (squid)`
Je peux maintenant redémarrer les OSD, toujours un nœud à la fois. Dans ma configuration, j’ai un OSD par nœud :
```bash
systemctl restart ceph-osd.target
```
Je surveille le statut Ceph avec la WebGUI Proxmox. Après le redémarrage, elle affiche quelques couleurs fancy. J’attends juste que les PG redeviennent verts, cela prend moins d’une minute :
![État du stockage Ceph dans Proxmox lors du premier redémarrage d'un OSD](images/proxmox-ceph-status-osd-restart.png)
Un avertissement apparaît : `HEALTH_WARN: all OSDs are running squid or later but require_osd_release < squid`
Maintenant tous mes OSD tournent sous Squid, je peux fixer la version minimum à celle‑ci :
```bash
ceph osd require-osd-release squid
```
ℹ️ Je n’utilise pas actuellement CephFS donc je n’ai pas à me soucier du daemon MDS (MetaData Server).
✅ Le cluster Ceph a été mis à niveau avec succès vers Squid (`19.2.3`).
---
## Vérifications
Les prérequis pour mettre à niveau le cluster vers Proxmox VE 9 sont maintenant complets. Suis‑je prêt à mettre à niveau ? Pas encore.
Un petit programme de checklist nommé **`pve8to9`** est inclus dans les derniers paquets Proxmox VE 8.4. Le programme fournit des indices et des alertes sur les problèmes potentiels avant, pendant et après la mise à niveau. Pratique non ?
Lancer l’outil la première fois me donne des indications sur ce que je dois faire. Le script vérifie un certain nombre de paramètres, regroupés par thème. Par exemple, voici la section sur les Virtual Guest :
```plaintext
= VIRTUAL GUEST CHECKS =
INFO: Checking for running guests..
WARN: 1 running guest(s) detected - consider migrating or stopping them.
INFO: Checking if LXCFS is running with FUSE3 library, if already upgraded..
SKIP: not yet upgraded, no need to check the FUSE library version LXCFS uses
INFO: Checking for VirtIO devices that would change their MTU...
PASS: All guest config descriptions fit in the new limit of 8 KiB
INFO: Checking container configs for deprecated lxc.cgroup entries
PASS: No legacy 'lxc.cgroup' keys found.
INFO: Checking VM configurations for outdated machine versions
PASS: All VM machine versions are recent enough
```
À la fin, vous avez le résumé. L’objectif est de corriger autant de `FAILURES` et `WARNINGS` que possible :
```plaintext
= SUMMARY =
TOTAL: 57
PASSED: 43
SKIPPED: 7
WARNINGS: 2
FAILURES: 2
```
Passons en revue les problèmes qu’il a trouvés :
```
FAIL: 1 custom role(s) use the to-be-dropped 'VM.Monitor' privilege and need to be adapted after the upgrade
```
Il y a quelque temps, pour utiliser Terraform avec mon cluster Proxmox, j'ai créé un rôle dédié. C'était détaillé dans cet [article]({{< ref "post/3-terraform-create-vm-proxmox" >}}).
Ce rôle utilise le privilège `VM.Monitor`, qui a été supprimé dans Proxmox VE 9. De nouveaux privilèges, sous `VM.GuestAgent.*`, existent à la place. Je supprime donc celui-ci et j'ajouterai les nouveaux une fois le cluster mis à niveau.
```
FAIL: systemd-boot meta-package installed. This will cause problems on upgrades of other boot-related packages. Remove 'systemd-boot' See https://pve.proxmox.com/wiki/Upgrade_from_8_to_9#sd-boot-warning for more information.
```
Proxmox VE utilise généralement `systemd-boot` pour le démarrage uniquement dans certaines configurations gérées par proxmox-boot-tool. Le méta-paquet `systemd-boot` doit être supprimé. Ce paquet était automatiquement installé sur les systèmes de PVE 8.1 à 8.4, car il contenait `bootctl` dans Bookworm.
Si le script de la checklist pve8to9 le suggère, vous pouvez supprimer le méta-paquet `systemd-boot` sans risque, sauf si vous l'avez installé manuellement et que vous utilisez `systemd-boot` comme bootloader :
```bash
apt remove systemd-boot -y
```
```
WARN: 1 running guest(s) detected - consider migrating or stopping them.
```
Dans une configuration HA, avant de mettre à jour un nœud, je le mets en mode maintenance. Cela déplace automatiquement les ressources ailleurs. Quand ce mode est désactivé, la machine revient à son emplacement précédent.
```
WARN: The matching CPU microcode package 'amd64-microcode' could not be found! Consider installing it to receive the latest security and bug fixes for your CPU.
Ensure you enable the 'non-free-firmware' component in the apt sources and run:
apt install amd64-microcode
```
Il est recommandé d’installer le microcode processeur pour les mises à jour qui peuvent corriger des bogues matériels, améliorer les performances et renforcer la sécurité du processeur.
J’ajoute la source `non-free-firmware` aux sources actuelles :
```bash
sed -i '/^deb /{/non-free-firmware/!s/$/ non-free-firmware/}' /etc/apt/sources.list
```
Puis installe le paquet `amd64-microcode` :
```bash
apt update
apt install amd64-microcode -y
```
Après ces petits ajustements, suis‑je prêt ? Vérifions en relançant le script `pve8to9`.
⚠️ N’oubliez pas de lancer `pve8to9` sur tous les nœuds pour vous assurer que tout est OK.
---
## Mise à Niveau
🚀 Maintenant tout est prêt pour le grand saut ! Comme pour la mise à jour mineure, je procéderai nœud par nœud, en gardant mes VM et CT actives.
### Mettre le Mode Maintenance
D’abord, j’entre le nœud en mode maintenance. Cela déplacera la charge existante sur les autres nœuds :
```bash
ha-manager crm-command node-maintenance enable $(hostname)
```
Après avoir exécuté la commande, j’attends environ une minute pour laisser le temps aux ressources de migrer.
### Changer les Dépôts Sources vers Trixie
Depuis Debian Trixie, le format `deb822` est désormais disponible et recommandé pour les sources. Il est structuré autour d’un format clé/valeur. Cela offre une meilleure lisibilité et sécurité.
#### Sources Debian
```bash
cat > /etc/apt/sources.list.d/debian.sources << EOF
Types: deb deb-src
URIs: http://deb.debian.org/debian/
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb deb-src
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
```
#### Sources Proxmox (sans subscription)
```bash
cat > /etc/apt/sources.list.d/proxmox.sources << EOF
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
```
#### Sources Ceph Squid (sans subscription)
```bash
cat > /etc/apt/sources.list.d/ceph.sources << EOF
Types: deb
URIs: http://download.proxmox.com/debian/ceph-squid
Suites: trixie
Components: no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
```
#### Supprimer les Anciennes Listes Bookworm
Les listes pour Debian Bookworm au format ancien doivent être supprimées :
```bash
rm -f /etc/apt/sources.list{,.d/*.list}
```
### Mettre à Jour les Dépôts `apt` Configurés
Rafraîchir les dépôts :
```bash
apt update
```
```plaintext
Get:1 http://security.debian.org/debian-security trixie-security InRelease [43.4 kB]
Get:2 http://deb.debian.org/debian trixie InRelease [140 kB]
Get:3 http://download.proxmox.com/debian/ceph-squid trixie InRelease [2,736 B]
Get:4 http://download.proxmox.com/debian/pve trixie InRelease [2,771 B]
Get:5 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:6 http://security.debian.org/debian-security trixie-security/main Sources [91.1 kB]
Get:7 http://security.debian.org/debian-security trixie-security/non-free-firmware Sources [696 B]
Get:8 http://security.debian.org/debian-security trixie-security/main amd64 Packages [69.0 kB]
Get:9 http://security.debian.org/debian-security trixie-security/main Translation-en [45.1 kB]
Get:10 http://security.debian.org/debian-security trixie-security/non-free-firmware amd64 Packages [544 B]
Get:11 http://security.debian.org/debian-security trixie-security/non-free-firmware Translation-en [352 B]
Get:12 http://download.proxmox.com/debian/ceph-squid trixie/no-subscription amd64 Packages [33.2 kB]
Get:13 http://deb.debian.org/debian trixie/main Sources [10.5 MB]
Get:14 http://download.proxmox.com/debian/pve trixie/pve-no-subscription amd64 Packages [241 kB]
Get:15 http://deb.debian.org/debian trixie/non-free-firmware Sources [6,536 B]
Get:16 http://deb.debian.org/debian trixie/contrib Sources [52.3 kB]
Get:17 http://deb.debian.org/debian trixie/main amd64 Packages [9,669 kB]
Get:18 http://deb.debian.org/debian trixie/main Translation-en [6,484 kB]
Get:19 http://deb.debian.org/debian trixie/contrib amd64 Packages [53.8 kB]
Get:20 http://deb.debian.org/debian trixie/contrib Translation-en [49.6 kB]
Get:21 http://deb.debian.org/debian trixie/non-free-firmware amd64 Packages [6,868 B]
Get:22 http://deb.debian.org/debian trixie/non-free-firmware Translation-en [4,704 B]
Get:23 http://deb.debian.org/debian trixie-updates/main Sources [2,788 B]
Get:24 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5,412 B]
Get:25 http://deb.debian.org/debian trixie-updates/main Translation-en [4,096 B]
Fetched 27.6 MB in 3s (8,912 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
666 packages can be upgraded. Run 'apt list --upgradable' to see them.
```
😈 666 paquets, je suis condamné !
### Mise à Niveau vers Debian Trixie et Proxmox VE 9
Lancer la mise à niveau :
```bash
apt-get dist-upgrade -y
```
Pendant le processus, vous serez invité à approuver des changements de fichiers de configuration et certains redémarrages de services. Il se peut aussi que vous voyiez la sortie de certains changements, vous pouvez simplement en sortir en appuyant sur `q` :
- `/etc/issue` : Proxmox VE régénérera automatiquement ce fichier au démarrage -> `No`
- `/etc/lvm/lvm.conf` : Changements pertinents pour Proxmox VE seront mis à jour -> `Yes`
- `/etc/ssh/sshd_config` : Selon votre configuration -> `Inspect`
- `/etc/default/grub` : Seulement si vous l’avez modifié manuellement -> `Inspect`
- `/etc/chrony/chrony.conf` : Si vous n’avez pas fait de modifications supplémentaires -> `Yes`
La mise à niveau a pris environ 5 minutes, selon le matériel.
À la fin de la mise à niveau, redémarrez la machine :
```bash
reboot
```
### Sortir du Mode Maintenance
Enfin, quand le nœud (espérons‑le) est revenu, vous pouvez désactiver le mode maintenance. La charge qui était localisée sur cette machine reviendra :
```bash
ha-manager crm-command node-maintenance disable $(hostname)
```
### Validation Après Mise à Niveau
- Vérifier la communication du cluster :
```bash
pvecm status
```
- Vérifier les points de montage des stockages
- Vérifier la santé du cluster Ceph :
```bash
ceph status
```
- Confirmer les opérations VM, les sauvegardes et les groupes HA
Les groupes HA ont été retirés au profit des règles d’affinité HA. Les groupes HA sont automatiquement migrés en règles HA.
- Désactiver le dépôt PVE Enterprise
Si vous n’utilisez pas le dépôt `pve-enterprise`, vous pouvez le désactiver : `` ```
```bash
sed -i 's/^/#/' /etc/apt/sources.list.d/pve-enterprise.sources
```
🔁 Ce nœud est maintenant mis à niveau vers Proxmox VE 9. Procédez aux autres nœuds.
## Actions Postérieures
Une fois que tout le cluster a été mis à niveau, procédez aux actions postérieures :
- Supprimer le flag `noout` du cluster Ceph :
```bash
ceph osd unset noout
```
- Recréer les mappings PCI passthrough
Pour la VM pour laquelle j’ai retiré le mapping hôte au début de la procédure, je peux maintenant recréer le mapping.
- Ajouter les privilèges pour le rôle Terraform
Pendant la phase de vérification, il m’a été conseillé de supprimer le privilège `VM.Monitor` de mon rôle personnalisé pour Terraform. Maintenant que de nouveaux privilèges ont été ajoutés avec Proxmox VE 9, je peux les attribuer à ce rôle :
- VM.GuestAgent.Audit
- VM.GuestAgent.FileRead
- VM.GuestAgent.FileWrite
- VM.GuestAgent.FileSystemMgmt
- VM.GuestAgent.Unrestricted
## Conclusion
🎉 Mon cluster Proxmox VE est maintenant en version 9 !
Le processus de mise à niveau s’est déroulé assez tranquillement, sans aucune interruption pour mes ressources.
J’ai maintenant accès aux règles d’affinité HA, dont j’avais besoin pour mon cluster OPNsense.
Comme vous avez pu le constater, je ne maintiens pas mes nœuds à jour très souvent. Je pourrais automatiser cela la prochaine fois, pour les garder à jour sans effort.
@@ -0,0 +1,426 @@
---
slug: proxmox-cluster-upgrade-8-to-9-ceph
title: Upgrading my 3-node Proxmox VE HA Cluster from 8 to 9 based on Ceph
description: Step-by-step upgrade of my 3-node Proxmox VE highly available cluster from 8 to 9, based on Ceph distributed storage, without any downtime.
date: 2025-11-04
draft: false
tags:
- proxmox
- high-availability
- ceph
categories:
- homelab
image: cover-14.webp
---
## Intro
My **Proxmox VE** cluster is almost one year old now, and I haven’t kept the nodes fully up to date. Time to address this and bump it to Proxmox VE **9**.
I'm mainly after the new HA affinity rules, but here the useful changes that this version brings:
- Debian 13 "Trixie".
- Snapshots for thick-provisioned LVM shared storage.
- SDN fabrics feature.
- Improved mobile UI.
- Affinity rules in HA cluster.
The cluster is a three‑node, highly available, hyper‑converged setup using Ceph for distributed storage.
In this article, I'll walk through the upgrade steps for my Proxmox VE cluster, from 8 to 9, while keeping the resources up and running. [Official docs](https://pve.proxmox.com/wiki/Upgrade_from_8_to_9).
---
## Prerequisites
Before jumping into the upgrade, let's review the prerequisites:
1. All nodes upgraded to the latest Proxmox VE `8.4`.
2. Ceph cluster upgraded to Squid (`19.2`).
3. Proxmox Backup Server upgraded to version 4.
4. Reliable access to the node.
5. Healthy cluster.
6. Backup of all VMs and CTs.
7. At least 5 GB free on `/`.
Notes about my environment:
- PVE nodes are on `8.3.2`, so a minor upgrade to 8.4 is required first.
- Ceph is Reef (`18.2.4`) and will be upgraded to Squid after PVE 8.4.
- I don’t use PBS in my homelab, so I can skip that step.
- I have more than 10GB available on `/` on my nodes, this is fine.
- I only have SSH console access, if a node becomes unresponsive I may need physical access.
- One VM has a CPU passthrough (APU). Passthrough prevents live‑migration, so I remove that mapping prior to the upgrade.
- Set Ceph OSDs to `noout` during the upgrade to avoid automatic rebalancing:
```bash
ceph osd set noout
```
### Update Proxmox VE to 8.4.14
The plan is simple, for all nodes, one at a time:
1. Enable the maintenance mode
```bash
ha-manager crm-command node-maintenance enable $(hostname)
```
2. Update the node
```bash
apt-get update
apt-get dist-upgrade -y
```
At the end of the update, I'm invited to remove a bootloader, which I execute:
```plaintext
Removable bootloader found at '/boot/efi/EFI/BOOT/BOOTX64.efi', but GRUB packages not set up to update it!
Run the following command:
echo 'grub-efi-amd64 grub2/force_efi_extra_removable boolean true' | debconf-set-selections -v -u
Then reinstall GRUB with 'apt install --reinstall grub-efi-amd64'
```
3. Restart the machine
```bash
reboot
```
4. Disable the maintenance node
```bash
ha-manager crm-command node-maintenance disable $(hostname)
```
Between each node, I wait for the Ceph status to be clean, without warnings.
✅ At the end, the Proxmox VE cluster is updated to `8.4.14`
### Upgrade Ceph from Reef to Squid
I can now move on into the Ceph upgrade, the Proxmox documentation for that procedure is [here](https://pve.proxmox.com/wiki/Ceph_Reef_to_Squid).
Update Ceph package sources on every node:
```bash
sed -i 's/reef/squid/' /etc/apt/sources.list.d/ceph.list
```
Upgrade the Ceph packages:
```
apt update
apt full-upgrade -y
```
After the upgrade on the first node, the Ceph version now shows `19.2.3`, I can see my OSDs appear as outdated, the monitors need either an upgrade or a restart:
![Ceph storage status in Proxmox after first node Ceph package udpate](images/proxmox-ceph-version-upgrade.png)
I carry on and upgrade the packages on the 2 other nodes.
I have a monitor on each node, so I have to restart each monitor, one node at a time:
```bash
systemctl restart ceph-mon.target
```
I verify the Ceph status between each restart:
```bash
ceph status
```
Once all monitors are restarted, they report the latest version, with `ceph mon dump`:
- Before: `min_mon_release 18 (reef)`
- After: `min_mon_release 19 (squid)`
Now I can restart the OSDs, still one node at a time. In my setup, I have one OSD per node:
```bash
systemctl restart ceph-osd.target
```
I monitor the Ceph status with the Proxmox WebGUI. After the restart, it is showing some fancy colors. I'm just waiting for the PGs to be back to green, it takes less than a minute:
![Ceph storage status in Proxmox during the first OSD restart](images/proxmox-ceph-status-osd-restart.png)
A warning shows up: `HEALTH_WARN: all OSDs are running squid or later but require_osd_release < squid`
Now all my OSDs are running Squid, I can set the minimum version to it:
```bash
ceph osd require-osd-release squid
```
ℹ️ I'm not currently using CephFS so I don't have to care about the MDS (MetaData Server) daemon.
✅ The Ceph cluster has been successfully upgraded to Squid (`19.2.3`).
---
## Checks
The prerequisites to upgrade the cluster to Proxmox VE 9 are now complete. Am I ready to upgrade? Not yet.
A small checklist program named **`pve8to9`** is included in the latest Proxmox VE 8.4 packages. The program will provide hints and warnings about potential issues before, during and after the upgrade process. Pretty handy isn't it?
Running the tool the first time give me some insights on what I need to do. The script checks a number of parameters, grouped by theme. For example, this is the Virtual Guest section:
```plaintext
= VIRTUAL GUEST CHECKS =
INFO: Checking for running guests..
WARN: 1 running guest(s) detected - consider migrating or stopping them.
INFO: Checking if LXCFS is running with FUSE3 library, if already upgraded..
SKIP: not yet upgraded, no need to check the FUSE library version LXCFS uses
INFO: Checking for VirtIO devices that would change their MTU...
PASS: All guest config descriptions fit in the new limit of 8 KiB
INFO: Checking container configs for deprecated lxc.cgroup entries
PASS: No legacy 'lxc.cgroup' keys found.
INFO: Checking VM configurations for outdated machine versions
PASS: All VM machine versions are recent enough
```
At the end, you have the summary. The goal is to address as many `FAILURES` and `WARNINGS` as possible:
```plaintext
= SUMMARY =
TOTAL: 57
PASSED: 43
SKIPPED: 7
WARNINGS: 2
FAILURES: 2
```
Let's review the problems it found:
```
FAIL: 1 custom role(s) use the to-be-dropped 'VM.Monitor' privilege and need to be adapted after the upgrade
```
Some time ago, in order to use Terraform with my Proxmox cluster, I created a dedicated role. This was detailed in that [post]({{< ref "post/3-terraform-create-vm-proxmox" >}}).
This role is using the `VM.Monitor` privilege, which is removed in Proxmox VE 9. Instead, new privileges under `VM.GuestAgent.*` exist. So I remove this one and I'll add those once the cluster have been upgraded.
```
FAIL: systemd-boot meta-package installed. This will cause problems on upgrades of other boot-related packages. Remove 'systemd-boot' See https://pve.proxmox.com/wiki/Upgrade_from_8_to_9#sd-boot-warning for more information.
```
Proxmox VE usually uses `systemd-boot` for booting only in some configurations which are managed by `proxmox-boot-tool`, the meta-package `systemd-boot` should be removed. The package was automatically shipped for systems installed from the PVE 8.1 to PVE 8.4, as it contained `bootctl` in Bookworm.
If the `pve8to9` checklist script suggests it, the `systemd-boot` meta-package is safe to remove unless you manually installed it and are using `systemd-boot` as a bootloader:
```bash
apt remove systemd-boot -y
```
```
WARN: 1 running guest(s) detected - consider migrating or stopping them.
```
In HA setup, before updating a node, I put it in maintenance mode. This automatically moves the workload elsewhere. When this mode is disabled, the workload moves back to its previous location.
```
WARN: The matching CPU microcode package 'amd64-microcode' could not be found! Consider installing it to receive the latest security and bug fixes for your CPU.
Ensure you enable the 'non-free-firmware' component in the apt sources and run:
apt install amd64-microcode
```
It is recommended to install processor microcode for updates which can fix hardware bugs, improve performance, and enhance security features of the processor.
I add the `non-free-firmware` source to the current ones:
```bash
sed -i '/^deb /{/non-free-firmware/!s/$/ non-free-firmware/}' /etc/apt/sources.list
```
Then install the `amd64-microcode` package:
```bash
apt update
apt install amd64-microcode -y
```
After these small adjustments, am I ready yet? Let's find out by relaunching the `pve8to9` script.
⚠️ Don't forget to run the `pve8to9` on all nodes to make sure everything is good.
---
## Upgrade
🚀 Now everything is ready for the big move! Like I did for the minor update, I'll proceed one node at a time, keeping my VMs and CTs up and running.
### Set Maintenance Mode
First, I enter the node into maintenance mode. This will move existing workload on other nodes:
```bash
ha-manager crm-command node-maintenance enable $(hostname)
```
After issuing the command, I wait about one minute to give the resources the time to migrate.
### Change Source Repositories to Trixie
Since Debian Trixie, the `deb822` format is now available and recommended for sources. It is structured around key/value format. This offers better readability and security.
#### Debian Sources
```bash
cat > /etc/apt/sources.list.d/debian.sources << EOF
Types: deb deb-src
URIs: http://deb.debian.org/debian/
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb deb-src
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
```
#### Proxmox Sources (without subscription)
```bash
cat > /etc/apt/sources.list.d/proxmox.sources << EOF
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
```
#### Ceph Squid Sources (without subscription)
```bash
cat > /etc/apt/sources.list.d/ceph.sources << EOF
Types: deb
URIs: http://download.proxmox.com/debian/ceph-squid
Suites: trixie
Components: no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
```
#### Remove Old Bookworm Source Lists
The lists for Debian Bookworm in the old format must be removed:
```bash
rm -f /etc/apt/sources.list{,.d/*.list}
```
### Update the Configured `apt` Repositories
Refresh the repositories:
```bash
apt update
```
```plaintext
Get:1 http://security.debian.org/debian-security trixie-security InRelease [43.4 kB]
Get:2 http://deb.debian.org/debian trixie InRelease [140 kB]
Get:3 http://download.proxmox.com/debian/ceph-squid trixie InRelease [2,736 B]
Get:4 http://download.proxmox.com/debian/pve trixie InRelease [2,771 B]
Get:5 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:6 http://security.debian.org/debian-security trixie-security/main Sources [91.1 kB]
Get:7 http://security.debian.org/debian-security trixie-security/non-free-firmware Sources [696 B]
Get:8 http://security.debian.org/debian-security trixie-security/main amd64 Packages [69.0 kB]
Get:9 http://security.debian.org/debian-security trixie-security/main Translation-en [45.1 kB]
Get:10 http://security.debian.org/debian-security trixie-security/non-free-firmware amd64 Packages [544 B]
Get:11 http://security.debian.org/debian-security trixie-security/non-free-firmware Translation-en [352 B]
Get:12 http://download.proxmox.com/debian/ceph-squid trixie/no-subscription amd64 Packages [33.2 kB]
Get:13 http://deb.debian.org/debian trixie/main Sources [10.5 MB]
Get:14 http://download.proxmox.com/debian/pve trixie/pve-no-subscription amd64 Packages [241 kB]
Get:15 http://deb.debian.org/debian trixie/non-free-firmware Sources [6,536 B]
Get:16 http://deb.debian.org/debian trixie/contrib Sources [52.3 kB]
Get:17 http://deb.debian.org/debian trixie/main amd64 Packages [9,669 kB]
Get:18 http://deb.debian.org/debian trixie/main Translation-en [6,484 kB]
Get:19 http://deb.debian.org/debian trixie/contrib amd64 Packages [53.8 kB]
Get:20 http://deb.debian.org/debian trixie/contrib Translation-en [49.6 kB]
Get:21 http://deb.debian.org/debian trixie/non-free-firmware amd64 Packages [6,868 B]
Get:22 http://deb.debian.org/debian trixie/non-free-firmware Translation-en [4,704 B]
Get:23 http://deb.debian.org/debian trixie-updates/main Sources [2,788 B]
Get:24 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5,412 B]
Get:25 http://deb.debian.org/debian trixie-updates/main Translation-en [4,096 B]
Fetched 27.6 MB in 3s (8,912 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
666 packages can be upgraded. Run 'apt list --upgradable' to see them.
```
😈 666 packages, I'm doomed!
### Upgrade to Debian Trixie and Proxmox VE 9
Launch the upgrade:
```bash
apt-get dist-upgrade -y
```
During the process , you will be prompted to approve changes to configuration files and some service restarts. You may also be shown the output of changes, you can simply exit there by pressing `q`:
- `/etc/issue`: Proxmox VE will auto-generate this file on boot -> `No`
- `/etc/lvm/lvm.conf`: Changes relevant for Proxmox VE will be updated -> `Yes`
- `/etc/ssh/sshd_config`: Depending your setup -> `Inspect`
- `/etc/default/grub`: Only if you changed it manually -> `Inspect`
- `/etc/chrony/chrony.conf`: If you did not make extra changes yourself -> `Yes`
The upgrade took about 5 minutes, depending of the hardware.
At the end of the upgrade, restart the machine:
```bash
reboot
```
### Remove Maintenance Mode
Finally when the node (hopefully) comes back, you can disable the maintenance mode. The workload which was located on that machine will come back:
```bash
ha-manager crm-command node-maintenance disable $(hostname)
```
### Post-Upgrade Validation
- Check cluster communication:
```bash
pvecm status
```
- Verify storage mounts points
- Check Ceph cluster health :
```bash
ceph status
```
- Confirm VM operations, backups, and HA groups
HA groups have been removed at the profit of HA affinity rules. HA groups are automatically migrated to HA rules.
- Disable PVE Enterprise repository
If you don't use the `pve-enterprise` repo, you can disable it:
```bash
sed -i 's/^/#/' /etc/apt/sources.list.d/pve-enterprise.sources
```
🔁 This node is now upgraded to Proxmox VE 9. Proceed to other nodes.
## Post Actions
Once the whole cluster has been upgraded, proceed to post actions:
- Remove the Ceph cluster `noout` flag:
```bash
ceph osd unset noout
```
- Recreate PCI passthrough mapping
For the VM which I removed the host mapping at the beginning of the procedure, I can now recreate the mapping.
- Add privileges for the Terraform role
During the check phase, I was advised to remove the privilege `VM.Monitor` from my custom role for Terraform. Now that new privileges have been added with Proxmox VE 9, I can assign them to that role:
- VM.GuestAgent.Audit
- VM.GuestAgent.FileRead
- VM.GuestAgent.FileWrite
- VM.GuestAgent.FileSystemMgmt
- VM.GuestAgent.Unrestricted
## Conclusion
🎉My Proxmox VE cluster is now is version 9!
The upgrade process was pretty smooth, without any downtime for my resources.
Now I have access to HA affinity rules, which I was needing for my OPNsense cluster.
As you could observe, I'm not maintaining my node up to date quite often. I might automate this next time, to keep them updated without any effort.
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

@@ -0,0 +1,424 @@
---
slug: migration-opnsense-proxmox-highly-available
title: Migration vers mon cluster OPNsense HA dans Proxmox VE
description: La démarche détaillée de la migration de ma box OPNsense physique vers un cluster de VM hautement disponible dans Proxmox VE.
date: 2025-11-20
draft: false
tags:
- opnsense
- high-availability
- proxmox
categories:
- homelab
image: cover-15.webp
---
## Intro
C'est la dernière étape de mon aventure de virtualisation d'**OPNsense**.
Il y a quelques mois, ma [box OPNsense physique a crash]({{< ref "post/10-opnsense-crash-disk-panic" >}}) à cause d'une défaillance matérielle. Cela a plongé ma maison dans le noir, littéralement. Pas de réseau, pas de lumières.
💡 Pour éviter de me retrouver à nouveau dans cette situation, j'ai imaginé un plan pour virtualiser mon pare-feu OPNsense dans mon cluster **Proxmox VE**. La dernière fois, j'avais mis en place un [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) pour valider cette solution : créer un cluster de deux VM **OPNsense** dans Proxmox et rendre le firewall hautement disponible.
Cette fois, je vais couvrir la création de mon futur cluster OPNsense depuis zéro, planifier la bascule et finalement migrer depuis ma box physique actuelle. C'est parti !
---
## La Configuration VLAN
Pour mes plans, je dois connecter le WAN, provenant de ma box FAI, à mon switch principal. Pour cela je crée un VLAN dédié pour transporter ce flux jusqu'à mes nœuds Proxmox.
### UniFi
D'abord, je configure mon réseau de couche 2 qui est géré par UniFi. Là, je dois créer deux VLANs :
- _WAN_ (20) : transporte le WAN entre ma box FAI et mes nœuds Proxmox.
- _pfSync_ (44), communication entre mes nœuds OPNsense.
Dans le contrôleur UniFi, dans `Paramètres` > `Réseaux`, j'ajoute un `New Virtual Network`. Je le nomme `WAN` et lui donne l'ID VLAN 20 :
![Création du VLAN WAN dans le contrôleur UniFi](images/unifi-add-vlan-for-wan.png)
Je fais la même chose pour le VLAN `pfSync` avec l'ID VLAN 44.
Je prévois de brancher ma box FAI sur le port 15 de mon switch, qui est désactivé pour l'instant. Je l'active, définis le VLAN natif sur le nouveau `WAN (20)` et désactive le trunking :
![Configuration du port du switch UniFi pour la liaison WAN](images/unifi-enable-port-wan-vlan.png)
Une fois ce réglage appliqué, je m'assure que seules les ports où sont connectés mes nœuds Proxmox propagent ces VLANs sur leur trunk.
J'ai fini la configuration UniFi.
### Proxmox SDN
Maintenant que le VLAN peut atteindre mes nœuds, je veux le gérer dans le SDN de Proxmox. J'ai configuré le SDN dans [cet article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}).
Dans `Datacenter` > `SDN` > `VNets`, je crée un nouveau VNet, je l'appelle `vlan20` pour suivre ma propre convention de nommage, je lui donne l'alias _WAN_ et j'utilise le tag (ID VLAN) 20 :
![Création du VNet pour le WAN dans le SDN Proxmox](images/proxmox-sdn-new-vnet-wan.png)
Je crée aussi le `vlan44` pour le VLAN _pfSync_, puis j'applique cette configuration et nous avons terminé avec le SDN.
---
## Création des VMs
Maintenant que la configuration VLAN est faite, je peux commencer à construire les machines virtuelles sur Proxmox.
La première VM s'appelle `cerbere-head1` (je ne vous l'ai pas dit ? Mon firewall actuel s'appelle `cerbere`, ça a encore plus de sens maintenant !). Voici les réglages :
- **Type d'OS** : Linux (même si OPNsense est basé sur FreeBSD)
- **Type de machine** : `q35`
- **BIOS** : `OVMF (UEFI)`
- **Disque** : 20 Go sur stockage Ceph distribué
- **RAM** : 4 Go, ballooning désactivé
- **CPU** : 2 vCPU
- **NICs**, pare-feu désactivé :
1. `vmbr0` (_Mgmt_)
2. `vlan20` (_WAN_)
3. `vlan13` _(User)_
4. `vlan37` _(IoT)_
5. `vlan44` _(pfSync)_
6. `vlan55` _(DMZ)_
7. `vlan66` _(Lab)_
![Paramètres matériels de la VM OPNsense dans Proxmox](images/proxmox-cerbere-vm-settings.png)
ℹ️ Maintenant je clone cette VM pour créer `cerbere-head2`, puis je procède à l'installation d'OPNsense. Je ne veux pas entrer trop dans les détails de l'installation d'OPNsense, je l'ai déjà documentée dans le [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}).
Après l'installation des deux instances OPNsense, j'attribue à chacune leur IP sur le réseau _Mgmt_ :
- `cerbere-head1` : `192.168.88.2/24`
- `cerbere-head2` : `192.168.88.3/24`
Tant que ces routeurs ne gèrent pas encore les réseaux, je leur donne comme passerelle mon routeur OPNsense actuel (`192.168.88.1`) pour me permettre de les atteindre depuis mon portable dans un autre VLAN.
---
## Configuration d'OPNsense
Initialement, j'envisageais de restaurer ma configuration OPNsense existante et de l'adapter à l'installation.
Puis j'ai décidé de repartir de zéro pour documenter et partager la procédure. Cette partie devenant trop longue, j'ai préféré créer un article dédié.
📖 Vous pouvez trouver les détails de la configuration complète d'OPNsense dans cet [article]({{< ref "post/13-opnsense-full-configuration" >}}), couvrant HA, DNS, DHCP, VPN et reverse proxy.
---
## VM Proxmox Hautement Disponible
Les ressources (VM ou LXC) dans Proxmox VE peuvent être marquées comme hautement disponibles, voyons comment les configurer.
### Prérequis pour la HA Proxmox
D'abord, votre cluster Proxmox doit le permettre. Il y a quelques exigences :
- Au moins 3 nœuds pour avoir le quorum
- Stockage partagé pour vos ressources
- Horloge synchronisée
- Réseau fiable
Un mécanisme de fencing doit être activé. Le fencing est le processus d'isoler un nœud de cluster défaillant pour s'assurer qu'il n'accède plus aux ressources partagées. Cela évite les situations de split-brain et permet à Proxmox HA de redémarrer en toute sécurité les VM affectées sur des nœuds sains. Par défaut, il utilise le watchdog logiciel Linux, _softdog_, suffisant pour moi.
Dans Proxmox VE 8, il était possible de créer des groupes HA, en fonction de leurs ressources, emplacements, etc. Cela a été remplacé, dans Proxmox VE 9, par des règles d'affinité HA. C'est la raison principale derrière la mise à niveau de mon cluster Proxmox VE, que j'ai détaillée dans ce [post]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}).
### Configurer la HA pour les VM
Le cluster Proxmox est capable de fournir de la HA pour les ressources, mais vous devez définir les règles.
Dans `Datacenter` > `HA`, vous pouvez voir le statut et gérer les ressources. Dans le panneau `Resources` je clique sur `Add`. Je dois choisir la ressource à configurer en HA dans la liste, ici `cerbere-head1` avec l'ID 122. Puis dans l'infobulle je peux définir le maximum de redémarrages et de relocations, je laisse `Failback` activé et l'état demandé à `started` :
![Créer une ressource HA dans Proxmox](images/proxmox-add-vm-ha.png)
Le cluster Proxmox s'assurera maintenant que cette VM est démarrée. Je fais de même pour l'autre VM OPNsense, `cerbere-head2`.
### Règles d'Affinité HA
Super, mais je ne veux pas qu'elles tournent sur le même nœud. C'est là qu'intervient la nouvelle fonctionnalité des règles d'affinité HA de Proxmox VE 9. Proxmox permet de créer des règles d'affinité de nœud et de ressource. Peu m'importe sur quel nœud elles tournent, mais je ne veux pas qu'elles soient ensemble. J'ai besoin d'une règle d'affinité de ressource.
Dans `Datacenter` > `HA` > `Affinity Rules`, j'ajoute une nouvelle règle d'affinité de ressource HA. Je sélectionne les deux VMs et choisis l'option `Keep Separate` :
![Créer une affinité de ressource HA dans Proxmox](images/proxmox-ha-resource-affinity-rule.png)
✅ Mes VMs OPNsense sont maintenant entièrement prêtes !
---
## Migration
🚀 Il est temps de rendre cela réel !
Je ne vais pas mentir, je suis assez excité. Je travaille pour ce moment depuis des jours.
### Le Plan de Migration
Ma box OPNsense physique est directement connectée à ma box FAI. Je veux la remplacer par le cluster de VM. (Pour éviter d'écrire le mot OPNsense à chaque ligne, j'appellerai simplement l'ancienne instance "la box" et la nouvelle "la VM" )
Voici le plan :
1. Sauvegarde de la configuration de la box.
2. Désactiver le serveur DHCP sur la box.
3. Changer les adresses IP de la box.
4. Changer les VIP sur la VM.
5. Désactiver la passerelle sur la VM.
6. Configurer le DHCP sur les deux VMs.
7. Activer le répéteur mDNS sur la VM.
8. Répliquer les services sur la VM.
9. Déplacement du câble Ethernet.
### Stratégie de Retour Arrière
Aucune. 😎
Je plaisante, le retour arrière consiste à restaurer la configuration de la box, arrêter les VMs OPNsense et rebrancher le câble Ethernet dans la box.
### Plan de vérification
Pour valider la migration, je dresse une checklist :
1. Bail DHCP WAN dans la VM.
2. Ping depuis mon PC vers le VIP du VLAN User.
3. Ping entre les VLANs.
4. SSH vers mes machines.
5. Renouveler le bail DHCP.
6. Vérifier `ipconfig`
7. Tester l'accès à des sites internet.
8. Vérifier les logs du pare-feu.
9. Vérifier mes services web.
10. Vérifier que mes services internes ne sont pas accessibles depuis l'extérieur.
11. Tester le VPN.
12. Vérifier tous les appareils IoT.
13. Vérifier les fonctionnalités Home Assistant.
14. Vérifier que la TV fonctionne.
15. Tester le Chromecast.
16. Imprimer quelque chose.
17. Vérifier la blocklist DNS.
18. Speedtest.
19. Bascule.
20. Failover.
21. Reprise après sinistre.
22. Champagne !
Est-ce que ça va marcher ? On verra bien !
### Étapes de Migration
1. **Sauvegarde de la configuration de la box.**
Sur mon instance OPNsense physique, dans `System` > `Configuration` > `Backups`, je clique sur le bouton `Download configuration` qui me donne le précieux fichier XML. Celui qui m'a sauvé la mise la [dernière fois]({{< ref "post/10-opnsense-crash-disk-panic" >}}).
2. **Désactiver le serveur DHCP sur la box.**
Dans `Services` > `ISC DHCPv4`, et pour toutes mes interfaces, je désactive le serveur DHCP. Je ne fournis que du DHCPv4 dans mon réseau.
3. **Changer les adresses IP de la box.**
Dans `Interfaces`, et pour toutes mes interfaces, je modifie l'IP du firewall, de `.1` à `.253`. Je veux réutiliser la même adresse IP comme VIP, et garder cette instance encore joignable si besoin.
Dès que je clique sur `Apply`, je perds la communication, ce qui est attendu.
4. **Changer les VIP sur la VM.**
Sur ma VM maître, dans `Interfaces` > `Virtual IPs` > `Settings`, je change l'adresse VIP pour chaque interface et la mets en `.1`.
5. **Désactiver la passerelle sur la VM.**
Dans `System` > `Gateways` > `Configuration`, je désactive `LAN_GW` qui n'est plus nécessaire.
6. **Configurer le DHCP sur les deux VMs.**
Sur les deux VMs, dans `Services` > `Dnsmasq DNS & DHCP`, j'active le service sur mes 5 interfaces.
7. **Activer le répéteur mDNS sur la VM.**
Dans `Services` > `mDNS Repeater`, j'active le service et j'active aussi le `CARP Failover`.
Le service ne démarre pas. Je verrai ce problème plus tard.
8. **Répliquer les services sur la VM.**
Dans `Système` > `High Availability` > `Status`, je clique sur le bouton `Synchronize and reconfigure all`.
9. **Déplacement du câble Ethernet.**
Physiquement dans mon rack, je débranche le câble Ethernet du port WAN (`igc0`) de ma box OPNsense physique et je le branche sur le port 15 de mon switch UniFi.
---
## Vérification
😮‍💨 Je prends une grande inspiration et commence la phase de vérification.
### Checklist
- ✅ Bail DHCP WAN dans la VM.
- ✅ Ping depuis mon PC vers le VIP du VLAN User.
- ⚠️ Ping entre VLANs.
Les pings fonctionnent, mais j'observe quelques pertes, environ 10 %.
- ✅ SSH vers mes machines.
- ✅ Renouvellement du bail DHCP.
- ✅ Vérifier `ipconfig`
- ❌ Tester un site internet. → ✅
Quelques sites fonctionnent, tout est incroyablement lent... Ça doit être le DNS. J'essaie de résoudre un domaine au hasard, ça marche. Mais je ne peux pas résoudre `google.com`. Je redémarre le service Unbound DNS, tout fonctionne maintenant. C'est toujours le DNS...
- ⚠️ Vérifier les logs du pare-feu.
Quelques flux sont bloqués, pas critique.
- ✅ Vérifier mes services web.
- ✅ Vérifier que mes services internes ne sont pas accessibles depuis l'extérieur.
- ✅ Tester le VPN.
- ✅ Vérifier tous les appareils IoT.
- ✅ Vérifier les fonctionnalités Home Assistant.
- ✅ Vérifier que la TV fonctionne.
- ❌ Tester le Chromecast.
C'est lié au service mDNS qui ne parvient pas à démarrer. Je peux le démarrer si je décoche l'option `CARP Failover`. Le Chromecast est visible maintenant. → ⚠️
- ✅ Imprimer quelque chose.
- ✅ Vérifier la blocklist DNS.
- ✅ Speedtest.
J'observe environ 15 % de diminution de bande passante (de 940Mbps à 825Mbps).
- ❌ Bascule.
La bascule fonctionne difficilement, beaucoup de paquets perdus pendant la bascule. Le service rendu n'est pas génial : plus d'accès internet et mes services web sont inaccessibles.
- ⌛ Failover.
- ⌛ Reprise après sinistre.
À tester plus tard.
📝 Bon, les résultats sont plutôt bons, pas parfaits, mais satisfaisants !
### Résolution des Problèmes
Je me concentre sur la résolution des problèmes restants rencontrés lors des tests.
1. **DNS**
Lors de la bascule, la connexion internet ne fonctionne pas. Pas de DNS, c'est toujours le DNS.
C'est parce que le nœud de secours n'a pas de passerelle lorsqu'il est en mode passif. L'absence de passerelle empêche le DNS de résoudre. Après la bascule, il conserve des domaines non résolus dans son cache. Ce problème conduit aussi à un autre souci : quand il est passif, je ne peux pas mettre à jour le système.
**Solution** : Définir une passerelle pointant vers l'autre nœud, avec un numéro de priorité plus élevé que la passerelle WAN (un numéro plus élevé signifie une priorité plus basse). Ainsi, cette passerelle n'est pas active tant que le nœud est maître.
2. **Reverse Proxy**
Lors de la bascule, tous les services web que j'héberge (reverse proxy/proxy couche 4) renvoient cette erreur : `SSL_ERROR_INTERNAL_ERROR_ALERT`. Après vérification des services synchronisés via XMLRPC Sync, Caddy et mDNS repeater n'étaient pas sélectionnés. C'est parce que ces services ont été installés après la configuration initiale du HA.
**Solution** : Ajouter Caddy à XMLRPC Sync.
3. **Pertes de paquets**
J'observe environ 10 % de pertes de paquets pour les pings depuis n'importe quel VLAN vers le VLAN _Mgmt_. Je n'ai pas ce problème pour les autres VLANs.
Le VLAN _Mgmt_ est le VLAN natif dans mon réseau, cela pourrait être la raison de ce problème. C'est le seul réseau non défini dans le SDN Proxmox. Je ne veux pas avoir à tagger ce VLAN.
**Solution** : Désactiver le pare-feu Proxmox de cette interface pour la VM. En réalité, je les ai tous désactivés et mis à jour la documentation ci-dessus. Je ne sais pas exactement pourquoi cela causait ce type de problème, mais la désactivation a résolu mon souci (j'ai pu reproduire le comportement en réactivant le pare-feu).
4. **Script CARP**
Lors de la bascule, le script d'événement CARP est déclenché autant de fois qu'il y a d'interfaces. J'ai 5 IPs virtuelles, le script reconfigure mon interface WAN 5 fois.
**Solution** : Retravailler le script pour récupérer l'état de l'interface WAN et ne reconfigurer l'interface que lorsque c'est nécessaire :
```php
#!/usr/local/bin/php
<?php
/**
* OPNsense CARP event script
* - Enables/disables the WAN interface only when needed
* - Avoids reapplying config when CARP triggers multiple times
*/
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
// Read CARP event arguments
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
// Accept only MASTER/BACKUP events
if (!in_array($type, ['MASTER', 'BACKUP'])) {
// Ignore CARP INIT, DEMOTED, etc.
exit(0);
}
// Validate subsystem name format, expected pattern: <ifname>@<vhid>
if (!preg_match('/^[a-z0-9_]+@\S+$/i', $subsystem)) {
log_error("Malformed subsystem argument: '{$subsystem}'.");
exit(0);
}
// Interface key to manage
$ifkey = 'wan';
// Determine whether WAN interface is currently enabled
$ifkey_enabled = !empty($config['interfaces'][$ifkey]['enable']) ? true : false;
// MASTER event
if ($type === "MASTER") {
// Enable WAN only if it's currently disabled
if (!$ifkey_enabled) {
log_msg("CARP event: switching to '$type', enabling interface '$ifkey'.", LOG_WARNING);
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_msg("CARP event: already '$type' for interface '$ifkey', nothing to do.");
}
// BACKUP event
} else {
// Disable WAN only if it's currently enabled
if ($ifkey_enabled) {
log_msg("CARP event: switching to '$type', disabling interface '$ifkey'.", LOG_WARNING);
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_msg("CARP event: already '$type' for interface '$ifkey', nothing to do.");
}
}
```
5. **mDNS Repeater**
Le répéteur mDNS ne veut pas démarrer quand je sélectionne l'option `CARP Failover`.
**Solution** : La machine nécessite un redémarrage pour démarrer ce service compatible CARP.
6. **Adresse IPv6**
Mon nœud `cerbere-head1` crie dans le fichier de logs tandis que l'autre ne le fait pas. Voici les messages affichés chaque seconde quand il est maître :
```plaintext
Warning rtsold <interface_up> vtnet1 is disabled. in the logs (OPNsense)
```
Un autre message que j'ai plusieurs fois après un switchback :
```plaintext
Error dhcp6c transmit failed: Can't assign requested address
```
Ceci est lié à IPv6. J'observe que mon nœud principal n'a pas d'adresse IPv6 globale, seulement une link-local. De plus, il n'a pas de passerelle IPv6. Mon nœud secondaire, en revanche, a à la fois l'adresse globale et la passerelle.
Je ne suis pas expert IPv6, après quelques heures de recherche, j'abandonne IPv6. Si quelqu'un peut m'aider, ce serait vraiment apprécié !
**Contournement** : Supprimer DHCPv6 pour mon interface WAN.
### Confirmation
Maintenant que tout est corrigé, je peux évaluer les performances du failover.
1. **Basculement**
En entrant manuellement en mode maintenance CARP depuis l'interface WebGUI, aucune perte de paquets n'est observée. Impressionnant.
2. **Failover**
Pour simuler un failover, je tue la VM OPNsense active. Ici j'observe une seule perte de paquet. Génial.
![Test de ping pendant le CARP failover d'OPNsense](images/opnsense-ping-failover.png)
3. **Reprise après sinistre**
Une reprise après sinistre est ce qui se produirait après un arrêt complet d'un cluster Proxmox, suite à une coupure de courant par exemple. Je n'ai pas eu le temps (ni le courage) de m'en occuper, je préfère mieux me préparer pour éviter les dommages collatéraux. Mais il est certain que ce genre de scénario doit être évalué.
### Avantages Supplémentaires
Outre le fait que cette nouvelle configuration est plus résiliente, j'ai constaté quelques autres avantages.
Mon rack est minuscule et l'espace est restreint. L'ensemble chauffe beaucoup, dépassant les 40 °C au sommet du rack en été. Réduire le nombre de machines allumées a permis de faire baisser la température. J'ai gagné 1,5 °C après avoir éteint l'ancien boîtier OPNsense, c'est super !
La consommation électrique est également un point important, mon petit datacenter consommait en moyenne 85 W. Là encore, j'ai constaté une légère baisse, d'environ 8 W. Sachant que le système fonctionne 24/7, ce n'est pas négligeable.
Enfin, j'ai également retiré le boîtier lui-même et le câble d'alimentation. Les places sont très limitées, ce qui est un autre point positif.
---
## Conclusion
🎉 J'ai réussi les gars ! Je suis très fier du résultat, et fier de moi.
De mon [premier crash de ma box OPNsense]({{< ref "post/10-opnsense-crash-disk-panic" >}}), à la recherche d'une solution, en passant par la [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) de haute disponibilité, jusqu'à cette migration, ce fut un projet assez long, mais extrêmement intéressant.
🎯 Se fixer des objectifs, c'est bien, mais les atteindre, c'est encore mieux.
Je vais maintenant mettre OPNsense de côté un petit moment pour me recentrer sur mon apprentissage de Kubernetes !
Comme toujours, si vous avez des questions, des remarques ou une solution à mon problème d'IPv6, je serai ravi de vous aider.
@@ -0,0 +1,421 @@
---
slug: migration-opnsense-proxmox-highly-available
title: Migration of my OPNsense HA Cluster in Proxmox VE
description: The detailed steps of the migration from my OPNsense physical box to a highly available cluster of VM in Proxmox VE.
date: 2025-11-20
draft: false
tags:
- opnsense
- high-availability
- proxmox
categories:
- homelab
image: cover-15.webp
---
## Intro
This is the final stage of my **OPNsense** virtualization journey.
A few months ago, my physical [OPNsense box crashed]({{< ref "post/10-opnsense-crash-disk-panic" >}}) because of a hardware failure. This leads my home in the dark, literally. No network, no lights.
💡 To avoid being in that situation again, I imagined a plan to virtualize my OPNsense firewall into my **Proxmox VE** cluster. The last time, I've set up a [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) to validate this solution: create a cluster of two **OPNsense** VMs in Proxmox and make the firewall highly available.
This time, I will cover the creation of my future OPNsense cluster from scratch, plan the cut over and finally migrate from my current physical box. Let's go!
---
## The VLAN Configuration
For my plans, I'll have to connect the WAN, coming from my ISP box, to my main switch. For that I create a dedicated VLAN to transport this flow to my Proxmox nodes.
### UniFi
First, I configure my layer 2 network which is managed by UniFi. There I need to create two VLANs:
- *WAN* (20): transport the WAN between my ISP box and my Proxmox nodes.
- *pfSync* (44), communication between my OPNsense nodes.
In the UniFi controller, in `Settings` > `Networks`, I add a `New Virtual Network`. I name it `WAN` and give it the VLAN ID 20:
![Creation of the WAN VLAN in the UniFi Controller](images/unifi-add-vlan-for-wan.png)
I do the same thing again for the `pfSync` VLAN with the VLAN ID 44.
I plan to plug my ISP box on the port 15 of my switch, which is disabled for now. I set it as active, set the native VLAN on the newly created one `WAN (20)` and disable trunking:
![Configuration of the UniFi switch port for the WAN uplink](images/unifi-enable-port-wan-vlan.png)
Once this setting applied, I make sure that only the ports where are connected my Proxmox nodes propagate these VLAN on their trunk.
I'm done with UniFi configuration.
### Proxmox SDN
Now that the VLAN can reach my nodes, I want to handle it in the Proxmox SDN. I've configured the SDN in [that article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}).
In `Datacenter` > `SDN` > `VNets`, I create a new VNet, call it `vlan20` to follow my own naming convention, give it the *WAN* alias and use the tag (VLAN ID) 20:
![Creation of the VNet for the WAN in the Proxmox SDN](images/proxmox-sdn-new-vnet-wan.png)
I also create the `vlan44` for the *pfSync* VLAN, then I apply this configuration and we are done with the SDN.
---
## Create the VMs
Now that the VLAN configuration is done, I can start buiding the virtual machines on Proxmox.
The first VM is named `cerbere-head1` (I didn't tell you? My current firewall is named `cerbere`, it makes even more sense now!). Here are the settings:
- **OS type**: Linux (even if OPNsense is based on FreeBSD)
- **Machine type**: `q35`
- **BIOS**: `OVMF (UEFI)`
- **Disk**: 20 GB on Ceph distributed storage
- **RAM**: 4 GB RAM, ballooning disabled
- **CPU**: 2 vCPU
- **NICs**, firewall disabled:
1. `vmbr0` (*Mgmt*)
2. `vlan20` (*WAN*)
3. `vlan13` *(User)*
4. `vlan37` *(IoT)*
5. `vlan44` *(pfSync)*
6. `vlan55` *(DMZ)*
7. `vlan66` *(Lab)*
![Hardware settings of the OPNsense VM in Proxmox](images/proxmox-cerbere-vm-settings.png)
ℹ️ Now I clone that VM to create `cerbere-head2`, then I proceed with OPNsense installation. I don't want to go into much details about OPNsense installation, I already documented it in the [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}).
After the installation of both OPNsense instances, I give to each of them their IP in the *Mgmt* network:
- `cerbere-head1`: `192.168.88.2/24`
- `cerbere-head2`: `192.168.88.3/24`
I give them the other OPNsense node as gateway (`192.168.88.1`) to allow me to reach them from my laptop in another VLAN.
---
## Configure OPNsense
Initially, I considered restoring my existing OPNsense configuration and adapt it to the setup.
Then I decided to start over to document and share it. This part was getting so long that I prefered create a dedicated post instead.
📖 You can find the details of the full OPNsense configuration in that [article]({{< ref "post/13-opnsense-full-configuration" >}}), covering HA, DNS, DHCP, VPN and reverse proxy.
---
## Proxmox VM High Availability
Resources (VM or LXC) in Proxmox VE can be tagged as highly available, let see how to set it up.
### Proxmox HA Requirements
First, your Proxmox cluster must allow it. There are some requirements:
- At least 3 nodes to have quorum
- Shared storage for your resources
- Time synchronized
- Reliable network
A fencing mechanism must be enabled. Fencing is the process of isolating a failed cluster node to ensure it no longer accesses shared resources. This prevents split-brain situations and allows Proxmox HA to safely restart affected VMs on healthy nodes. By default, it is using Linux software watchdog, *softdog*, good enough for me.
In Proxmox VE 8, It was possible to create HA groups, depending of their resources, locations, etc. This has been replaced, in Proxmox VE 9, by HA affinity rules. This is actually the main reason behind my Proxmox VE cluster upgrade, which I've detailed in that [post]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}).
### Configure VM HA
The Proxmox cluster is able to provide HA for the resources, but you need to define the rules.
In `Datacenter` > `HA`, you can see the status and manage the resources. In the `Resources` panel I click on `Add`. I need to pick the resource to configure as HA in the list, here `cerbere-head1` with ID 122. Then in the tooltip I can define the maximum of restart and relocate, I keep `Failback` enabled and the requested state to `started`:
![Create HA resource in Proxmox](images/proxmox-add-vm-ha.png)
The Proxmox cluster will now make sure this VM is started. I do the same for the other OPNsense VM, `cerbere-head2`.
### HA Affinity Rules
Great, but I don't want them on the same node. This is when the new feature HA affinity rules, of Proxmox VE 9, come in. Proxmox allows to create node affinity and resource affinity rules. I don't mind on which node they run, but I don't want them together. I need a resource affinity rule.
In `Datacenter` > `HA` > `Affinity Rules`, I add a new HA resource affinity rule. I select both VMs and pick the option `Keep Separate`:
![Create HA resource affinity in Proxmox](images/proxmox-ha-resource-affinity-rule.png)
✅ My OPNsense VMs are now fully ready!
---
## Migration
🚀 Time to make it real!
I'm not gonna lie, I'm quite excited. I'm working for this moment for days.
### The Migration Plan
I have my physical OPNsense box directly connected to my ISP box. I want to swap it for the VM cluster. (To avoid writing the word OPNsense on each line, I'll simply name it "the box" and "the VM")
Here is the plan:
1. Backup of the box configuration.
2. Disable DHCP server on the box.
3. Change IP addresses of the box.
4. Change VIP on the VM.
5. Disable gateway on VM.
6. Configure DHCP on both VMs.
7. Enable mDNS repeater on VM.
8. Replicate services on VM.
9. Move of the Ethernet cable.
### Rollback Strategy
None. 😎
I'm kidding, the rollback consists of restoring the box configuration, shutdown the OPNsense VMs and plug back the Ethernet cable into the box.
### Verification Plan
To validate the migration, I'm drawing up a checklist:
1. WAN DHCP lease in the VM.
2. Ping from my PC to the VIP of the User VLAN.
3. Ping cross VLAN.
4. SSH into my machines.
5. Renew DHCP lease.
6. Check `ipconfig`
7. Test internet website.
8. Check firewall logs.
9. Check my webservices.
10. Verify if my internal webservices are not accessible from outside.
11. Test VPN.
12. Check all IoT devices.
13. Check Home Assistant features.
14. Check if the TV works.
15. Test the Chromecast.
16. Print something.
17. Verify DNS blocklist.
18. Speedtest.
19. Switchover.
20. Failover.
21. Disaster Recovery.
22. Champaign!
Will it work? Let's find out!
### Migration Steps
1. **Backup of the box configuration.**
On my physical OPNsense instance, in `System` > `Configuration` > `Backups`, I click the `Download configuration` button which give me the precious XML file. The one that saved my ass the [last time]({{< ref "post/10-opnsense-crash-disk-panic" >}}).
2. **Disable DHCP server on the box.**
In `Services` > `ISC DHCPv4`, and for all my interfaces, I disable the DHCP server. I only serve DHCPv4 in my network.
3. **Change IP addresses of the box.**
In `Interfaces`, and for all my interfaces, I modify the IP of the firewall, from `.1` to `.253`. I want to reuse the same IP address as VIP, and have this instance still reachable if needed.
As soon as I click on `Apply`, I lost the communication, which is expected.
4. **Change VIP on the VM.**
On my master VM, In `Interfaces` > `Virtual IPs` > `Settings`, I change the VIP address for each interface and set it to `.1`.
5. **Disable gateway on VM.**
In `System` > `Gateways` > `Configuration`, I disable the `LAN_GW` which is not needed anymore.
6. **Configure DHCP on both VMs.**
In both VM, in `Services` > `Dnsmasq DNS & DHCP`, I enable the service on my 5 interfaces.
7. **Enable mDNS repeater on VM.**
In `Services` > `mDNS Repeater`, I enable the service and also enable CARP Failover.
The service does not start. I'll see that problem later.
8. **Replicate services on VM.**
In `System` > `High Availability` > `Status`, I click the button to `Synchronize and reconfigure all`.
9. **Move of the Ethernet cable.**
Physically in my rack, I unplug the Ethernet cable from the WAN port (`igc0`) of my physical OPNsense box and plug it into the port 15 of my UniFi switch.
---
## Verification
😮‍💨 I take a deep breath and start the verification phase.
### Checklist
- ✅ WAN DHCP lease in the VM.
- ✅ Ping from my PC to the VIP of the User VLAN.
- ⚠️ Ping cross VLAN.
Pings are working, but I observe some drops, about 10%.
- ✅ SSH into my machines.
- ✅ Renew DHCP lease.
- ✅ Check `ipconfig`
- ❌ Test internet website. → ✅
A few websites are working, everything is incredibly slow... It must be the DNS. I try to lookup a random domain, it is working. But I can't lookup `google.com`. I restart the Unbound DNS service, everything works now. It is always the DNS...
- ⚠️ Check firewall logs.
Few flows are blocks, not mandatory.
- ✅Check my webservices.
- ✅Verify if my internal webservices are not accessible from outside.
- ✅ Test VPN.
- ✅ Check all IoT devices.
- ✅ Check Home Assistant features.
- ✅Check if the TV works.
- ❌ Test the Chromecast.
It is related to the mDNS service not able to start. I can start it if I uncheck the `CARP Failover` option. the Chromecast is visible now. → ⚠️
- ✅Print something.
- ✅Verify DNS blocklist.
- ✅Speedtest.
I observe roughly 15% of decrease bandwidth (from 940Mbps to 825Mbps).
- ❌ Switchover.
The switchover barely works, a lot of dropped packets during the switch. The service provided is not great: no more internet and my webservices are not reachable.
- ⌛ Failover.
- ⌛ Disaster Recovery.
To be tested later.
📝 Well, the results are pretty good, not perfect, but satisfying!
### Problem Solving
I focus on resolving remaining problems experienced during the tests.
1. **DNS**
During the switchover, the internet connection is not working. No DNS, it is always DNS.
It's because the backup node does not have a gateway while passive. No gateway prevents the DNS to resolve. After the switchover, it still has unresolved domains in its cache. This problem also lead to another issue, while passive, I can't update the system.
**Solution**: Create a gateway pointing to the other node, with a higher priority number than the WAN gateway (higher number means lower priority). This way, that gateway is not active while the node is master.
2. **Reverse Proxy**
During the switchover, every webservices which I host (reverse proxy/layer 4 proxy) give this error: `SSL_ERROR_INTERNAL_ERROR_ALERT`. After checking the services synchronized throught XMLRPC Sync, Caddy and mDNS repeater were not selected. It is because these services were installed after the initial configuration of the HA.
**Solution**: Add Caddy to XMLRPC Sync.
3. **Packet Drops**
I observe about 10% packet drops for pings from any VLAN to the *Mgmt* VLAN. I don't have this problem for the other VLANs.
The *Mgmt* VLAN is the native one in my network, it might be the reason behind this issue. This is the only network not defined in the Proxmox SDN. I don't want to have to tag this VLAN.
**Solution**: Disable the Proxmox firewall of this interface for the VM. I actually disable them all and update the documentation above. I'm not sure why this cause that kind of problem, but disabling it fixed my issue (I could reproduce the behavior while activating the firewall again).
4. **CARP Script**
During a switchover, the CARP event script is triggered as many times as the number of interfaces. I have 5 virtual IPs, the script reconfigure my WAN interface 5 times.
**Solution**: Rework the script to get the WAN interface state and only reconfigure the inteface when needed:
```php
#!/usr/local/bin/php
<?php
/**
* OPNsense CARP event script
* - Enables/disables the WAN interface only when needed
* - Avoids reapplying config when CARP triggers multiple times
*/
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("system.inc");
// Read CARP event arguments
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';
// Accept only MASTER/BACKUP events
if (!in_array($type, ['MASTER', 'BACKUP'])) {
// Ignore CARP INIT, DEMOTED, etc.
exit(0);
}
// Validate subsystem name format, expected pattern: <ifname>@<vhid>
if (!preg_match('/^[a-z0-9_]+@\S+$/i', $subsystem)) {
log_error("Malformed subsystem argument: '{$subsystem}'.");
exit(0);
}
// Interface key to manage
$ifkey = 'wan';
// Determine whether WAN interface is currently enabled
$ifkey_enabled = !empty($config['interfaces'][$ifkey]['enable']) ? true : false;
// MASTER event
if ($type === "MASTER") {
// Enable WAN only if it's currently disabled
if (!$ifkey_enabled) {
log_msg("CARP event: switching to '$type', enabling interface '$ifkey'.", LOG_WARNING);
$config['interfaces'][$ifkey]['enable'] = '1';
write_config("enable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_msg("CARP event: already '$type' for interface '$ifkey', nothing to do.");
}
// BACKUP event
} else {
// Disable WAN only if it's currently enabled
if ($ifkey_enabled) {
log_msg("CARP event: switching to '$type', disabling interface '$ifkey'.", LOG_WARNING);
unset($config['interfaces'][$ifkey]['enable']);
write_config("disable interface '$ifkey' due CARP event '$type'", false);
interface_configure(false, $ifkey, false, false);
} else {
log_msg("CARP event: already '$type' for interface '$ifkey', nothing to do.");
}
}
```
5. **mDNS Repeater**
The mDNS repeater does not want to start when I select the option for `CARP Failover`.
**Solution**: The machine requires a reboot to start this service CARP aware.
6. **IPv6 Address**
My `cerbere-head1` node is crying in the log file while the other does not. Here are the messages spit every seconds while it is master:
```plaintext
Warning rtsold <interface_up> vtnet1 is disabled. in the logs (OPNsense)
```
Another one I'm having several times after a switchback:
```plaintext
Error dhcp6c transmit failed: Can't assign requested address
```
This is related to IPv6. I observe that my main node does not have a global IPv6 address, only a link-local. Also, it does not have a IPv6 gateway. My secondary node, in the other hand, has both addresses and the gateway.
I'm no IPv6 expert, after searching for a couple of hours, I give up the IPv6. If someone out here can help, it would be really appreciated!
**Workaround**: Remove DHCPv6 for my WAN interface.
### Confirmation
Now that everything is fixed, I can evaluate the failover performance.
1. **Switchover**
When manually entering CARP maintenance mode from the WebGUI interface, no packet drop is observed. Impressive.
2. **Failover**
To simulate a failover, I kill the active OPNsense VM. Here I observe only one packet dropped. Awesome.
![Ping test during OPNsense CARP failover](images/opnsense-ping-failover.png)
3. **Disaster Recovery**
A disaster recovery is what would happen after a full Proxmox cluster stop, after an electrical outage for example. I didn't have the time (or the courage) to do that, I'd prefer to prepare a bit better to avoid collateral damages. But surely, this kind of scenario must be evaluated.
### Extras Benefits
Leaving aside the fact that this new setup is more resilient, I have few more bonuses.
My rack is tiny and the space is tight. The whole thing is heating quite much, exceeding 40°C on top of the rack in summer. Reducing the number of machines powered up lower the temperature. I've gained **1,5°C** after shutting down the old OPNsense box, cool!
Power consumption is also a concern, my tiny datacenter was drawing 85W on average. Here again I could observe a small decrease, about 8W lower. Considering that this run 24/7, not negligible.
Finally I also removed the box itself and the power cable. Slots are very limited, another good point.
---
## Conclusion
🎉 I did it guys! I'm very proud of the results, proud of myself.
From my [first OPNsense box crash]({{< ref "post/10-opnsense-crash-disk-panic" >}}), the thinking about a solution, the HA [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}), to this migration. This has been a quite long project, but extremly interesting.
🎯 This is great to set objectives, but this is even better when you reach them.
Now I'm going to leave OPNsense aside for a bit, to be able to re-focus on my Kubernetes journey!
As always, if you have questions, remarks or a solution for my IPv6 problem, I'll be really happy to share with you.

Some files were not shown because too many files have changed in this diff Show More