Compare commits
15 Commits
4177e53284
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 02ee9aea80 | |||
| 23ec1fdf80 | |||
| ef8a22d55b | |||
| 5aa3612cdd | |||
| 9adf6f55a2 | |||
| 604d301a1c | |||
| 956b284d4b | |||
| 0a4b1a24f7 | |||
| de2044343d | |||
| b8b7baee0f | |||
| 162fbabd26 | |||
| 9702741bbe | |||
| 9c9db094a0 | |||
| ac62e53698 | |||
| 5d34c5f815 |
52
.gitea/workflows/deploy.yml
Normal file
52
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Build and Publish Web
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Hugo Setup
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: 'latest'
|
||||
extended: true
|
||||
|
||||
- name: Web Build
|
||||
run: |
|
||||
cd themes/minimal-black
|
||||
npm install
|
||||
cd ../..
|
||||
hugo --minify -b "https://jirkabuilds.dev/"
|
||||
|
||||
- name: Packaging ZIP
|
||||
run: |
|
||||
cd public
|
||||
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
|
||||
run: |
|
||||
curl -f --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
|
||||
--upload-file build.zip \
|
||||
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip"
|
||||
|
||||
- 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
21
LICENSE
Normal 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.
|
||||
@@ -13,3 +13,10 @@ hugo new projects/{article_name}.md
|
||||
```
|
||||
|
||||
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)**.
|
||||
|
||||
@@ -4,12 +4,16 @@ draft: false
|
||||
title: "Let's start a blog!"
|
||||
author: "Jirka"
|
||||
tags: ["hugo", "idea", "guide", "tutorial"]
|
||||
categories: ["blog", "idea"]
|
||||
categories: ["Blog setup", "idea"]
|
||||
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).
|
||||
|
||||
> [!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
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
```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.
|
||||
|
||||
---
|
||||
This article is one from series about this blog and self-hosting. All connected articles can found [here](categories/blog-setup).
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
---
|
||||
date: '2026-03-24T10:17:21+01:00'
|
||||
draft: false
|
||||
title: 'Hosting Blog'
|
||||
title: 'How to self-host a blog'
|
||||
author: "Jirka"
|
||||
tags: ["caddy", "vps", "wireguard", "docker", "guide", "tutorial"]
|
||||
categories: ["blog", "self-hosting"]
|
||||
description: "How this blog came online."
|
||||
tags: ["caddy", "docker", "wireguard", "vps", "guide", "tutorial", "self-hosted"]
|
||||
categories: ["Blog setup"]
|
||||
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.
|
||||
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
|
||||
|
||||
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
|
||||
# Shared network between containers (for later use)
|
||||
networks:
|
||||
jirkabuilds_proxy_network:
|
||||
proxy_network:
|
||||
|
||||
services:
|
||||
jirkabuilds_wireguard:
|
||||
wireguard:
|
||||
image: linuxserver/wireguard:latest
|
||||
container_name: wireguard
|
||||
cap_add:
|
||||
@@ -199,13 +202,13 @@ services:
|
||||
restart: unless-stopped
|
||||
# We will add wireguard to this network, but limit access from WG itself
|
||||
networks:
|
||||
- jirkabuilds_proxy_network
|
||||
- proxy_network
|
||||
|
||||
jirkabuilds_caddy:
|
||||
caddy:
|
||||
image: caddy:latest
|
||||
container_name: jirkabuilds_caddy
|
||||
container_name: caddy
|
||||
# Caddy shares all networks with WireGuard
|
||||
network_mode: "service:jirkabuilds_wireguard"
|
||||
network_mode: "service:wireguard"
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||
- ./site_data:/srv
|
||||
@@ -261,3 +264,6 @@ docker compose up -d
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
date: '2026-03-24T18:48:40+01:00'
|
||||
draft: true
|
||||
draft: false
|
||||
title: 'Time for version control'
|
||||
author: "Jirka"
|
||||
tags: ["gitea", "self-hostet", "docker", "guide", "tutorial"]
|
||||
categories: ["self-host", "documentation"]
|
||||
tags: ["gitea", "self-hosted", "docker", "guide", "tutorial"]
|
||||
categories: ["Blog setup"]
|
||||
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/).
|
||||
|
||||
> [!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
|
||||
|
||||
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:
|
||||
```yaml
|
||||
networks:
|
||||
jirkabuilds_proxy_network:
|
||||
proxy_network:
|
||||
|
||||
include:
|
||||
- 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:
|
||||
```yaml
|
||||
networks:
|
||||
gitea-internal:
|
||||
jirkabuilds_proxy_network:
|
||||
gitea_internal:
|
||||
proxy_network:
|
||||
|
||||
services:
|
||||
jirkabuilds_gitea:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:latest
|
||||
container_name: jirkabuilds_gitea
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=${APP_UID}
|
||||
- USER_GID=${APP_GID}
|
||||
- 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__USER=${DB_USER}
|
||||
- GITEA__database__PASSWD=${DB_PASSWORD}
|
||||
restart: always
|
||||
networks:
|
||||
- gitea-internal
|
||||
- gitea_internal
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
@@ -84,7 +87,7 @@ services:
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
jirkabuilds_gitea_db:
|
||||
gitea_db:
|
||||
image: docker.io/library/postgres:14
|
||||
restart: always
|
||||
environment:
|
||||
@@ -92,7 +95,7 @@ services:
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
- POSTGRES_DB=${DB_NAME}
|
||||
networks:
|
||||
- gitea-internal
|
||||
- gitea_internal
|
||||
volumes:
|
||||
- ./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:
|
||||
```yaml
|
||||
jirkabuilds_gitea:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:latest
|
||||
container_name: jirkabuilds_gitea
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=${APP_UID}
|
||||
- USER_GID=${APP_GID}
|
||||
- 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__USER=${DB_USER}
|
||||
- GITEA__database__PASSWD=${DB_PASSWORD}
|
||||
restart: always
|
||||
networks:
|
||||
- gitea-internal
|
||||
- jirkabuilds_proxy_network
|
||||
- gitea_internal
|
||||
- proxy_network
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
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:
|
||||
```
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
286
content/blog/04-automatic-release.md
Normal file
286
content/blog/04-automatic-release.md
Normal file
@@ -0,0 +1,286 @@
|
||||
---
|
||||
date: '2026-03-24T20:36:26+01:00'
|
||||
draft: false
|
||||
title: 'Automatic web deployment'
|
||||
author: "Jirka"
|
||||
tags: ["self-hosted", "gitea", "automation", "docker"]
|
||||
categories: ["Blog setup"]
|
||||
description: "Last step, how to relase changes to web automatically"
|
||||
---
|
||||
|
||||
Okay, this should be the last step of this article series. Automatic releases to web.
|
||||
|
||||
The idea is simple, push changes to `master` branch of repo holding this web and automatically release it.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
I know, it sounds silly, it has a reason. You do not want to have container with privileges to run docker containers. It is even more true, when you consider you can control this container via Gitea actions. So, we will start docker in container and then give Gitea runner rights to that. It is actually much simpler to do, then it may seem like.
|
||||
|
||||
First, let's get registration runner token. Where you can obtain one depends on scope, from which the runner should be accessible. I want the runner to be usable only by me, so I will get registration token from Gitea → Profile settings → Actions → Runners → Create new Runner.
|
||||
|
||||
I will store this token into `.env` file inside my `gitea` directory created in [last](./03-gitea.md) article with `RUNNER_TOKEN` name.
|
||||
|
||||
Next we modify Gitea `docker-compose.yml` file to look as follows:
|
||||
```yml
|
||||
networks:
|
||||
gitea_internal:
|
||||
proxy_network:
|
||||
gitea_runner_net: # For runner dind comunication
|
||||
gitea_net: # For runner gitea comunication, isolated from db
|
||||
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:latest
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=${APP_UID}
|
||||
- USER_GID=${APP_GID}
|
||||
- GITEA__database__DB_TYPE=postgres
|
||||
- GITEA__database__HOST=gitea_db:5432
|
||||
- GITEA__database__NAME=${DB_NAME}
|
||||
- GITEA__database__USER=${DB_USER}
|
||||
- GITEA__database__PASSWD=${DB_PASSWORD}
|
||||
restart: always
|
||||
networks:
|
||||
- gitea_internal
|
||||
- proxy_network
|
||||
- gitea_net
|
||||
volumes:
|
||||
- ./gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
depends_on:
|
||||
- gitea_db
|
||||
|
||||
gitea_db:
|
||||
image: docker.io/library/postgres:14
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
- POSTGRES_DB=${DB_NAME}
|
||||
networks:
|
||||
- gitea_internal
|
||||
volumes:
|
||||
- ./postgres:/var/lib/postgresql/data
|
||||
|
||||
# New
|
||||
dind:
|
||||
image: docker:dind
|
||||
container_name: gitea-dind
|
||||
restart: always
|
||||
privileged: true
|
||||
environment:
|
||||
- DOCKER_TLS_CERTDIR=/certs
|
||||
volumes:
|
||||
- dind_certs:/certs
|
||||
- dind_data:/var/lib/docker
|
||||
networks:
|
||||
gitea_runner_net:
|
||||
aliases:
|
||||
- docker
|
||||
|
||||
runner:
|
||||
image: gitea/act_runner:latest
|
||||
container_name: gitea-runner
|
||||
restart: always
|
||||
depends_on:
|
||||
- dind
|
||||
- gitea
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=https://git.jirkabuilds.dev
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN}
|
||||
- GITEA_RUNNER_NAME=docker-runner-dind
|
||||
- DOCKER_HOST=tcp://docker:2376
|
||||
- DOCKER_CERT_PATH=/certs/client
|
||||
- DOCKER_TLS_VERIFY=1
|
||||
volumes:
|
||||
- runner_data:/data
|
||||
- dind_certs:/certs:ro
|
||||
networks:
|
||||
- gitea_net
|
||||
- gitea_runner_net
|
||||
|
||||
volumes:
|
||||
dind_certs:
|
||||
dind_data:
|
||||
runner_data:
|
||||
```
|
||||
|
||||
And that is all, after `docker compose up -d`, runner should show up in the registry.
|
||||
|
||||
## Set up workflow
|
||||
|
||||
Next step is to set up workflow inside repository. Before we can do that, we need token for workload, to add access for package creation.
|
||||
|
||||
To do so, in Gitea got to Settings → Applications → Generate New Token. Give it permission to create package and copy token.
|
||||
|
||||
Now go to desired repo Settings → Actions → Secrets → Add secret and save token to Value. Name it `PACKAGE_TOKEN`.
|
||||
|
||||
Now we can use the token in our workflow. Workflow will be defined in `.gitea/workflows/deploy.yml` inside repository. And should contain something like this:
|
||||
```yaml
|
||||
name: Build and Publish Web
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Hugo Setup
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: 'latest'
|
||||
extended: true
|
||||
|
||||
- name: Web Build
|
||||
run: |
|
||||
cd themes/minimal-black
|
||||
npm install
|
||||
cd ../..
|
||||
hugo --minify
|
||||
|
||||
- name: Packaging ZIP
|
||||
run: |
|
||||
cd public
|
||||
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
|
||||
run: |
|
||||
curl -f --user "${{ github.actor }}:${{ secrets.PACKAGE_TOKEN }}" \
|
||||
--upload-file build.zip \
|
||||
"https://git.jirkabuilds.dev/api/packages/${{ github.repository_owner }}/generic/hugo-build/latest/web.zip"
|
||||
|
||||
# TODO - Webhook
|
||||
```
|
||||
|
||||
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).
|
||||
19
content/projects/01-blog.md
Normal file
19
content/projects/01-blog.md
Normal 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.
|
||||
12
hugo.toml
12
hugo.toml
@@ -52,8 +52,8 @@ theme = "minimal-black"
|
||||
showNowSection = true
|
||||
showFeaturedProjects = true
|
||||
showLatestPosts = true
|
||||
featuredProjectsLimit = 3
|
||||
latestPostsLimit = 3
|
||||
featuredProjectsLimit = 4
|
||||
latestPostsLimit = 4
|
||||
projectsTitle = "Latest projects"
|
||||
projectsSubtitle = ""
|
||||
blogTitle = "Latest articles"
|
||||
@@ -86,10 +86,10 @@ theme = "minimal-black"
|
||||
useDevicon = true
|
||||
|
||||
# Social Links
|
||||
# [[params.social]] # TODO
|
||||
# label = "Gitea"
|
||||
# url = "https://git.jirkabuilds.dev/jirka"
|
||||
# icon = "fa-solid fa-code-branch"
|
||||
[[params.social]]
|
||||
label = "Gitea"
|
||||
url = "https://git.jirkabuilds.dev/jirka"
|
||||
icon = "fa-solid fa-code-branch"
|
||||
|
||||
# Navigation Menu
|
||||
[menu]
|
||||
|
||||
37
layouts/_default/list.html
Normal file
37
layouts/_default/list.html
Normal 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 }}
|
||||
19
layouts/_default/terms.html
Normal file
19
layouts/_default/terms.html
Normal 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 }}
|
||||
@@ -25,7 +25,7 @@ html[data-theme="dark"] {
|
||||
--color-text: #f9fafb;
|
||||
--color-text-muted: #9ca3af;
|
||||
--color-border: #27272a;
|
||||
--color-accent: #555555;
|
||||
--color-accent: #707070;
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
|
||||
@@ -1245,7 +1245,7 @@ html[data-theme="dark"] {
|
||||
--color-text: #f9fafb;
|
||||
--color-text-muted: #9ca3af;
|
||||
--color-border: #27272a;
|
||||
--color-accent: #555555;
|
||||
--color-accent: #707070;
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
|
||||
Reference in New Issue
Block a user