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