Compare commits

..

14 Commits

Author SHA1 Message Date
02ee9aea80 Finished first project!
All checks were successful
Build and Publish Web / build (push) Successful in 8s
2026-03-25 10:28:47 +01:00
23ec1fdf80 Make gray more light 2026-03-25 10:16:39 +01:00
ef8a22d55b Improved category for block setup
All checks were successful
Build and Publish Web / build (push) Successful in 15s
2026-03-25 10:00:05 +01:00
5aa3612cdd Changed categories and tags, added warning. 2026-03-25 09:56:12 +01:00
9adf6f55a2 Added some support for tags and categories 2026-03-25 09:44:46 +01:00
604d301a1c Added License 2026-03-25 08:40:56 +01:00
956b284d4b Fix: Added missing delete to workflow 2026-03-25 08:31:12 +01:00
0a4b1a24f7 Show 4 projects and articles at home screen 2026-03-25 08:28:37 +01:00
de2044343d Added Gitea link to footer 2026-03-25 08:21:20 +01:00
b8b7baee0f Dropped domain prefixes and unified container and network names 2026-03-25 08:19:20 +01:00
162fbabd26 Fix: Delete old package before upload
All checks were successful
Build and Publish Web / build (push) Successful in 15s
2026-03-24 22:41:33 +01:00
9702741bbe Finished workflow (I hope)
All checks were successful
Build and Publish Web / build (push) Successful in 1m8s
2026-03-24 22:32:29 +01:00
9c9db094a0 Added article about auto release updates 2026-03-24 22:32:21 +01:00
ac62e53698 Make public 2026-03-24 22:31:50 +01:00
13 changed files with 317 additions and 73 deletions

View File

@@ -27,18 +27,26 @@ jobs:
cd themes/minimal-black cd themes/minimal-black
npm install npm install
cd ../.. cd ../..
hugo --minify hugo --minify -b "https://jirkabuilds.dev/"
- name: Packaging ZIP - name: Packaging ZIP
run: | run: |
cd public cd public
zip -r ../build.zip ./* zip -r ../build.zip ./*
- name: Delete old package (if exists)
run: |
curl -X DELETE --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip" || true
- name: Uploading package back to gitea - name: Uploading package back to gitea
run: | run: |
curl --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \ curl -f --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
--upload-file build.zip \ --upload-file build.zip \
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip" "https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip"
# TODO - Webhook - name: Trigger Webhook
run: |
curl -X POST "https://hooks.jirkabuilds.dev/hooks/deploy-web" \
-H "X-Deploy-Token: ${{ secrets.WEBHOOK_SECRET }}"

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 JirkaBuilds
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -13,3 +13,10 @@ hugo new projects/{article_name}.md
``` ```
Then just edit `*/{article_name}.md` and add content. Then just edit `*/{article_name}.md` and add content.
## License
Unless otherwise stated, the source code of this website (HTML, CSS, JavaScript, Hugo configuration) is licensed under the **MIT License** (see the `LICENSE` file).
All blog content (article texts in the `/content` directory and photographs/images created by the author) is licensed under the **Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)**.

View File

@@ -4,12 +4,16 @@ draft: false
title: "Let's start a blog!" title: "Let's start a blog!"
author: "Jirka" author: "Jirka"
tags: ["hugo", "idea", "guide", "tutorial"] tags: ["hugo", "idea", "guide", "tutorial"]
categories: ["blog", "idea"] categories: ["Blog setup", "idea"]
description: "Behind the scenes of the idea and setup." description: "Behind the scenes of the idea and setup."
--- ---
This blog has been created as one of my personal projects, first one released on this page. (Actually, this article, about creating this blog, is being written before creation of the blog and this page). This blog has been created as one of my personal projects, first one released on this page. (Actually, this article, about creating this blog, is being written before creation of the blog and this page).
> [!WARNING]
> If you decide to follow my steps, please, be careful and use your head. I do not guarantee they will work for you and do so at your own risk.
## How it started ## How it started
The original idea was simple: **I would like to share my projects and knowledge with others.** But how? The original idea was simple: **I would like to share my projects and knowledge with others.** But how?
@@ -36,7 +40,7 @@ This article is just about how to set up the Hugo for my purpose and how the con
## Hugo setup ## Hugo setup
Work with hugo is super simple, I've start with their official [guide](https://gohugo.io/getting-started/quick-start/), but I will cover basic steps here. Work with Hugo is super simple, I've start with their official [guide](https://gohugo.io/getting-started/quick-start/), but I will cover basic steps here.
To create empty Hugo project (after installing Hugo), start with: To create empty Hugo project (after installing Hugo), start with:
```bash ```bash
@@ -142,3 +146,6 @@ So I've created `layouts/_default/_markup/render-link.html` will follow content:
``` ```
It creates correct links just from file links and will warn me if anything will go wrong. It creates correct links just from file links and will warn me if anything will go wrong.
---
This article is one from series about this blog and self-hosting. All connected articles can found [here](categories/blog-setup).

View File

@@ -1,16 +1,19 @@
--- ---
date: '2026-03-24T10:17:21+01:00' date: '2026-03-24T10:17:21+01:00'
draft: false draft: false
title: 'Hosting Blog' title: 'How to self-host a blog'
author: "Jirka" author: "Jirka"
tags: ["caddy", "vps", "wireguard", "docker", "guide", "tutorial"] tags: ["caddy", "docker", "wireguard", "vps", "guide", "tutorial", "self-hosted"]
categories: ["blog", "self-hosting"] categories: ["Blog setup"]
description: "How this blog came online." description: "How this blog came online without public IP."
--- ---
In last post [Let's start a blog!](./01-blog.md) I've introduced idea and how-to guide how I will write this blog, but left it offline. In last post [Let's start a blog!](./01-blog.md) I've introduced idea and how-to guide how I will write this blog, but left it offline.
That is going to change in this post. That is going to change in this post.
> [!WARNING]
> If you decide to follow my steps, please, be careful and use your head. I do not guarantee they will work for you and do so at your own risk.
## Requirements ## Requirements
This whole blog/website project is about self-hosting. That said, I will host this page my on server/PC at home. For that, you usually have public IP address. This whole blog/website project is about self-hosting. That said, I will host this page my on server/PC at home. For that, you usually have public IP address.
@@ -183,10 +186,10 @@ Let's start by creating `docker-compose.yml`:
```yaml docker-compose.yml ```yaml docker-compose.yml
# Shared network between containers (for later use) # Shared network between containers (for later use)
networks: networks:
jirkabuilds_proxy_network: proxy_network:
services: services:
jirkabuilds_wireguard: wireguard:
image: linuxserver/wireguard:latest image: linuxserver/wireguard:latest
container_name: wireguard container_name: wireguard
cap_add: cap_add:
@@ -199,13 +202,13 @@ services:
restart: unless-stopped restart: unless-stopped
# We will add wireguard to this network, but limit access from WG itself # We will add wireguard to this network, but limit access from WG itself
networks: networks:
- jirkabuilds_proxy_network - proxy_network
jirkabuilds_caddy: caddy:
image: caddy:latest image: caddy:latest
container_name: jirkabuilds_caddy container_name: caddy
# Caddy shares all networks with WireGuard # Caddy shares all networks with WireGuard
network_mode: "service:jirkabuilds_wireguard" network_mode: "service:wireguard"
volumes: volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile - ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./site_data:/srv - ./site_data:/srv
@@ -261,3 +264,6 @@ docker compose up -d
``` ```
And your web should be online. And your web should be online.
---
This article is one from series about this blog and self-hosting. All connected articles can found [here](categories/blog-setup).

View File

@@ -1,10 +1,10 @@
--- ---
date: '2026-03-24T18:48:40+01:00' date: '2026-03-24T18:48:40+01:00'
draft: true draft: false
title: 'Time for version control' title: 'Time for version control'
author: "Jirka" author: "Jirka"
tags: ["gitea", "self-hosted", "docker", "guide", "tutorial"] tags: ["gitea", "self-hosted", "docker", "guide", "tutorial"]
categories: ["self-host", "documentation"] categories: ["Blog setup"]
description: "Let's look at how to self host gitea on our infrastructure." description: "Let's look at how to self host gitea on our infrastructure."
--- ---
@@ -12,6 +12,9 @@ How would I share my projects with you, if I do not have any git hosting server?
That is a reason, why we need to set up one! You can choose from more variant, but I decided for [Gitea](https://about.gitea.com/). That is a reason, why we need to set up one! You can choose from more variant, but I decided for [Gitea](https://about.gitea.com/).
> [!WARNING]
> If you decide to follow my steps, please, be careful and use your head. I do not guarantee they will work for you and do so at your own risk.
## Self-hosting Gitea ## Self-hosting Gitea
Thanks to our earlier setup, next step is pretty simple. Thanks to our earlier setup, next step is pretty simple.
@@ -37,7 +40,7 @@ mv * web
Now create new `docker-compose.yml` file with following content: Now create new `docker-compose.yml` file with following content:
```yaml ```yaml
networks: networks:
jirkabuilds_proxy_network: proxy_network:
include: include:
- web/docker-compose.yml - web/docker-compose.yml
@@ -56,24 +59,24 @@ And you should be back online.
Create new directory `gitea` for Gitea and it's data an into it create new `docker-compose.yml` file with following content: Create new directory `gitea` for Gitea and it's data an into it create new `docker-compose.yml` file with following content:
```yaml ```yaml
networks: networks:
gitea-internal: gitea_internal:
jirkabuilds_proxy_network: proxy_network:
services: services:
jirkabuilds_gitea: gitea:
image: docker.gitea.com/gitea:latest image: docker.gitea.com/gitea:latest
container_name: jirkabuilds_gitea container_name: gitea
environment: environment:
- USER_UID=${APP_UID} - USER_UID=${APP_UID}
- USER_GID=${APP_GID} - USER_GID=${APP_GID}
- GITEA__database__DB_TYPE=postgres - GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=jirkabuilds_gitea_db:5432 - GITEA__database__HOST=gitea_db:5432
- GITEA__database__NAME=${DB_NAME} - GITEA__database__NAME=${DB_NAME}
- GITEA__database__USER=${DB_USER} - GITEA__database__USER=${DB_USER}
- GITEA__database__PASSWD=${DB_PASSWORD} - GITEA__database__PASSWD=${DB_PASSWORD}
restart: always restart: always
networks: networks:
- gitea-internal - gitea_internal
volumes: volumes:
- ./gitea:/data - ./gitea:/data
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
@@ -84,7 +87,7 @@ services:
depends_on: depends_on:
- db - db
jirkabuilds_gitea_db: gitea_db:
image: docker.io/library/postgres:14 image: docker.io/library/postgres:14
restart: always restart: always
environment: environment:
@@ -92,7 +95,7 @@ services:
- POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME} - POSTGRES_DB=${DB_NAME}
networks: networks:
- gitea-internal - gitea_internal
volumes: volumes:
- ./postgres:/var/lib/postgresql/data - ./postgres:/var/lib/postgresql/data
``` ```
@@ -122,35 +125,38 @@ When you finish initial setup, we can add Gitea to our stack. Start by editing G
There you should remove line with ports and port definition under Gitea service and add proxy network under networks. Changed part of the file should look like this: There you should remove line with ports and port definition under Gitea service and add proxy network under networks. Changed part of the file should look like this:
```yaml ```yaml
jirkabuilds_gitea: gitea:
image: docker.gitea.com/gitea:latest image: docker.gitea.com/gitea:latest
container_name: jirkabuilds_gitea container_name: gitea
environment: environment:
- USER_UID=${APP_UID} - USER_UID=${APP_UID}
- USER_GID=${APP_GID} - USER_GID=${APP_GID}
- GITEA__database__DB_TYPE=postgres - GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=jirkabuilds_gitea_db:5432 - GITEA__database__HOST=gitea_db:5432
- GITEA__database__NAME=${DB_NAME} - GITEA__database__NAME=${DB_NAME}
- GITEA__database__USER=${DB_USER} - GITEA__database__USER=${DB_USER}
- GITEA__database__PASSWD=${DB_PASSWORD} - GITEA__database__PASSWD=${DB_PASSWORD}
restart: always restart: always
networks: networks:
- gitea-internal - gitea_internal
- jirkabuilds_proxy_network - proxy_network
volumes: volumes:
- ./gitea:/data - ./gitea:/data
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
depends_on: depends_on:
- jirkabuilds_gitea_db - gitea_db
``` ```
Last step is to change `Caddyfile` in `web` folder. All you need to do is add following lines: Last step is to change `Caddyfile` in `web` folder. All you need to do is add following lines:
``` ```
git.jirkabuilds.dev { git.jirkabuilds.dev {
reverse_proxy jirkabuilds_gitea:3000 reverse_proxy gitea:3000
} }
``` ```
If you have set up DNS correctly, after shutting the stack down and up the Gitea should be online. If you have set up DNS correctly, after shutting the stack down and up the Gitea should be online.
And that's it! And that's it!
---
This article is one from series about this blog and self-hosting. All connected articles can found [here](categories/blog-setup).

View File

@@ -1,10 +1,10 @@
--- ---
date: '2026-03-24T20:36:26+01:00' date: '2026-03-24T20:36:26+01:00'
draft: true draft: false
title: 'Automatic web update release' title: 'Automatic web deployment'
author: "Jirka" author: "Jirka"
tags: ["self-host", "gitea", "automation"] tags: ["self-hosted", "gitea", "automation", "docker"]
categories: ["self-host", "documentation", "automation"] categories: ["Blog setup"]
description: "Last step, how to relase changes to web automatically" description: "Last step, how to relase changes to web automatically"
--- ---
@@ -14,6 +14,9 @@ The idea is simple, push changes to `master` branch of repo holding this web and
We will split this problem into two: Building web with Hugo and second, updating files with webhook. Let's start. We will split this problem into two: Building web with Hugo and second, updating files with webhook. Let's start.
> [!WARNING]
> If you decide to follow my steps, please, be careful and use your head. I do not guarantee they will work for you and do so at your own risk.
## Set up Gitea runner ## Set up Gitea runner
Gitea does support actions like GitHub, but you have to provide it runner to execute you tasks. We are going to use the most secured way, runner in docker, which will start another docker container in another docker. Gitea does support actions like GitHub, but you have to provide it runner to execute you tasks. We are going to use the most secured way, runner in docker, which will start another docker container in another docker.
@@ -27,37 +30,37 @@ I will store this token into `.env` file inside my `gitea` directory created in
Next we modify Gitea `docker-compose.yml` file to look as follows: Next we modify Gitea `docker-compose.yml` file to look as follows:
```yml ```yml
networks: networks:
jirka_builds_gitea_internal: gitea_internal:
jirkabuilds_proxy_network: proxy_network:
jirkabuilds_gitea_runner_net: # For runner dind comunication gitea_runner_net: # For runner dind comunication
jirkabuilds_gitea_net: # For runner gitea comunication, isolated from db gitea_net: # For runner gitea comunication, isolated from db
services: services:
jirkabuilds_gitea: gitea:
image: docker.gitea.com/gitea:latest image: docker.gitea.com/gitea:latest
container_name: jirkabuilds_gitea container_name: gitea
environment: environment:
- USER_UID=${APP_UID} - USER_UID=${APP_UID}
- USER_GID=${APP_GID} - USER_GID=${APP_GID}
- GITEA__database__DB_TYPE=postgres - GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=jirkabuilds_gitea_db:5432 - GITEA__database__HOST=gitea_db:5432
- GITEA__database__NAME=${DB_NAME} - GITEA__database__NAME=${DB_NAME}
- GITEA__database__USER=${DB_USER} - GITEA__database__USER=${DB_USER}
- GITEA__database__PASSWD=${DB_PASSWORD} - GITEA__database__PASSWD=${DB_PASSWORD}
restart: always restart: always
networks: networks:
- jirka_builds_gitea_internal - gitea_internal
- jirkabuilds_proxy_network - proxy_network
- jirkabuilds_gitea_net - gitea_net
volumes: volumes:
- ./gitea:/data - ./gitea:/data
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
depends_on: depends_on:
- jirkabuilds_gitea_db - gitea_db
jirkabuilds_gitea_db: gitea_db:
image: docker.io/library/postgres:14 image: docker.io/library/postgres:14
restart: always restart: always
environment: environment:
@@ -65,33 +68,33 @@ services:
- POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME} - POSTGRES_DB=${DB_NAME}
networks: networks:
- jirka_builds_gitea_internal - gitea_internal
volumes: volumes:
- ./postgres:/var/lib/postgresql/data - ./postgres:/var/lib/postgresql/data
# New # New
dind: dind:
image: docker:dind image: docker:dind
container_name: jirkabuilds-gitea-dind container_name: gitea-dind
restart: always restart: always
privileged: true privileged: true
environment: environment:
- DOCKER_TLS_CERTDIR=/certs - DOCKER_TLS_CERTDIR=/certs
volumes: volumes:
- jirkabuilds_dind_certs:/certs - dind_certs:/certs
- jirkabuilds_dind_data:/var/lib/docker - dind_data:/var/lib/docker
networks: networks:
jirkabuilds_gitea_runner_net: gitea_runner_net:
aliases: aliases:
- docker - docker
runner: runner:
image: gitea/act_runner:latest image: gitea/act_runner:latest
container_name: jirkabuilds-gitea-runner container_name: gitea-runner
restart: always restart: always
depends_on: depends_on:
- dind - dind
- jirkabuilds_gitea - gitea
environment: environment:
- GITEA_INSTANCE_URL=https://git.jirkabuilds.dev - GITEA_INSTANCE_URL=https://git.jirkabuilds.dev
- GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN} - GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN}
@@ -100,16 +103,16 @@ services:
- DOCKER_CERT_PATH=/certs/client - DOCKER_CERT_PATH=/certs/client
- DOCKER_TLS_VERIFY=1 - DOCKER_TLS_VERIFY=1
volumes: volumes:
- jirkabuilds_runner_data:/data - runner_data:/data
- jirkabuilds_dind_certs:/certs:ro - dind_certs:/certs:ro
networks: networks:
- jirkabuilds_gitea_net - gitea_net
- jirkabuilds_gitea_runner_net - gitea_runner_net
volumes: volumes:
jirkabuilds_dind_certs: dind_certs:
jirkabuilds_dind_data: dind_data:
jirkabuilds_runner_data: runner_data:
``` ```
And that is all, after `docker compose up -d`, runner should show up in the registry. And that is all, after `docker compose up -d`, runner should show up in the registry.
@@ -160,13 +163,124 @@ jobs:
cd public cd public
zip -r ../build.zip ./* zip -r ../build.zip ./*
# Need to delete old package first, otherwise new will not replace it
- name: Delete old package (if exists)
run: |
curl -X DELETE --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip" || true
- name: Uploading package back to gitea - name: Uploading package back to gitea
run: | run: |
curl --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \ curl -f --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
--upload-file build.zip \ --upload-file build.zip \
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/build.zip" "https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip"
# TODO - Webhook # TODO - Webhook
``` ```
This will automatically create package on push to master. This will automatically create package on push to master.
Now, once the package was successfully built, we can move onto the webhook.
## Webhook set up
For webhook, we will use `almir/webhook:latest` image, But because we need curl and zip, we will build it on our own.
Created `webhook` directory next to `web` directory and create `Dockerfile`:
```
FROM almir/webhook:latest
USER root
RUN apk add --no-cache curl unzip
WORKDIR /app
```
Next we will specify script, which will be executed on webhook trigger. Create file `deploy.sh` with `+x` privileges to be executable:
```bash
#!/bin/sh
set -e
TEMP_DIR=$(mktemp -d)
ZIP_PATH="$TEMP_DIR/web.zip"
curl -fL -o "$ZIP_PATH" "https://git.jirkabuilds.dev/api/packages/jirka/generic/hugo-build/latest/web.zip"
# Delete old web data
rm -rf /site_data/*
rm -rf /site_data/.[!.]* 2>/dev/null || true
unzip -q "$ZIP_PATH" -d /site_data/
rm -rf "$TEMP_DIR"
```
As you can see, we are downloading created package and replacing all site content.
Next step is to define hook itself. Create `hooks.json` file with following content:
```
[
{
"id": "deploy-web",
"execute-command": "/app/deploy.sh",
"command-working-directory": "/app",
"trigger-rule": {
"match": {
"type": "value",
"value": "secret token",
"parameter": {
"source": "header",
"name": "X-Deploy-Token"
}
}
}
}
]
```
You should create `secret`, which you will store to Gitea, same as with token earlier` with name `WEBHOOK_SECRET`. Thanks to it, only the workflow can trigger this webhook.
And last step is to create `docker-compose.yml`:
```
services:
webhook:
build: .
container_name: release_web_webhook
volumes:
- ./hooks.json:/etc/webhook/hooks.json:ro
- ./deploy.sh:/app/deploy.sh:ro
- ./../web/site_data:/site_data
command: ["-verbose", "-hooks=/etc/webhook/hooks.json", "-hotreload"]
restart: unless-stopped
networks:
- proxy_network
networks:
proxy_network:
```
You can see, we are using the same proxy network as for everything. Next step is to add following block to `Caddyfile`:
```
hooks.jirkabuilds.dev {
reverse_proxy release_web_webhook:9000
}
```
And following line to our root `docker-compose.yml`
```
- webhook/docker-compose.yml
```
Now you can restart the stack and webhook should work.
Final last step is to replace #TODO in our workflow with following:
```
- name: Trigger Webhook
run: |
curl -X POST "https://hooks.jirkabuilds.dev/hooks/deploy-web" \
-H "X-Deploy-Token: ${{ secrets.WEBHOOK_SECRET }}"
```
And that is it. On next push, web should update itself automatically.
---
This article is one from series about this blog and self-hosting. All connected articles can found [here](categories/blog-setup).

View File

@@ -0,0 +1,19 @@
---
date: '2026-03-25T10:21:48+01:00'
draft: false
title: 'This webpage'
author: "Jirka"
tags: ["self-hosted", "docker"]
categories: ["projects"]
description: "This whole webpage is my project!"
git: "https://git.jirkabuilds.dev/jirka/web"
---
This is The first project shared on this webpage, and it is the webpage itself!
There are several articles connected to how this page was build [here](categories/blog-setup).
Source files for Hugo can be found on my Gitea [here](https://git.jirkabuilds.dev/jirka/web).
And that is it. Feel free to explore and learn something.

View File

@@ -52,8 +52,8 @@ theme = "minimal-black"
showNowSection = true showNowSection = true
showFeaturedProjects = true showFeaturedProjects = true
showLatestPosts = true showLatestPosts = true
featuredProjectsLimit = 3 featuredProjectsLimit = 4
latestPostsLimit = 3 latestPostsLimit = 4
projectsTitle = "Latest projects" projectsTitle = "Latest projects"
projectsSubtitle = "" projectsSubtitle = ""
blogTitle = "Latest articles" blogTitle = "Latest articles"
@@ -86,10 +86,10 @@ theme = "minimal-black"
useDevicon = true useDevicon = true
# Social Links # Social Links
# [[params.social]] # TODO [[params.social]]
# label = "Gitea" label = "Gitea"
# url = "https://git.jirkabuilds.dev/jirka" url = "https://git.jirkabuilds.dev/jirka"
# icon = "fa-solid fa-code-branch" icon = "fa-solid fa-code-branch"
# Navigation Menu # Navigation Menu
[menu] [menu]

View File

@@ -0,0 +1,37 @@
{{ define "main" }}
<section class="layout-page">
<div class="page-int section-stack">
<header class="space-y-2">
<h1 class="heading-page text-2xl sm:text-3xl">{{ .Title }}</h1>
</header>
{{ $paginator := .Paginate .Pages }}
<div class="grid gap-4 md:grid-cols-2">
{{ range $paginator.Pages.ByDate.Reverse }}
{{ partial "components/post-card.html" (dict "Page" . "Root" $) }}
{{ end }}
</div>
{{ if gt $paginator.TotalPages 1 }}
<nav class="mt-6 flex items-center justify-between text-xs text-muted">
{{ if $paginator.HasPrev }}
<a href="{{ $paginator.Prev.URL }}" class="link-underline">
← Novější
</a>
{{ else }}
<span></span>
{{ end }}
{{ if $paginator.HasNext }}
<a href="{{ $paginator.Next.URL }}" class="link-underline">
Starší →
</a>
{{ else }}
<span></span>
{{ end }}
</nav>
{{ end }}
</div>
</section>
{{ end }}

View File

@@ -0,0 +1,19 @@
{{ define "main" }}
<section class="layout-page">
<div class="page-int section-stack">
<header class="space-y-2">
<h1 class="heading-page text-2xl sm:text-3xl">{{ .Title }}</h1>
</header>
<div class="flex flex-wrap gap-2">
{{ range .Data.Terms }}
<a href="{{ .Page.Permalink }}" class="flex items-baseline gap-1.5 px-3 py-1 bg-white/5 border border-white/10 rounded-full hover:bg-white/10 hover:border-white/20 transition-all text-sm">
{{/* Název tagu */}}
<span class="font-medium text-white/90">{{ .Page.Title }}</span>
<span class="text-xs text-muted">({{ .Count }})</span>
</a>
{{ end }}
</div>
</div>
</section>
{{ end }}

View File

@@ -25,7 +25,7 @@ html[data-theme="dark"] {
--color-text: #f9fafb; --color-text: #f9fafb;
--color-text-muted: #9ca3af; --color-text-muted: #9ca3af;
--color-border: #27272a; --color-border: #27272a;
--color-accent: #555555; --color-accent: #707070;
} }
/* Base Styles */ /* Base Styles */

View File

@@ -1245,7 +1245,7 @@ html[data-theme="dark"] {
--color-text: #f9fafb; --color-text: #f9fafb;
--color-text-muted: #9ca3af; --color-text-muted: #9ca3af;
--color-border: #27272a; --color-border: #27272a;
--color-accent: #555555; --color-accent: #707070;
} }
/* Base Styles */ /* Base Styles */