init: first commit
This commit is contained in:
38
.gitea/workflows/publish-image.yml
Normal file
38
.gitea/workflows/publish-image.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Publish morthimer/website image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Repository checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Lint Dockerfile with Hadolint
|
||||||
|
uses: hadolint/hadolint-action@v3.1.0
|
||||||
|
with:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: lint
|
||||||
|
steps:
|
||||||
|
- name: Repository login
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ secrets.DOCKER_REGISTRY }}
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ secrets.DOCKER_REGISTRY }}/${{ gitea.repository }}:latest
|
||||||
|
${{ secrets.DOCKER_REGISTRY }}/${{ gitea.repository }}:${{ gitea.tag }}
|
||||||
|
build-args: |
|
||||||
|
img_ver=${{ gitea.tag }}
|
||||||
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
FROM alpine:3
|
||||||
|
|
||||||
|
ARG img_ver
|
||||||
|
ENV IMAGE_VERSION ${img_ver}
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.title="Website" \
|
||||||
|
org.opencontainers.image.description="My website -- morthimer.fr" \
|
||||||
|
org.opencontainers.image.source="https://git.int.morthimer.fr/morthimer/website" \
|
||||||
|
org.opencontainers.image.url="https://git.int.morthimer.fr/morthimer/website" \
|
||||||
|
org.opencontainers.image.authors="morthimer"
|
||||||
|
LABEL org.opencontainers.image.version="${IMAGE_VERSION}"
|
||||||
|
|
||||||
|
|
||||||
|
RUN apk update && apk upgrade \
|
||||||
|
&& apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community hugo go git \
|
||||||
|
&& addgroup -g 1000 morthimer \
|
||||||
|
&& adduser -u 1000 -G morthimer -s /bin/sh -D morthimer
|
||||||
|
|
||||||
|
USER morthimer
|
||||||
|
WORKDIR /home/morthimer
|
||||||
|
|
||||||
|
RUN hugo new site www \
|
||||||
|
&& cd www \
|
||||||
|
&& hugo mod init git.morthimer.fr
|
||||||
|
COPY --chown=morthimer:morthimer rootfs/ /
|
||||||
|
WORKDIR /home/morthimer/www
|
||||||
|
|
||||||
|
EXPOSE 1313
|
||||||
|
ENTRYPOINT [ "hugo" ]
|
||||||
|
CMD [ "server", "--bind", "0.0.0.0", "-w", "-D" ]
|
||||||
18
Makefile
Normal file
18
Makefile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
init-sandbox:
|
||||||
|
docker run -d --name dev-ct alpine sleep infinity
|
||||||
|
docker exec -it dev-ct ash
|
||||||
|
|
||||||
|
clean-sandbox:
|
||||||
|
docker stop dev-ct && docker rm dev-ct
|
||||||
|
|
||||||
|
lint:
|
||||||
|
docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile
|
||||||
|
|
||||||
|
build-dev:
|
||||||
|
docker build --no-cache -t hugo-dev .
|
||||||
|
|
||||||
|
run-dev:
|
||||||
|
docker run -p 80:1313 --name hugo-dev -d hugo-dev
|
||||||
|
|
||||||
|
clean-dev:
|
||||||
|
docker rm -f hugo-dev
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
# website
|
# website - https://morthimer.fr
|
||||||
|
|
||||||
|
# Description
|
||||||
|
This portfolio website was made with (Hugo)[https://gohugo.io/] with this (theme)[https://github.com/Yukuro/hugo-theme-shell]
|
||||||
55
rootfs/home/morthimer/www/hugo.toml
Normal file
55
rootfs/home/morthimer/www/hugo.toml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
baseURL = "http://localhost/"
|
||||||
|
title = "Shell"
|
||||||
|
ignoreErrors = ["error-remote-getjson"]
|
||||||
|
|
||||||
|
[module]
|
||||||
|
[[module.imports]]
|
||||||
|
path = 'github.com/yukuro/hugo-theme-shell'
|
||||||
|
|
||||||
|
[params]
|
||||||
|
description = "morthimer's Portfolio"
|
||||||
|
[params.Terminal]
|
||||||
|
schema = "gruvbox_dark"
|
||||||
|
|
||||||
|
userName = "guest"
|
||||||
|
pcName = "morthimer.fr"
|
||||||
|
workDir = "www"
|
||||||
|
profile = "profile.txt"
|
||||||
|
|
||||||
|
ps1Delay = 20
|
||||||
|
stdoutDelay = 20
|
||||||
|
commandDelay = 40
|
||||||
|
|
||||||
|
titleDelay = 0
|
||||||
|
contentDelay = 0
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Greetings!
|
||||||
|
I'm morthimer.
|
||||||
|
|
||||||
|
Skills:
|
||||||
|
- Docker, Kubernetes
|
||||||
|
- Python, Bash, Go
|
||||||
|
- Ansible, Terraform
|
||||||
|
- GitLab CI, GitHub Actions, ArgoCD
|
||||||
|
- Prometheus, Loki, Grafana
|
||||||
|
"""
|
||||||
|
|
||||||
|
[params.Tree]
|
||||||
|
use = true
|
||||||
|
folderName = "links"
|
||||||
|
files = [
|
||||||
|
["Git", "https://git.morthimer.fr"],
|
||||||
|
["Wiki", "https://wiki.morthimer.fr"],
|
||||||
|
]
|
||||||
|
|
||||||
|
[params.Tree2]
|
||||||
|
use = true
|
||||||
|
folderName = "bookmarks"
|
||||||
|
files = [
|
||||||
|
["IT Roadmaps", "https://roadmap.sh/"],
|
||||||
|
["DevOps Training", "https://github.com/bregman-arie/devops-exercises"],
|
||||||
|
["Awesome Content","https://github.com/sindresorhus/awesome"],
|
||||||
|
["server-world.info","https://www.server-world.info/en/"],
|
||||||
|
["The Brutalist Report", "https://brutalist.report/" ],
|
||||||
|
]
|
||||||
78
rootfs/home/morthimer/www/layouts/index.html
Normal file
78
rootfs/home/morthimer/www/layouts/index.html
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
{{ $env := printf "<strong><span id='user'>%s@%s</span><span id='terminal'>:</span><span id='dir'>~/%s</span></strong><span id='terminal'>$</span>" .Site.Params.Terminal.userName .Site.Params.Terminal.pcName "" | safeHTML }}
|
||||||
|
{{ $envWithDir := printf "<strong><span id='user'>%s@%s</span><span id='terminal'>:</span><span id='dir'>~/%s</span></strong><span id='terminal'>$</span>" .Site.Params.Terminal.userName .Site.Params.Terminal.pcName .Site.Params.Terminal.workDir | safeHTML }}
|
||||||
|
|
||||||
|
{{ $cd := printf "<span id='terminal'>cd %s</span>" .Site.Params.Terminal.workDir | safeHTML }}
|
||||||
|
{{ $cat := printf "<span id=terminal>cat %s</span>" .Site.Params.Terminal.profile | safeHTML }}
|
||||||
|
|
||||||
|
{{ $description := "" }}
|
||||||
|
{{ if eq (substr .Site.Params.Terminal.description -3 3) ".md" }}
|
||||||
|
{{ $s := "" }}
|
||||||
|
{{ with .Site.GetPage .Site.Params.Terminal.description }}
|
||||||
|
<!-- replace the first p tag with a br tag -->
|
||||||
|
{{ $s = replaceRE "</?p[^>]*>" "" .Content 1 }}
|
||||||
|
{{ end }}
|
||||||
|
{{ $description = printf "<span id='terminal'>%s</span>" $s | safeHTML}}
|
||||||
|
{{ else }}
|
||||||
|
{{ $limit := sub (len (findRE "\n" .Site.Params.Terminal.description)) 1 }}
|
||||||
|
{{ $description = printf "<span id='terminal'>%s</span>" .Site.Params.Terminal.description }}
|
||||||
|
{{ $description = replaceRE "\n" "<br>" $description $limit| safeHTML }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $tree := "" }}
|
||||||
|
{{ $leaf := "" }}
|
||||||
|
{{ if .Site.Params.Tree.use }}
|
||||||
|
{{ $tree = printf "<span id='terminal'>tree ./%s/</span>" .Site.Params.Tree.folderName | safeHTML}}
|
||||||
|
{{ $leaf = printf "%s<strong><span id='dir'>./%s/</span></strong><br>" $leaf .Site.Params.Tree.folderName | safeHTML}}
|
||||||
|
{{ range $index, $val := .Site.Params.Tree.files }}
|
||||||
|
{{ $ac := index $val 0}}
|
||||||
|
{{ $link := index $val 1}}
|
||||||
|
|
||||||
|
<!-- pass link (i.e. http, https) and mailto -->
|
||||||
|
{{ $l := $.Site.GetPage $link }}
|
||||||
|
{{ if $l }}
|
||||||
|
{{ $link = $l.Permalink}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if eq (add $index 1) (len $.Site.Params.Tree.files) }}
|
||||||
|
{{ $leaf = printf "<span id='terminal'>%s└── <a href='%s'>%s</a></span>" $leaf $link $ac | safeHTML}}
|
||||||
|
{{ else }}
|
||||||
|
{{ $leaf = printf "<span id='terminal'>%s├── <a href='%s'>%s</a></span><br>" $leaf $link $ac | safeHTML}}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $tree2 := "" }}
|
||||||
|
{{ $leaf2 := "" }}
|
||||||
|
{{ if .Site.Params.Tree2.use }}
|
||||||
|
{{ $tree2 = printf "<span id='terminal'>tree ./%s/</span>" .Site.Params.Tree2.folderName | safeHTML}}
|
||||||
|
{{ $leaf2 = printf "%s<strong><span id='dir'>./%s/</span></strong><br>" $leaf2 .Site.Params.Tree2.folderName | safeHTML}}
|
||||||
|
{{ range $index, $val := .Site.Params.Tree2.files }}
|
||||||
|
{{ $ac := index $val 0}}
|
||||||
|
{{ $link := index $val 1}}
|
||||||
|
|
||||||
|
<!-- pass link (i.e. http, https) and mailto -->
|
||||||
|
{{ $l := $.Site.GetPage $link }}
|
||||||
|
{{ if $l }}
|
||||||
|
{{ $link = $l.Permalink}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if eq (add $index 1) (len $.Site.Params.Tree2.files) }}
|
||||||
|
{{ $leaf2 = printf "<span id='terminal'>%s└── <a href='%s'>%s</a></span>" $leaf2 $link $ac | safeHTML}}
|
||||||
|
{{ else }}
|
||||||
|
{{ $leaf2 = printf "<span id='terminal'>%s├── <a href='%s'>%s</a></span><br>" $leaf2 $link $ac | safeHTML}}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $end := $env }}
|
||||||
|
|
||||||
|
{{ $payload := delimit (slice $cd $cat $description $tree $leaf $end) "" }}
|
||||||
|
|
||||||
|
{{ $ps1Delay := $.Site.Params.Terminal.ps1Delay }}
|
||||||
|
{{ $stdoutDelay := $.Site.Params.Terminal.stdoutDelay }}
|
||||||
|
{{ $commandDelay := $.Site.Params.Terminal.commandDelay }}
|
||||||
|
|
||||||
|
{{ partial "partials/typeIndex.html" (dict "context" . "env" $env "cd" $cd "envWithDir" $envWithDir "cat" $cat "description" $description "tree" $tree "leaf" $leaf "tree2" $tree2 "leaf2" $leaf2 "ps1delay" $ps1Delay "stdoutdelay" $stdoutDelay "commanddelay" $commandDelay ) }}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
70
rootfs/home/morthimer/www/layouts/partials/typeIndex.html
Normal file
70
rootfs/home/morthimer/www/layouts/partials/typeIndex.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<span id="ps1_01"></span> <span id="cd"></span> <br>
|
||||||
|
<span id="ps1_02"></span> <span id="cat"></span> <br>
|
||||||
|
<span id="std_out_01"></span> <br>
|
||||||
|
<span id="ps1_03"></span> <span id="tree"></span> <br>
|
||||||
|
<span id="std_out_02"></span> <br>
|
||||||
|
<span id="ps1_04"></span> <span id="tree2"></span> <br>
|
||||||
|
<span id="std_out_03"></span> <br>
|
||||||
|
<span id="ps1_05"></span>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
async function typewriter(text, elementId, waitAfter) {
|
||||||
|
var n = 0,
|
||||||
|
isTag = false
|
||||||
|
addText = "";
|
||||||
|
const el = document.getElementById(elementId);
|
||||||
|
|
||||||
|
const wait = () => new Promise(r => setTimeout(r, waitAfter));
|
||||||
|
const nowait = () => new Promise(r => r());
|
||||||
|
|
||||||
|
const render = () => el.innerHTML = (text.slice(0, n + 1) + addText);
|
||||||
|
|
||||||
|
const cursor = document.createElement('span');
|
||||||
|
cursor.id = "blink";
|
||||||
|
|
||||||
|
el.style.setProperty("--cursor-visibility", "visible");
|
||||||
|
while (n < text.length) {
|
||||||
|
if (text.charAt(n + 1) === "<") isTag = true;
|
||||||
|
if (text.charAt(n + 1) === ">") isTag = false;
|
||||||
|
|
||||||
|
if (isTag) {
|
||||||
|
n++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
|
||||||
|
if (waitAfter === 0) {
|
||||||
|
await nowait();
|
||||||
|
} else {
|
||||||
|
await wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
el.style.setProperty("--cursor-visibility", "collapse");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDelay(d) {
|
||||||
|
const parsed = parseInt(d, 10);
|
||||||
|
if (isNaN(parsed)) return 0;
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ps1Delay = parseDelay("{{ .ps1delay }}"),
|
||||||
|
stdoutDelay = parseDelay("{{ .stdoutdelay }}"),
|
||||||
|
commandDelay = parseDelay("{{ .commanddelay }}");
|
||||||
|
const typeeffetct = async () => {
|
||||||
|
await typewriter("{{ .env }}", "ps1_01", ps1Delay); await typewriter("{{ .cd }}", "cd", commandDelay);
|
||||||
|
await typewriter("{{ .envWithDir }}", "ps1_02", ps1Delay); await typewriter("{{ .cat }}", "cat", commandDelay);
|
||||||
|
await typewriter("{{ .description }}", "std_out_01", stdoutDelay);
|
||||||
|
await typewriter("{{ .envWithDir }}", "ps1_03", ps1Delay); await typewriter("{{ .tree }}", "tree", commandDelay);
|
||||||
|
await typewriter("{{ .leaf }}", "std_out_02", stdoutDelay);
|
||||||
|
await typewriter("{{ .envWithDir }}", "ps1_04", ps1Delay); await typewriter("{{ .tree2 }}", "tree2", commandDelay);
|
||||||
|
await typewriter("{{ .leaf2 }}", "std_out_03", stdoutDelay);
|
||||||
|
await typewriter("{{ .envWithDir }}", "ps1_05", ps1Delay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeeffetct()
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user