Compare commits
10 Commits
f65657a781
...
89d25e31b4
Author | SHA1 | Date | |
---|---|---|---|
89d25e31b4 | |||
447214fe8a | |||
e786f0af0e | |||
095318ddc2 | |||
1450f0c639 | |||
3810942da3 | |||
7cbfef3543 | |||
02a84b7d37 | |||
7e84b198fc | |||
cda2e5b41d |
33
.gitea/workflows/build.yml
Normal file
33
.gitea/workflows/build.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
name: Release CI action
|
||||||
|
run-name: ${{ gitea.repository }} release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-container:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: qemu setup
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
- name: dockerx setup
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
# - name: Cache Docker layers
|
||||||
|
# uses: actions/cache@v2
|
||||||
|
# with:
|
||||||
|
# path: /tmp/.buildx-cache
|
||||||
|
# key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
# restore-keys: |
|
||||||
|
# ${{ runner.os }}-buildx-
|
||||||
|
- name: login
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
# NOTE: See https://gitea.com/gitea/docs/pulls/77/files
|
||||||
|
registry: git.gtz.dk
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
- name: build and push container
|
||||||
|
run: docker buildx build --push --platform linux/amd64,linux/arm64 -t git.gtz.dk/${{ gitea.repository }}:latest .
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
**/.DS_Store
|
@ -5,4 +5,8 @@ RUN hugo new site /hugo
|
|||||||
RUN git clone https://github.com/yihui/hugo-xmin.git themes/hugo-xmin
|
RUN git clone https://github.com/yihui/hugo-xmin.git themes/hugo-xmin
|
||||||
ADD hugo.toml /hugo/hugo.toml
|
ADD hugo.toml /hugo/hugo.toml
|
||||||
ADD content /hugo/content
|
ADD content /hugo/content
|
||||||
CMD ["hugo", "serve", "--bind", "0.0.0.0"]
|
ADD static /hugo/static
|
||||||
|
ADD shortcodes /hugo/layouts/shortcodes
|
||||||
|
ENV PORT=1313
|
||||||
|
EXPOSE $PORT
|
||||||
|
CMD ["hugo", "serve", "--bind", "0.0.0.0", "--port", "$PORT"]
|
||||||
|
8
content/posts/example.md
Normal file
8
content/posts/example.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
+++
|
||||||
|
date = '2024-11-27'
|
||||||
|
draft = true
|
||||||
|
title = 'Example'
|
||||||
|
tags = ['tutorial']
|
||||||
|
categories = ['technical']
|
||||||
|
+++
|
||||||
|
content goes here.
|
@ -1,6 +1,5 @@
|
|||||||
+++
|
+++
|
||||||
date = '2024-11-27'
|
date = '2024-11-27'
|
||||||
draft = false
|
|
||||||
title = 'How to Host a Simple Blog'
|
title = 'How to Host a Simple Blog'
|
||||||
tags = ['howto', 'tutorial', 'web']
|
tags = ['howto', 'tutorial', 'web']
|
||||||
categories = ['technical']
|
categories = ['technical']
|
||||||
@ -24,11 +23,13 @@ Ideally, the directory structure should look like this:
|
|||||||
blog
|
blog
|
||||||
├── Dockerfile // dockerfile to build and host the site
|
├── Dockerfile // dockerfile to build and host the site
|
||||||
├── README.md // info about the repository, not a blogpost
|
├── README.md // info about the repository, not a blogpost
|
||||||
├── config.toml // blog-framework configuration file
|
├── hugo.toml // blog-framework configuration file
|
||||||
└── content
|
├── content
|
||||||
├── about.md // the "about" page
|
│ ├── about.md // the "about" page
|
||||||
└── posts // actual blog posts go here
|
│ └── posts // actual blog posts go here
|
||||||
└── example.md
|
│ └── example.md
|
||||||
|
└── static // non-markdown files
|
||||||
|
└── example.png
|
||||||
```
|
```
|
||||||
|
|
||||||
And then to build the site, simply build the container:
|
And then to build the site, simply build the container:
|
||||||
@ -52,9 +53,125 @@ RUN hugo new site /hugo
|
|||||||
RUN git clone https://github.com/yihui/hugo-xmin.git themes/hugo-xmin
|
RUN git clone https://github.com/yihui/hugo-xmin.git themes/hugo-xmin
|
||||||
ADD hugo.toml /hugo/hugo.toml
|
ADD hugo.toml /hugo/hugo.toml
|
||||||
ADD content /hugo/content
|
ADD content /hugo/content
|
||||||
CMD ["hugo", "serve", "--bind", "0.0.0.0"]
|
ADD static /hugo/static
|
||||||
|
ENV PORT=1313
|
||||||
|
EXPOSE $PORT
|
||||||
|
CMD hugo serve --bind 0.0.0.0 --port $PORT
|
||||||
```
|
```
|
||||||
|
|
||||||
For now, I am just using the built-in server in `hugo`, but it should be possible to serve using `nginx`.
|
For now, I am just using the built-in server in `hugo`, but it should be possible to serve using `nginx`.
|
||||||
|
|
||||||
I mentioned `hugo` before, but I was mostly mad that I had to add the autogenerated stuff in git - with this approach... I don't have to 🎊!
|
I mentioned `hugo` before, but I was mostly mad that I had to add the autogenerated stuff in git - with this approach... I don't have to 🎊!
|
||||||
|
|
||||||
|
## Images
|
||||||
|
Just put images in the `static` directory, and reference to them in your blogposts like you would normally in a `hugo` project:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
![example](/example.png)
|
||||||
|
```
|
||||||
|
|
||||||
|
![example](/example.png#center)
|
||||||
|
|
||||||
|
This is not centered, and there's no built-in [shortcode](https://gohugo.io/content-management/shortcodes/) for centering images (why not, hugo? You have a shortcode for figures, but no css class for centering - you cant even add a `style` tag? Such an oversight)...
|
||||||
|
So we have to add one dirty thing to this setup. We have to add a `shortcodes` directory, that is then also added to the docker container in `/hugo/layouts/shortcodes`:
|
||||||
|
|
||||||
|
```
|
||||||
|
blog
|
||||||
|
├── Dockerfile
|
||||||
|
├── README.md
|
||||||
|
├── hugo.toml
|
||||||
|
├── content
|
||||||
|
│ ├── about.md
|
||||||
|
│ └── posts
|
||||||
|
│ ├── example.md
|
||||||
|
│ └── how-to-blog.md
|
||||||
|
├── shortcodes
|
||||||
|
│ └── centered.html // <-- Added
|
||||||
|
└── static
|
||||||
|
└── example.png
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- centered.html -->
|
||||||
|
<p align="center">
|
||||||
|
<img alt="example" src="{{.Get `image`}}" style="max-width: 100%;">
|
||||||
|
</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we can use this new shortcode like so:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
{{</* centered image="/example.png" */>}}
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< centered image="/example.png" >}}
|
||||||
|
|
||||||
|
Yes! Now we're cooking with gas! ... or atleast cooking with something. Note that this image centering trick does not work in [reader mode](https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages).
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
We have made a docker file for automatically downloading, generating and serving a simple `hugo` blog site.
|
||||||
|
Personally, I would've liked the `static` and `shortcodes` directories to not exist, but blogposts need images and it needs to center them, so they are a necessary evil.
|
||||||
|
Could we make the directory structure better and cleaner? Probably yes.
|
||||||
|
Will I make it better for this blog in the future? Probably yes.
|
||||||
|
Will I make another post when I do that? Probably yes!
|
||||||
|
|
||||||
|
If you want to just manually build and run docker image on your website server, feel free to stop reading here.
|
||||||
|
The next section concerns about hosting, orchestrating and deploying the site automatically, but it's totally not required.
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
Being able to build and launch the docker image is nice and can suffice for smaller projects.
|
||||||
|
Yes, this blog is a small project and the manual method should be more than enough, but I also play [factorio](https://store.steampowered.com/app/427520/Factorio/) (highly recommend it!), so I _hvae_ to automate everything that is tedious.
|
||||||
|
I also have other projects that I host on my VPS (Virtual Private Server) such my portfolio site [gtz.dk](https://gtz.dk) and a [gitea instance](https://git.gtz.dk/) amongst other things.
|
||||||
|
|
||||||
|
## Continuous Integration
|
||||||
|
I am using my personal [gitea instance](https://git.gtz.dk/agj/blog) to host the source code for this blog - which means that I will be using the integrated CI system there, but you can use whichever CI service you'd like.
|
||||||
|
The general concepts of the workflow should be fairly easy to translate to any kind of CI, but this is how my setup looks like:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Release CI action
|
||||||
|
run-name: ${{ gitea.repository }} release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-container:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: build container
|
||||||
|
run: docker build -t git.gtz.dk/${{ gitea.repository }}:latest .
|
||||||
|
- name: login
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
# NOTE: See https://gitea.com/gitea/docs/pulls/77/files
|
||||||
|
registry: git.gtz.dk
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
- name: push container
|
||||||
|
run: docker push git.gtz.dk/${{ gitea.repository }}:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
This may look a bit overwhelming if you don't know [Github Actions](https://docs.github.com/en/actions), but it is really quite straight forward.
|
||||||
|
Every time we push a commit to the `main` branch, we run the job named `build-and-push-container`.
|
||||||
|
In the job, we first download our repository with the `actions/checkout@v4` action, then we build the container using `docker build` (we make sure to accurately tag the image), then we log in to the container registry that we want to host the container at using the `docker/login-action@v3` action, and the we simply `docker push` the container image.
|
||||||
|
|
||||||
|
Make sure to replace the `git.gtz.dk` website mentions with your own github hosting service (whether self-hosted, or `github.com`) and replace the `gitea/GITEA` mentions with `github/GITHUB` instead.
|
||||||
|
Note that the syntax is extemely similar to GitHub Actions - in fact Gitea Actions are trying to be 1 to 1 compatible with GitHub Actions, so it should be relatively straight forward.
|
||||||
|
|
||||||
|
This setup also gives us the possibility of performing traditional code-review before releasing by using [pull requests](https://docs.gitea.com/next/usage/pull-request?_highlight).
|
||||||
|
This should empower us to identify and correct issues (e.g. spelling mistakes or whatever) before they are pushed to the official website.
|
||||||
|
|
||||||
|
I will probably make a post about how to host a private gitea instance with an actions runner and all that jazz. For now, I will consider that particular rabbit hole out-of-scope.
|
||||||
|
|
||||||
|
This was the most difficult thing to do. We are _almost_ there.
|
||||||
|
|
||||||
|
## Continuous Delivery
|
||||||
|
With a docker image readily available, we can automatically deploy the blog when we push it!
|
||||||
|
|
||||||
|
I personally am a big fan of the simplicity of [portainer](https://www.portainer.io/), as it scales really well when doing perosnal server stuff.
|
||||||
|
|
||||||
|
## P.S.
|
||||||
|
You may notice that the build script on the real
|
||||||
|
3
shortcodes/centered.html
Normal file
3
shortcodes/centered.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img alt="example" src="{{.Get `image`}}" style="max-width: 100%;">
|
||||||
|
</p>
|
BIN
static/example.png
Normal file
BIN
static/example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Loading…
x
Reference in New Issue
Block a user