Compare commits

...

No commits in common. '2.0' and 'master' have entirely different histories.
2.0 ... master

@ -1,41 +0,0 @@
---
kind: pipeline
type: docker
name: build
steps:
- name: docker
image: plugins/docker
settings:
registry: docker.cybre.town
repo: docker.cybre.town/adb/adb.sh
tags:
- "${DRONE_COMMIT_SHA:0:8}"
- "latest"
username:
from_secret: docker_username
password:
from_secret: docker_password
---
kind: pipeline
type: docker
name: deploy
depends_on:
- build
steps:
- name: pull and deploy
image: appleboy/drone-ssh:linux-amd64
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_user_name
key:
from_secret: ssh_private_key
script: |
cd /media/docker/adb.sh
docker compose -f docker-compose.prod.yml -p adb-sh pull -q
docker compose -f docker-compose.prod.yml -p adb-sh up -d

3
.gitignore vendored

@ -1,3 +0,0 @@
.idea
dist
node_modules

@ -1,14 +0,0 @@
FROM node:16-alpine AS builder
COPY ./ /home/node/app
WORKDIR /home/node/app
RUN npm ci && npm run build
FROM nginx:alpine
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /home/node/app/dist /var/www/html
EXPOSE 8080

@ -1,15 +0,0 @@
version: '3'
networks:
web:
external: true
services:
frontend:
image: node:16
volumes:
- ./:/app
working_dir: /app
command: 'npm run dev'
ports:
- "8080:8080"

@ -1,20 +0,0 @@
version: '3'
networks:
web:
external: true
services:
frontend:
image: docker.cybre.town/adb/adb.sh
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.adb-sh.rule=Host(`adb.sh`)"
- "traefik.http.routers.adb-sh.entrypoints=https"
- "traefik.http.services.adb-sh.loadbalancer.server.port=8080"
- "traefik.http.routers.adb-sh.tls.certresolver=mytlschallenge"
- "traefik.docker.network=web"
networks:
- web

@ -1,22 +0,0 @@
version: '3'
networks:
web:
external: true
services:
frontend:
image: docker.cybre.town/adb/adb.sh
build:
dockerfile: ./Dockerfile
context: ./
labels:
- "traefik.enable=true"
- "traefik.http.routers.adb-sh.rule=Host(`adb.sh`)"
- "traefik.http.routers.adb-sh.entrypoints=https"
- "traefik.http.services.adb-sh.loadbalancer.server.port=8080"
- "traefik.http.routers.adb-sh.tls.certresolver=mytlschallenge"
- "traefik.docker.network=web"
ports:
- "9000:8080"

@ -0,0 +1,348 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>ADB</title>
<meta charset="utf-8"/>
<meta content="Alban David Becker" name="author">
<meta content="Alban David Becker" name="publisher">
<meta content="Alban David Becker" name="copyright">
<meta content="Alban David Becker - Media / Programming" name="description">
<meta content="Alban, David, Becker, Media, Photography, Programming, Engineering, Development" name="keywords">
<meta content="Private Homepage" name="page-type">
<meta content="en" http-equiv="content-language">
<meta content="index, follow" name="robots">
<meta content="width=device-width,initial-scale=0.8,maximum-scale=0.8,user-scalable=0" name="viewport">
<style>
@import 'https://fonts.googleapis.com/css?family=Roboto+Mono:100';
html, body {
font-family: Roboto Mono, monospace;
height: 100%;
width: auto;
margin: 0;
background-color: #1f262b;
}
h1, h2, h3 {
color: #fff;
text-align: center;
}
table {
position: relative;
margin: auto;
width: calc(100% - 2rem);
max-width: 40rem;
background-color: #1f262b;
box-shadow: 3px 3px 10px #333;
border: 2px solid #fff;
border-collapse: separate;
border-spacing: 2px;
border-radius: 0.75rem;
color: #fff;
font-size: 1.2rem;
font-family: "Roboto", regular, sans-serif;
}
tr {
margin: auto;
border: 1px solid #fff;
}
th {
margin: auto;
background-color: #546E7A;
padding: 20px;
border-radius: 8px;
}
td {
margin: auto;
background-color: #37474F;
padding: 10px;
border-radius: 8px;
}
td.left, th.left {
border-radius: 0.5rem 0 0 0.5rem;
}
td.right, th.right {
border-radius: 0 0.5rem 0.5rem 0;
}
td.mid, th.mid {
border-radius: 0 0 0 0;
}
.footer {
margin: 5rem 0 1rem 1rem;
bottom: 5px;
word-break: break-word;
font-size: 1em;
color: #fafafa;
}
.logo-img {
fill: #fafafa;
}
.matrix {
font-family: Helvetica, monospace;
display: inline-block;
height: 50px;
padding-bottom: 10px;
}
.social_icons {
position: absolute;
top: 10rem;
user-select: none;
width: 90%;
left: 5%;
}
.social_icons > div {
position: relative;
display: inline-block;
height: min-content;
cursor: pointer;
}
a {
color: inherit;
text-decoration: none;
}
.top {
height: 100%;
}
.social {
position: sticky;
font-size: 3em;
color: #fafafa;
height: 20rem;
width: 100%;
top: calc(50% - 10rem);
text-align: center;
}
.logo-img {
fill: #fafafa;
height: 50px;
width: 50px;
}
</style>
</head>
<body>
<div class="top">
<div class="social">
<div class="text">
<noscript>Please activate JavaScript to see the text animation. There are no trackers on this site! :)
</noscript>
</div>
<div class="social_icons">
<div onclick="location.href='https://github.com/adb-sh/'">
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="m256 0c-140.699219 0-256 116.300781-256 257 0 139.882812 114.25 255 256 255 141.574219 0 256-114.945312 256-255 0-140.699219-115.300781-257-256-257zm45 477.5c-14.398438 3-29.699219 4.5-45 4.5s-30.601562-1.5-45-4.5v-70.199219c0-16.800781 4.5-22.800781 10.5-30.902343 3.054688-3.492188 4.898438-6.625 18.597656-27.296876l-23.097656-3.601562c-59.402344-8.699219-82.800781-39.601562-92.101562-63.601562-12-32.097657-5.699219-72.300782 15.902343-97.796876 3.300781-3.902343 6-10.503906 3.601563-17.402343-4.503906-13.800781-3.902344-35.699219-.902344-44.101563 15.90625 2.273438 32.261719 13.667969 45.902344 21.902344 6.285156 3.667969 9.582031 2.699219 12.597656 3 10.960938-2.28125 28.058594-7.800781 54.300781-7.800781 16.199219 0 33.300781 2.398437 50.101563 7.199219 3.003906-.070313 7.832031 2.484374 16.199218-2.398438 14.257813-8.6875 30.058594-19.691406 45.898438-21.902344 3 8.402344 3.601562 30.300782-.898438 44.101563-2.402343 6.898437.296876 13.5 3.601563 17.402343 21.597656 25.5 27.898437 65.699219 15.898437 97.796876-9.300781 24-32.699218 54.902343-92.101562 63.601562l-23.097656 3.601562c14.160156 21.367188 15.652344 23.929688 18.601562 27.296876 5.996094 8.101562 10.496094 14.101562 10.496094 30.902343zm30-8.699219v-61.5c0-17.101562-3.601562-28.5-8.402344-36.902343 45.601563-12.296876 78.003906-39.300782 92.402344-78 15.300781-40.796876 8.402344-89.398438-17.101562-123 4.503906-20.097657 4.503906-52.199219-6.296876-67.199219-4.800781-6.597657-11.402343-10.199219-19.800781-10.199219-.300781 0-.300781 0-.300781 0-23.261719 1.257812-41.570312 12.972656-61.199219 24.898438-18-4.800782-36.300781-7.199219-54.601562-7.199219-18.597657 0-37.199219 2.699219-53.695313 7.199219-20.664062-12.460938-38.796875-23.671876-62.703125-24.898438-7.5 0-14.101562 3.601562-18.902343 10.199219-10.796876 15-10.796876 47.101562-6.296876 67.199219-25.503906 33.601562-32.402343 82.5-17.101562 123 14.398438 38.699218 46.800781 65.703124 92.402344 78-3.722656 6.511718-6.667969 14.914062-7.828125 26.285156-9.210938 3.175781-17.199219 4.210937-24.628907 2.027344-7.835937-2.316407-13.941406-7.546876-19.246093-16.46875-11.914063-20.015626-32.207031-36.355469-55.3125-34.230469l2.636719 29.882812c10.699218-.980469 21.347656 10.339844 26.878906 19.671875 9.125 15.367188 21.417968 25.445313 36.546875 29.914063 11.230469 3.308593 21.496093 3.230469 32.550781.871093v40.449219c-87.300781-30.601562-151-114-151-211.800781 0-124.199219 101.800781-227 226-227s226 102.800781 226 227c0 97.800781-63.699219 181.199219-151 211.800781zm0 0"/>
</svg>
</div>
<div onclick="location.href='https://git.adb.sh/adb/'">
<svg class="logo-img" viewBox="0 0 919 919" xmlns="http://www.w3.org/2000/svg">
<path d="M 901.543,500.352 500.352,901.527 c -23.094,23.11 -60.567,23.11 -83.692,0 L 333.359,818.211 439.031,712.535 c 24.563,8.293 52.727,2.727 72.297,-16.847 19.688,-19.696 25.203,-48.102 16.699,-72.75 L 629.883,521.094 c 24.648,8.496 53.066,3.004 72.754,-16.711 27.5,-27.492 27.5,-72.059 0,-99.574 -27.52,-27.516 -72.078,-27.516 -99.61,0 -20.683,20.703 -25.8,51.097 -15.312,76.582 l -95,94.992 V 326.414 c 6.699,-3.32 13.027,-7.742 18.613,-13.312 27.5,-27.497 27.5,-72.059 0,-99.598 -27.5,-27.488 -72.09,-27.488 -99.57,0 -27.5,27.539 -27.5,72.101 0,99.598 6.797,6.789 14.668,11.925 23.066,15.363 v 252.281 c -8.398,3.438 -16.25,8.531 -23.066,15.367 -20.828,20.821 -25.84,51.395 -15.156,76.977 L 292.422,777.285 17.3242,502.211 c -23.10545,-23.129 -23.10545,-60.602 0,-83.711 L 418.535,17.3242 c 23.098,-23.10545 60.559,-23.10545 83.692,0 L 901.543,416.641 c 23.113,23.113 23.113,60.605 0,83.711"
transform="scale(1,-1) translate(0, -919)"/>
</svg>
</div>
<div onclick="location.href='https://social.adb.sh/@adb'">
<svg class="logo-img" viewBox="0 0 256 256">
<path d="M 115.05664 0 C 83.417974 0.25866667 52.984047 3.6847447 35.248047 11.830078 C 35.248047 11.830078 0.072265625 27.564666 0.072265625 81.25 C 0.072265625 93.543333 -0.16667709 108.24208 0.22265625 123.83008 C 1.4999896 176.33141 9.8473382 228.07387 58.388672 240.92188 C 80.770005 246.84588 99.986891 248.08699 115.46289 247.23633 C 143.52822 245.68033 159.2832 237.2207 159.2832 237.2207 L 158.35742 216.85742 C 158.35742 216.85742 138.30134 223.18082 115.77734 222.41016 C 93.461344 221.64482 69.902302 220.00414 66.292969 192.60547 C 65.959635 190.1988 65.792969 187.62454 65.792969 184.92188 C 65.792969 184.92187 87.700224 190.27683 115.46289 191.54883 C 132.43889 192.32749 148.35801 190.55433 164.52734 188.625 C 195.53534 184.92233 222.5344 165.81671 225.92773 148.35938 C 231.2744 120.85937 230.83398 81.25 230.83398 81.25 C 230.83398 27.564666 195.66016 11.830078 195.66016 11.830078 C 177.92549 3.6847447 147.47265 0.25866667 115.83398 0 L 115.05664 0 z M 79.25 41.947266 C 92.428667 41.947266 102.40719 47.012531 109.00586 57.144531 L 115.42188 67.898438 L 121.83789 57.144531 C 128.43522 47.012531 138.41375 41.947266 151.59375 41.947266 C 162.98308 41.947266 172.15997 45.951052 179.16797 53.761719 C 185.9613 61.572385 189.34375 72.130682 189.34375 85.416016 L 189.34375 150.41992 L 163.58984 150.41992 L 163.58984 87.326172 C 163.58984 74.026172 157.99411 67.275391 146.80078 67.275391 C 134.42478 67.275391 128.22266 75.282521 128.22266 91.117188 L 128.22266 125.65234 L 102.62109 125.65234 L 102.62109 91.117188 C 102.62109 75.282521 96.417016 67.275391 84.041016 67.275391 C 72.847682 67.275391 67.251953 74.026172 67.251953 87.326172 L 67.251953 150.41992 L 41.498047 150.41992 L 41.498047 85.416016 C 41.498047 72.130682 44.881115 61.572385 51.675781 53.761719 C 58.682448 45.951052 67.859333 41.947266 79.25 41.947266"/>
</svg>
</div>
<div onclick="location.href='https://matrix.to/#/@adb:adb.sh'">
<svg class="logo-img" style="width: 60px" viewBox="0 0 210 190">
<path d="M 8.1424685,29.681081 H 41.347757 v 13.758366 h -15.34587 v 96.903883 h 15.34587 v 13.82451 H 8.1424685 Z"/>
<path d="m 134.15059,54.419682 q 4.76251,0 9.39273,1.852088 4.63022,1.852088 8.40054,6.482307 3.04272,3.770322 4.10105,9.26044 0.66146,3.638029 0.66146,10.649505 l -0.13229,45.442298 H 137.25945 V 82.201 q 0,-4.101052 -1.32292,-6.746892 -2.51355,-5.027095 -9.26044,-5.027095 -7.80523,0 -10.7818,6.482307 -1.52135,3.439592 -1.52135,8.268249 V 128.10632 H 95.389035 V 85.177569 q 0,-6.416161 -1.32292,-9.326585 -2.381256,-5.225533 -9.326585,-5.225533 -8.069811,0 -10.847943,5.225533 -1.521358,2.97657 -1.521358,8.863563 V 128.10632 H 53.254037 V 56.139478 h 18.32244 v 10.517213 q 3.505738,-5.622409 6.6146,-8.003665 5.490117,-4.233344 14.221388,-4.233344 8.268245,0 13.361495,3.63803 4.10105,3.373446 6.21772,8.665125 3.70418,-6.350015 9.19429,-9.326585 5.82085,-2.97657 12.96462,-2.97657 z"/>
<path d="m 168.34806,140.34333 h 15.34587 V 43.174863 H 168.34806 V 29.681081 h 33.20529 V 154.16784 h -33.20529 z"/>
</svg>
</div>
<div onclick="location.href='https://www.instagram.com/alban.da'">
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="m75 512h362c41.355469 0 75-33.644531 75-75v-362c0-41.355469-33.644531-75-75-75h-362c-41.355469 0-75 33.644531-75 75v362c0 41.355469 33.644531 75 75 75zm-45-437c0-24.8125 20.1875-45 45-45h362c24.8125 0 45 20.1875 45 45v362c0 24.8125-20.1875 45-45 45h-362c-24.8125 0-45-20.1875-45-45zm0 0"/>
<path d="m256 391c74.4375 0 135-60.5625 135-135s-60.5625-135-135-135-135 60.5625-135 135 60.5625 135 135 135zm0-240c57.898438 0 105 47.101562 105 105s-47.101562 105-105 105-105-47.101562-105-105 47.101562-105 105-105zm0 0"/>
<path d="m406 151c24.8125 0 45-20.1875 45-45s-20.1875-45-45-45-45 20.1875-45 45 20.1875 45 45 45zm0-60c8.269531 0 15 6.730469 15 15s-6.730469 15-15 15-15-6.730469-15-15 6.730469-15 15-15zm0 0"/>
</svg>
</div>
<div onclick="location.href='https://open.spotify.com/user/op3q884heqao7laioz05ebaoz'">
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="m256 0c-140.960938 0-256 115.050781-256 256 0 140.960938 115.050781 256 256 256 140.960938 0 256-115.050781 256-256 0-140.960938-115.050781-256-256-256zm0 482c-124.617188 0-226-101.382812-226-226s101.382812-226 226-226 226 101.382812 226 226-101.382812 226-226 226zm0 0"/>
<path d="m99.066406 148.667969 5.195313 29.546875c109.394531-19.234375 220.378906-4.640625 317.398437 37.136718l11.863282-27.550781c-102.253907-44.035156-219.179688-59.402343-334.457032-39.132812zm0 0"/>
<path d="m103.832031 239.34375-.765625.152344 5.890625 29.417968.757813-.152343c95.839844-19.128907 197.550781-7.15625 286.394531 33.710937l12.535156-27.253906c-94.550781-43.496094-202.796875-56.238281-304.8125-35.875zm0 0"/>
<path d="m129.703125 326.050781 5.277344 29.53125c73.082031-13.058593 147.707031-4.347656 215.808593 25.203125l11.941407-27.523437c-73.539063-31.902344-154.121094-41.3125-233.027344-27.210938zm0 0"/>
</svg>
</div>
<div onclick="location.href='https://soundcloud.com/alban-david-becker'">
<svg class="logo-img" viewBox="0 -121 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="m180 0h30v270h-30zm0 0"/>
<path d="m120 90h30v180h-30zm0 0"/>
<path d="m60 60h30v210h-30zm0 0"/>
<path d="m0 150h30v120h-30zm0 0"/>
<path d="m512 180c0-49.625-40.375-90-90-90-2.542969 0-5.082031.105469-7.605469.320312-18.867187-53.082031-71.167969-90.320312-129.394531-90.320312-11.421875 0-22.773438 1.429688-33.738281 4.253906l-11.261719 2.898438v262.847656h182c49.625 0 90-40.375 90-90zm-242-148.9375c4.949219-.707031 9.964844-1.0625 15-1.0625 49.285156 0 93.097656 33.933594 104.175781 80.6875l3.5 14.773438c11.894531-2.664063 18.164063-5.460938 29.324219-5.460938 33.085938 0 60 26.914062 60 60s-26.914062 60-60 60h-152zm0 0"/>
</svg>
</div>
<div onclick="location.href='https://t.me/ADBac'">
<svg class="logo-img" viewBox="1 -35 511.99993 511" xmlns="http://www.w3.org/2000/svg">
<path d="m121.453125 253.171875 63.554687 158.886719 82.75-82.753906 141.535157 112.503906 102.707031-441.308594-512 205.480469zm-39.933594-47.640625 244.046875-97.945312-194.074218 117.363281zm287.535157-89.25-161.980469 148.1875-19.484375 73.425781-36.035156-90.085937zm-149.851563 219.230469 9.816406-36.996094 15.144531 12.035156zm171.65625 53.394531-147.386719-117.152344 221.902344-203.007812zm0 0"/>
</svg>
</div>
</div>
</div>
</div>
<h1>services I'm hosting:</h1>
<table>
<tr>
<th class="left">service</th>
<th class="right">url</th>
</tr>
<tr>
<td class="left">git</td>
<td class="right"><a href="https://git.adb.sh">git.adb.sh</a></td>
</tr>
<tr>
<td class="left">Nextcloud</td>
<td class="right"><a href="https://cloud.adb.sh">cloud.adb.sh</a></td>
</tr>
<tr>
<td class="left">Matrix</td>
<td class="right"><a href="https://chat.adb.sh">chat.adb.sh</a></td>
</tr>
<tr>
<td class="left">Element</td>
<td class="right"><a href="https://element.adb.sh">element.adb.sh</a></td>
</tr>
<tr>
<td class="left">Mastodon</td>
<td class="right"><a href="https://social.adb.sh">social.adb.sh</a></td>
</tr>
<tr>
<td class="left">email</td>
<td class="right"><a href="https://mail.adb.sh">mail.adb.sh</a></td>
</tr>
<tr>
<td class="left">Jitsi</td>
<td class="right"><a href="https://meet.adb.sh">meet.adb.sh</a></td>
</tr>
<tr>
<td class="left">Etherpad</td>
<td class="right"><a href="https://ether.adb.sh">ether.adb.sh</a></td>
</tr>
<tr>
<td class="left">short url</td>
<td class="right"><a href="https://s.adb.sh">s.adb.sh</a></td>
</tr>
<tr>
<td class="left">searx</td>
<td class="right"><a href="https://searx.adb.sh">searx.adb.sh</a></td>
</tr>
</table>
<div class="footer">
<div>&copy; 2020 Alban David Becker</div>
<div>some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from
<a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by
<a href="http://creativecommons.org/licenses/by/3.0/" target="_blank" title="Creative Commons BY 3.0">CC 3.0
BY</a>
</div>
<a href="http://bpzvci77gdvrn4grh2slh5dmz5lxrzmg7nkij7ltxht4gv4weamc4dad.onion">
more privacy?: http://bpzvci77gdvrn4grh2slh5dmz5lxrzmg7nkij7ltxht4gv4weamc4dad.onion
</a><br/>
<a href="bitcoin:bc1qaekdddmucre8yvwcy4knyhdtqs3kj5mgnk4kj6?label=adb.sh">
bitcoin:bc1qaekdddmucre8yvwcy4knyhdtqs3kj5mgnk4kj6
</a>
</div>
<script>
// TextScramble
class TextScramble {
constructor(el) {
this.el = el
this.chars = '!<>-_\\/[]{}—=+*^?#________'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({from, to, start, end})
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let {from, to, start, end, char} = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}
const phrases = [
"Hey!",
"That's my page!",
"if you like", "check out", "my social media", "below :D"
]
const el = document.querySelector('.text')
const fx = new TextScramble(el)
let counter = 0
const next = () => {
fx.setText(phrases[counter]).then(() => {
setTimeout(next, 600)
})
counter = (counter + 1) % phrases.length
}
next()
</script>
</body>
</html>

@ -1,115 +0,0 @@
worker_processes auto;
worker_cpu_affinity auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
#daemon off;
events {
worker_connections 1024;
}
http {
# rewrite_log on;
include mime.types;
default_type application/json;
access_log /var/log/nginx/access.log;
sendfile on;
# tcp_nopush on;
keepalive_timeout 3;
# tcp_nodelay on;
gzip on;
client_max_body_size 1m;
server {
listen 8080 default_server;
server_name _;
error_page 400 = @400;
location @400 { return 400 '{"status":400,"message":"Bad request"}\n'; }
error_page 401 = @401;
location @401 { return 401 '{"status":401,"message":"Unauthorized"}\n'; }
error_page 403 = @403;
location @403 { return 403 '{"status":403,"message":"Forbidden"}\n'; }
error_page 404 = @404;
location @404 { return 404 '{"status":404,"message":"Resource not found"}\n'; }
error_page 405 = @405;
location @405 { return 405 '{"status":405,"message":"Method not allowed"}\n'; }
error_page 408 = @408;
location @408 { return 408 '{"status":408,"message":"Request timeout"}\n'; }
error_page 413 = @413;
location @413 { return 413 '{"status":413,"message":"Payload too large"}\n'; }
error_page 414 = @414;
location @414 { return 414 '{"status":414,"message":"Request URI too large"}\n'; }
error_page 415 = @415;
location @415 { return 415 '{"status":415,"message":"Unsupported media type"}\n'; }
error_page 426 = @426;
location @426 { return 426 '{"status":426,"message":"HTTP request was sent to HTTPS port"}\n'; }
error_page 429 = @429;
location @429 { return 429 '{"status":429,"message":"API rate limit exceeded"}\n'; }
error_page 495 = @495;
location @495 { return 495 '{"status":495,"message":"Client certificate authentication error"}\n'; }
error_page 496 = @496;
location @496 { return 496 '{"status":496,"message":"Client certificate not presented"}\n'; }
error_page 497 = @497;
location @497 { return 497 '{"status":497,"message":"HTTP request was sent to mutual TLS port"}\n'; }
error_page 500 = @500;
location @500 { return 500 '{"status":500,"message":"Server error"}\n'; }
error_page 501 = @501;
location @501 { return 501 '{"status":501,"message":"Not implemented"}\n'; }
error_page 502 = @502;
location @502 { return 502 '{"status":502,"message":"Bad gateway"}\n'; }
location /mail {
return 302 mailto:info@adb.sh;
}
location / {
index index.html;
root /var/www/html;
try_files $uri $uri/ =404;
absolute_redirect off;
}
location =/ {
return 302 https://adb.sh/me/;
}
location =/linkedin {
return 302 https://www.linkedin.com/in/alban-david-becker-800761282/;
}
}
server {
listen 8080;
server_name alban.world;
location / {
return 302 https://adb.sh/;
}
}
server {
listen 8080;
server_name albans.world;
location / {
return 302 https://adb.sh/;
}
}
}

26945
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,29 +0,0 @@
{
"name": "adb.sh_2.0",
"version": "0.0.1",
"description": "",
"main": "index.js",
"authors": {
"name": "",
"email": ""
},
"repository": "/adb.sh_2.0",
"scripts": {
"dev": "vuepress dev src",
"build": "vuepress build src"
},
"devDependencies": {
"sass": "^1.54.9",
"sass-loader": "^10.3.1",
"vuepress": "^1.9.7",
"webpack": "^4.46.0"
},
"dependencies": {
"@vuepress/plugin-search": "^1.9.7",
"@vuepress/theme-default": "^1.9.7",
"bootstrap": "^5.2.3",
"bootstrap-darkmode": "^5.0.1",
"bootstrap-icons": "^1.10.3",
"vuepress-plugin-sitemap": "^2.3.1"
}
}

@ -1,318 +0,0 @@
/**
* Particle Network Animation https://codepen.io/franky/pen/LGMWPK
* Inspiration: https://github.com/JulianLaval/canvas-particle-network
*/
class ParticleNetworkAnimation {
constructor(element, options) {
this.$el = element;
this.container = element;
//this.canvas = document.createElement('canvas');
this.canvas = element;
this.sizeCanvas();
//this.container.appendChild(this.canvas);
this.ctx = this.canvas.getContext('2d');
this.particleNetwork = new ParticleNetwork(this, options);
this.bindUiActions();
return this;
}
bindUiActions() {
window.addEventListener('resize', () => {
this.forceUpdate();
});
}
sizeCanvas() {
this.canvas.width = this.container.offsetWidth;
this.canvas.height = this.container.offsetHeight;
}
forceUpdate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.sizeCanvas();
this.particleNetwork.createParticles();
}
}
class Particle{
constructor(parent, x, y) {
this.network = parent;
this.canvas = parent.canvas;
this.ctx = parent.ctx;
this.particleColor = returnRandomArrayitem(this.network.options.particleColors);
this.radius = getLimitedRandom(1.5, 2.5);
this.opacity = 0;
this.x = x || Math.random() * this.canvas.width;
this.y = y || Math.random() * this.canvas.height;
this.velocity = {
x: (Math.random() - 0.5) * parent.options.velocity,
y: (Math.random() - 0.5) * parent.options.velocity
};
}
update(){
if (this.opacity < 1) {
this.opacity += 0.01;
} else {
this.opacity = 1;
}
// Change dir if outside map
if (this.x > this.canvas.width + 100 || this.x < -100) {
this.velocity.x = -this.velocity.x;
}
if (this.y > this.canvas.height + 100 || this.y < -100) {
this.velocity.y = -this.velocity.y;
}
// Update position
this.x += this.velocity.x;
this.y += this.velocity.y;
}
draw(){
// Draw particle
this.ctx.beginPath();
this.ctx.fillStyle = this.particleColor;
this.ctx.globalAlpha = this.opacity;
this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
this.ctx.fill();
}
}
class ParticleNetwork{
constructor(parent, options = {
velocity: 2, // the higher the faster
density: 10000, // the lower the denser
netLineDistance: 200,
netLineColor: '#929292',
particleColors: ['#aaa'] // ['#6D4E5C', '#aaa', '#FFC458' ]
}) {
this.options = options;
this.canvas = parent.canvas;
this.ctx = parent.ctx;
this.init();
}
init(){
// Create particle objects
this.createParticles(false);
// Update canvas
this.animationFrame = requestAnimationFrame(this.update.bind(this));
this.bindUiActions();
}
createParticles(isInitial) {
// Initialise / reset particles
let me = this;
this.particles = [];
let quantity = this.canvas.width * this.canvas.height / this.options.density;
if (isInitial) {
let counter = 0;
clearInterval(this.createIntervalId);
this.createIntervalId = setInterval(function() {
if (counter < quantity - 1) {
// Create particle object
this.particles.push(new Particle(this));
}
else {
clearInterval(me.createIntervalId);
}
counter++;
}.bind(this), 250);
}
else {
// Create particle objects
for (let i = 0; i < quantity; i++) {
this.particles.push(new Particle(this));
}
}
}
createInteractionParticle() {
// Add interaction particle
this.interactionParticle = new Particle(this);
this.interactionParticle.velocity = {
x: 0,
y: 0
};
this.particles.push(this.interactionParticle);
return this.interactionParticle;
}
removeInteractionParticle() {
// Find it
let index = this.particles.indexOf(this.interactionParticle);
if (index > -1) {
// Remove it
this.interactionParticle = undefined;
this.particles.splice(index, 1);
}
}
update() {
if (this.canvas) {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalAlpha = 1;
// Draw connections
for (let i = 0; i < this.particles.length; i++) {
for (let j = this.particles.length - 1; j > i; j--) {
let distance, p1 = this.particles[i], p2 = this.particles[j];
// check very simply if the two points are even a candidate for further measurements
distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y));
if (distance > this.options.netLineDistance) {
continue;
}
// the two points seem close enough, now let's measure precisely
distance = Math.sqrt(
Math.pow(p1.x - p2.x, 2) +
Math.pow(p1.y - p2.y, 2)
);
if (distance > this.options.netLineDistance) {
continue;
}
this.ctx.beginPath();
this.ctx.strokeStyle = this.options.netLineColor;
this.ctx.globalAlpha = (this.options.netLineDistance - distance) / this.options.netLineDistance * p1.opacity * p2.opacity;
this.ctx.lineWidth = 0.7;
this.ctx.moveTo(p1.x, p1.y);
this.ctx.lineTo(p2.x, p2.y);
this.ctx.stroke();
}
}
// Draw particles
this.particles.forEach(k => {
k.update();
k.draw();
})
if (this.options.velocity !== 0) {
this.animationFrame = requestAnimationFrame(this.update.bind(this));
}
}
else {
cancelAnimationFrame(this.animationFrame);
}
}
bindUiActions() {
// Mouse / touch event handling
this.spawnQuantity = 3;
this.mouseIsDown = false;
this.touchIsMoving = false;
this.onMouseMove = function(e) {
if (!this.interactionParticle) {
this.createInteractionParticle();
}
this.interactionParticle.x = e.offsetX;
this.interactionParticle.y = e.offsetY;
}.bind(this);
this.onTouchMove = function(e) {
e.preventDefault();
this.touchIsMoving = true;
if (!this.interactionParticle) {
this.createInteractionParticle();
}
this.interactionParticle.x = e.changedTouches[0].clientX;
this.interactionParticle.y = e.changedTouches[0].clientY;
}.bind(this);
this.onMouseDown = function() {
this.mouseIsDown = true;
let counter = 0;
let quantity = this.spawnQuantity;
let intervalId = setInterval(function() {
if (this.mouseIsDown) {
if (counter === 1) {
quantity = 1;
}
for (let i = 0; i < quantity; i++) {
if (this.interactionParticle) {
this.particles.push(new Particle(this, this.interactionParticle.x, this.interactionParticle.y));
}
}
}
else {
clearInterval(intervalId);
}
counter++;
}.bind(this), 50);
}.bind(this);
this.onTouchStart = function(e) {
e.preventDefault();
setTimeout(function() {
if (!this.touchIsMoving) {
for (let i = 0; i < this.spawnQuantity; i++) {
this.particles.push(new Particle(this, e.changedTouches[0].clientX, e.changedTouches[0].clientY));
}
}
}.bind(this), 200);
}.bind(this);
this.onMouseUp = function() {
this.mouseIsDown = false;
}.bind(this);
this.onMouseOut = function() {
this.removeInteractionParticle();
}.bind(this);
this.onTouchEnd = function(e) {
e.preventDefault();
this.touchIsMoving = false;
this.removeInteractionParticle();
}.bind(this);
this.canvas.addEventListener('mousemove', this.onMouseMove);
this.canvas.addEventListener('touchmove', this.onTouchMove);
//this.canvas.addEventListener('mousedown', this.onMouseDown);
this.canvas.addEventListener('touchstart', this.onTouchStart);
this.canvas.addEventListener('mouseup', this.onMouseUp);
this.canvas.addEventListener('mouseout', this.onMouseOut);
this.canvas.addEventListener('touchend', this.onTouchEnd);
}
unbindUiActions() {
if (this.canvas) {
this.canvas.removeEventListener('mousemove', this.onMouseMove);
this.canvas.removeEventListener('touchmove', this.onTouchMove);
this.canvas.removeEventListener('mousedown', this.onMouseDown);
this.canvas.removeEventListener('touchstart', this.onTouchStart);
this.canvas.removeEventListener('mouseup', this.onMouseUp);
this.canvas.removeEventListener('mouseout', this.onMouseOut);
this.canvas.removeEventListener('touchend', this.onTouchEnd);
}
}
}
let getLimitedRandom = function(min, max, roundToInteger) {
let number = Math.random() * (max - min) + min;
if (roundToInteger) {
number = Math.round(number);
}
return number;
};
let returnRandomArrayitem = function(array) {
return array[Math.floor(Math.random()*array.length)];
};
export {
ParticleNetworkAnimation
};

@ -1,74 +0,0 @@
/*
Copyright (c) 2021 by Justin Windle (https://codepen.io/soulwire/pen/mErPAK)
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.
*/
export class TextScramble {
constructor(el) {
this.el = el
this.chars = '!<>-_\\/[]{}—=+*^?#________'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({from, to, start, end})
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let {from, to, start, end, char} = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

@ -1,130 +0,0 @@
<template>
<div class="particle-network-animation">
<canvas ref="pna" ></canvas>
<slot />
</div>
</template>
<script>
import { ParticleNetworkAnimation } from '../ParticleNetworkAnimation';
export default {
name: 'BannerWrapperNetwork',
props: {
options: {
type: Object,
default: () => ({
velocity: 0.5, // the higher the faster
density: 30000, // the lower the denser
netLineDistance: 120,
netLineColor: '#ccc',
particleColors: ['#ccc']
}),
},
},
data: () => ({
animation: null,
}),
mounted() {
setTimeout(() =>
this.animation = new ParticleNetworkAnimation(this.$refs.pna, this.options
), 1000);
},
updated() {
this.animation?.forceUpdate();
},
};
</script>
<style scoped lang="scss">
.particle-network-animation {
position: relative;
top: 0;
left: 0;
right: 0;
box-shadow: var(--shadow200);
&.white{
background-color: #fff;
}
&.no-shadow{
box-shadow: none;
}
&::before {
z-index: -2;
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-position: center center;
background-size: cover;
opacity: 0.2;
}
canvas{
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
}
.wrapper{
//pointer-events: none;
}
}
.glow {
z-index: -1;
position: fixed;
top: 50%;
left: 50%;
background-image: radial-gradient(circle closest-side, rgba(255, 255, 255, 0.025), transparent);
}
$duration: 25s;
.glow-1 {
width: 150vw;
height: 150vh;
margin-top: -75vh;
margin-left: -75vw;
animation: glow-1-move $duration linear infinite both;
}
@keyframes glow-1-move {
from {
transform: translate(-100%, 100%);
}
to {
transform: translate(100%, -100%);
}
}
.glow-2 {
width: 100vw;
height: 100vh;
margin-top: -50vh;
margin-left: -50vw;
animation: glow-2-move $duration linear $duration / 3 infinite both;
}
@keyframes glow-2-move {
from {
transform: translate(-100%, 0%);
}
to {
transform: translate(100%, 100%);
}
}
.glow-3 {
width: 120vw;
height: 120vh;
margin-top: -60vh;
margin-left: -60vw;
animation: glow-3-move $duration linear $duration / 3 * 2 infinite both;
}
@keyframes glow-3-move {
from {
transform: translate(100%, 100%);
}
to {
transform: translate(0%, -100%);
}
}
</style>

@ -1,60 +0,0 @@
<template>
<transition name="fade">
<a
class="btn currentlyListening"
href=" https://spot2gether.cybre.town/user/op3q884heqao7laioz05ebaoz"
target="_blank"
ref="noopener noreferrer"
v-if="currentlyPlaying?.item"
>
<div class="row align-items-center">
<i class="bi-music-note col-auto icon" />
<div class="col-auto d-flex flex-column text">
<b>{{ currentlyPlaying?.item?.name }}</b>
<div>{{ currentlyPlaying?.item?.artists.map(artist => artist.name).join(', ') }}</div>
</div>
</div>
</a>
</transition>
</template>
<script>
let updateMusicInfo = null;
const noob = () => null;
export default {
name: "CurrentlyListening",
data: () => ({
currentlyPlaying: null,
}),
methods: {
async fetchMusicInfo() {
return await fetch(
'https://spot2gether.cybre.town/api/public/users/op3q884heqao7laioz05ebaoz/info'
).then(data => data.json());
}
},
async mounted() {
this.currentlyPlaying = (await this.fetchMusicInfo().catch(noob))?.currentlyPlaying;
updateMusicInfo = setInterval(async () => {
this.currentlyPlaying = (await this.fetchMusicInfo().catch(noob))?.currentlyPlaying;
}, 10000);
},
beforeDestroy() {
clearInterval(updateMusicInfo);
},
};
</script>
<style lang="scss">
.currentlyListening {
position: relative;
.icon {
font-size: 1.2rem;
}
.text {
font-size: .8rem;
text-align: left !important;
}
}
</style>

@ -1,32 +0,0 @@
<template>
<div v-if="active">
<slot />
</div>
<div v-else class="card">
<div class="card-body">
<div>
<slot name="lock">
<p v-if="name">Click to load external content from {{ name }}.</p>
<p v-else>Click to load external content.</p>
</slot>
</div>
<button class="btn btn-primary" @click="active = true">load content</button>
</div>
</div>
</template>
<script>
export default {
name: "ExternalContentWrapper",
props: {
name: String,
},
data: () => ({
active: false,
}),
}
</script>
<style scoped>
</style>

@ -1,28 +0,0 @@
<template>
<ul>
<slot
v-for="page of $site.pages
.filter(page => page.regularPath.match(new RegExp(`^${ path }.`)))
.slice(0, limit)
"
:page="page"
>
<li>
<router-link :to="page.regularPath">{{ page.title }}</router-link>
</li>
</slot>
</ul>
</template>
<script>
export default {
name: "FolderList",
props: {
path: String,
limit: {
type: Number,
default: 8,
},
},
};
</script>

@ -1,25 +0,0 @@
<template>
<div>
<div>
<CurrentlyListening />
<StickyWrapper>
<TextScramble :phrases="[
'Hey!',
'Welcome to adb.sh :D',
'I do web development', 'networking / hosting', 'electronics', 'DJing / music',
]" />
<SocialIcons />
<div class="row my-4 justify-content-center">
<router-link class="col-auto mx-2 btn btn-outline-light" to="/projects" >projects</router-link>
<router-link class="col-auto mx-2 btn btn-outline-light" to="/music" >music</router-link>
</div>
</StickyWrapper>
</div>
</div>
</template>
<script>
export default {
name: "HomeContent",
}
</script>

@ -1,37 +0,0 @@
<template>
<div class="SocialIcons row">
<a class="col-auto btn bi-github" href="https://github.com/adb-sh/" target="_blank" rel="noopener noreferrer" />
<a class="col-auto btn bi-git" href="https://git.cybre.town/adb" target="_blank" rel="noopener noreferrer" />
<a class="col-auto btn bi-mastodon" href="https://social.cybre.town/@adb" target="_blank" rel="noopener noreferrer" />
<a class="col-auto btn bi-instagram" href="https://www.instagram.com/me.adb.sh" target="_blank" rel="noopener noreferrer" />
<a class="col-auto btn bi-spotify" href="https://open.spotify.com/user/op3q884heqao7laioz05ebaoz" target="_blank" rel="noopener noreferrer" />
<a class="col-auto btn bi-youtube" href="https://www.youtube.com/channel/UCoxRdN8T4aCR8tqDpOJAjOQ" target="_blank" rel="noopener noreferrer" />
</div>
</template>
<style scoped lang="scss">
.SocialIcons {
position: relative;
user-select: none;
width: 100%;
display: flex;
justify-content: center;
a.btn {
font-size: calc(1.5rem + 1vw);
max-font-size: 2.5rem;
}
}
.social_icons > div {
position: relative;
display: inline-block;
height: min-content;
cursor: pointer;
}
.logo-img {
fill: #fff;
height: 3rem;
margin: .75rem;
}
</style>

@ -1,20 +0,0 @@
<template>
<div class="StickyWrapper">
<slot name="top"/>
<div class="content">
<slot />
</div>
</div>
</template>
<style scoped lang="scss">
.StickyWrapper {
position: relative;
height: 100vh;
.content {
position: sticky;
top: 50%;
transform: translate(0, -50%);
}
}
</style>

@ -1,38 +0,0 @@
<script>
import { TextScramble } from "../TextScramble.mjs";
export default {
props: {
phrases: Array,
},
mounted() {
const el = this.$refs.TextScramble;
const fx = new TextScramble(el);
let counter = 0
const next = () => {
fx.setText(this.phrases[counter]).then(() => setTimeout(next, 600));
counter = (counter + 1) % this.phrases.length;
}
next();
}
};
</script>
<template>
<div class="TextScramble my-4" ref="TextScramble"></div>
</template>
<style lang="scss">
.TextScramble {
font-size: calc(1.5rem + 1vw);
max-font-size: 2.5rem;
text-align: center;
font-family: "Roboto Mono", monospace;
font-weight: 100;
.dud {
color: #166161;
}
}
</style>

@ -1,51 +0,0 @@
module.exports = {
title: '0xADB',
description: 'Welcome to adb.sh',
head: [
['meta', { name: 'theme-color', content: '#3eaf7c' }],
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
['meta', { name: 'author', content: 'Alban David Becker' }],
['meta', { name: 'publisher', content: 'Alban David Becker' }],
['meta', { name: 'copyright', content: 'Alban David Becker' }],
['meta', { name: 'keywords', content: 'Alban, David, Becker, web development, development, hosting, open source, FOSS, music, DJ' }],
['meta', { name: 'page-type', content: 'Private Homepage' }],
['meta', { name: 'robots', content: 'follow' }],
['meta', { 'http-equiv': 'content-language', content: 'en' }],
],
markdown: {
anchor: { permalink: false },
extendMarkdown: md => {
md.set({ breaks: true });
}
},
dest: "./dist",
themeConfig: {
repo: '',
editLinks: false,
docsDir: '',
editLinkText: '',
lastUpdated: false,
searchMaxSuggestions: 10,
searchHotkeys: ['s', 'k', '/'],
searchPlaceholder: 'Ctrl + S',
test: [/.+.md/],
nav: [
{
text: 'projects',
link: '/projects',
},
{
text: 'music',
link: '/music',
},
],
},
plugins: {
'@vuepress/plugin-search': {},
'vuepress-plugin-sitemap': {
hostname: 'https://adb.sh/',
exclude: ['/404.html'],
}
}
}

@ -1,21 +0,0 @@
const matchPath = /(?<path>|.+)\/(?<filename>[-_\w]+)(?<filetype>|\/|\.html|\.md)$/;
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
router.beforeEach((to, from, next) => {
if (to.path === '/') next('/me');
if (!to.name) {
const { filename } = to.fullPath.match(matchPath).groups;
next(
siteData.pages
.find((page) => page.regularPath.match(matchPath)?.groups?.filename === filename)
?.regularPath
);
}
next();
});
};

@ -1,8 +0,0 @@
/**
* Custom Styles here.
*
* refhttps://v1.vuepress.vuejs.org/config/#index-styl
*/
.home .hero img
max-width 450px!important

@ -1,10 +0,0 @@
/**
* Custom palette here.
*
* refhttps://v1.vuepress.vuejs.org/zh/config/#palette-styl
*/
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34

@ -1,92 +0,0 @@
<template>
<div class="app">
<div class="background">
<img src="../assets/background.jpg" alt="">
</div>
<section class="layout" data-theme="dark">
<header>
<div class="bg-dark-opacity1 shadow">
<site-header class="container" />
</div>
</header>
<main class="content">
<BannerWrapperNetwork v-if="!$page.frontmatter?.disableAnimation" class="background bg-opacity-50" />
<div v-if="$page.frontmatter?.sidebar" class="container">
<div class="row">
<div class="col-xl-4 p-4">
<div class="card toc">
<div class="card-header">
<router-link :to="`/${$page.path.split('/')[1]}/`"><b>/{{ $page.path.split('/')[1] }}/</b></router-link>
</div>
<div class="card-body">
<FolderList :path="`/${$page.path.split('/')[1]}/`" />
</div>
</div>
</div>
<Content class="col-xl-8 p-4" />
</div>
</div>
<div v-else>
<div class="container">
<Content class="p-4" />
</div>
</div>
</main>
<footer class="footer py-3">
<site-footer class="container" />
</footer>
</section>
</div>
</template>
<script>
import SiteHeader from "./SiteHeader";
import SiteFooter from "./SiteFooter";
import FolderList from "../components/FolderList";
import "bootstrap-icons/font/bootstrap-icons.scss";
import "./main.scss";
import "@vuepress/theme-default/styles/code.styl";
import BannerWrapperNetwork from "../components/BannerWrapperNetwork";
export default {
components: {BannerWrapperNetwork, SiteFooter, SiteHeader, FolderList },
};
</script>
<style scoped lang="scss">
.layout {
position: relative;
min-height: 100vh;
}
header {
position: fixed;
z-index: 10;
width: 100%;
font-size: 1.2rem;
}
main.content {
padding: 5rem 0 2rem 0;
.toc {
position: sticky;
top: 5rem;
}
.container {
position: relative;
}
}
.background {
height: 100vh;
width: 100%;
position: fixed;
top: 0;
img {
height: 100%;
width: 100%;
object-fit: cover;
}
}
</style>

@ -1,14 +0,0 @@
<template>
<div class="m-4">
<h1>404 Not Found</h1>
<router-link class="btn btn-primary" to="/">Zur Startseite</router-link>
</div>
</template>
<script>
import "bootstrap/scss/bootstrap.scss";
export default {
name: "NotFound"
}
</script>

@ -1,7 +0,0 @@
<template>
<div class="footer border-top py-2">
<span class="copyright">Copyright © {{ (new Date).getFullYear() }} Alban David Becker</span>
</div>
</template>
<style scoped></style>

@ -1,66 +0,0 @@
<template>
<nav class="navbar px-4">
<router-link class="btn d-flex" to="/me">
<div class="flex-column justify-content-center">
<b>{{ $site.title }}</b>
</div>
</router-link>
<div class="row align-items-center">
<SearchBox class="col-auto" />
<div v-for="nav of $site.themeConfig.nav" class="col-auto d-none d-xl-block">
<div v-if="nav.children || nav.path" class="category dropdown">
<router-link :to="nav.link" class="link btn">{{ nav.text }} <i class="bi-chevron-down" /></router-link>
<div class="dropdown-menu">
<router-link
v-for="site of (nav.children ?? [])
.concat(nav.path
? $site.pages
.filter(page => page.regularPath.match(new RegExp(`${nav.path}.`)))
.map(page => ({ text: page.title, link: page.regularPath }))
: []
)
"
:to="site.link"
class="dropdown-item"
>
{{ site.text }}
</router-link>
</div>
</div>
<div v-else class="site">
<router-link :to= "nav.link" class="link btn">{{ nav.text }}</router-link>
</div>
</div>
</div>
</nav>
</template>
<script>
import SearchBox from "@vuepress/plugin-search/SearchBox";
export default {
components: { SearchBox },
};
</script>
<style scoped lang="scss">
.header-title {
color: black;
}
.header-img {
height: 3.5rem;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.dropdown-item {
}
.link {
color: rgb(27, 29, 29);
}
</style>

@ -1,19 +0,0 @@
/* roboto-mono-100 - latin */
@font-face {
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 100;
src: local(''),
url('../assets/fonts/roboto-mono-v22-latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('../assets/fonts/roboto-mono-v22-latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* roboto-mono-regular - latin */
@font-face {
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 400;
src: local(''),
url('../assets/fonts/roboto-mono-v22-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('../assets/fonts/roboto-mono-v22-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

@ -1,71 +0,0 @@
$dark: #1f262b;
$dark-opacity1: #1f262be8;
$dark-opacity2: #1f262b80;
$dark-body-bg: $dark-opacity1;
@import "bootstrap/scss/bootstrap";
@import "bootstrap-darkmode/scss/darktheme";
@import "fonts.css";
html, body {
background-color: $dark-body-bg;
line-break: loose;
word-break: break-word;
}
img {
max-width: 100% !important;
border-radius: .25rem;
margin: 0.125rem;
}
table {
@extend .table;
}
.search-box{
input {
background-color: unset !important;
color: $light !important;
}
}
h1, h2, h3, h4, h5 {
margin-top: 1em;
}
:not(pre) > code {
background-color: #aaa2;
border-radius: .4rem;
padding: .2rem .4rem;
}
[data-theme="dark"] .card {
background-color: $dark-opacity2 !important;
}
.bg-dark {
background-color: $dark !important;
}
.bg-dark-opacity1 {
background-color: $dark-opacity1 !important;
}
.bg-dark-opacity2 {
background-color: $dark-opacity2 !important;
}
.fade-enter-active, .fade-leave-active {
transition-property: opacity;
transition-duration: .25s;
}
.fade-enter-active {
transition-delay: .25s;
}
.fade-enter, .fade-leave-active {
opacity: 0
}

@ -1,86 +0,0 @@
---
home: true
meta:
- name: description
content: Alban David Becker - Web Development, DevOps, Engineering, Hosting, Music
- name: keywords
content: Alban, David, Becker, web development, devops, development, hosting, open source, FOSS
- name: robots
content: index, follow
---
<HomeContent />
---
## :smile: About me
- studying Applied Informatics in North of Germany
- working at [Zenner IOT](https://zenner-iot.com/)
- volunteering at [DD-IX - Dresden Internet Exchange](https://dd-ix.net/)
### :rocket: My Tech Stack
#### WebDev
![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white)![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white)![Bootstrap](https://img.shields.io/badge/bootstrap-%238511FA.svg?style=for-the-badge&logo=bootstrap&logoColor=white)![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E)![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)![Vue.js](https://img.shields.io/badge/vuejs-%2335495e.svg?style=for-the-badge&logo=vuedotjs&logoColor=%234FC08D)![Nuxtjs](https://img.shields.io/badge/Nuxt-002E3B?style=for-the-badge&logo=nuxtdotjs&logoColor=#00DC82)![SolidJS](https://img.shields.io/badge/SolidJS-2c4f7c?style=for-the-badge&logo=solid&logoColor=c8c9cb)![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB)![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white)![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB)![Deno JS](https://img.shields.io/badge/deno%20js-000000?style=for-the-badge&logo=deno&logoColor=white)![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)![Django](https://img.shields.io/badge/django-%23092E20.svg?style=for-the-badge&logo=django&logoColor=white)
#### DevOps
![Debian](https://img.shields.io/badge/Debian-D70A53?style=for-the-badge&logo=debian&logoColor=white)![Arch](https://img.shields.io/badge/Arch%20Linux-1793D1?logo=arch-linux&logoColor=fff&style=for-the-badge)![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)![Kubernetes](https://img.shields.io/badge/kubernetes-%23326ce5.svg?style=for-the-badge&logo=kubernetes&logoColor=white)![Ansible](https://img.shields.io/badge/ansible-%231A1918.svg?style=for-the-badge&logo=ansible&logoColor=white)![Nix](https://img.shields.io/badge/NIX-5277C3.svg?style=for-the-badge&logo=NixOS&logoColor=white)
![MariaDB](https://img.shields.io/badge/MariaDB-003545?style=for-the-badge&logo=mariadb&logoColor=white)![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white)![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white)![Redis](https://img.shields.io/badge/redis-%23DD0031.svg?style=for-the-badge&logo=redis&logoColor=white)
#### UI/UX
![Adobe InDesign](https://img.shields.io/badge/Adobe%20InDesign-49021F?style=for-the-badge&logo=adobeindesign&logoColor=white)![Adobe Illustrator](https://img.shields.io/badge/adobe%20illustrator-%23FF9A00.svg?style=for-the-badge&logo=adobe%20illustrator&logoColor=white)![Adobe Photoshop](https://img.shields.io/badge/adobe%20photoshop-%2331A8FF.svg?style=for-the-badge&logo=adobe%20photoshop&logoColor=white)![Adobe Premiere Pro](https://img.shields.io/badge/Adobe%20Premiere%20Pro-9999FF.svg?style=for-the-badge&logo=Adobe%20Premiere%20Pro&logoColor=white)![Figma](https://img.shields.io/badge/figma-%23F24E1E.svg?style=for-the-badge&logo=figma&logoColor=white)
## Services I'm hosting
<div class="alert alert-warning" role="alert">
* WARNING!: Planned downtime from <code>12.01.2024 8:00</code> to <code>13.01.2024 23:59</code> due to server relocation!
</div>
### :rocket: Public services
| service | URL |
| ---------- | ---------------------------------------------- |
| Gitea\* | [git.cybre.town](https://git.cybre.town) |
| Drone\* | [drone.cybre.town](https://drone.cybre.town) |
| Mastodon\* | [social.cybre.town](https://social.cybre.town) |
| HedgeDoc\* | [md.cybre.town](https://md.cybre.town) |
<!-- | Jitsi | [meet.adb.sh](https://meet.adb.sh) | -->
<!-- | Frama Date | [polls.cybre.town](https://polls.cybre.town) | -->
<!-- | Peertube | [video.cybre.town](https://video.cybre.town) | -->
<!-- | Searx | [searx.cybre.town](https://searx.cybre.town) | -->
<!-- | Penpot | [penpot.cybre.town](https://penpot.cybre.town) | -->
### :lock: Private services
| service | URL |
| ----------- | ------------------------------------------ |
| Nextcloud\* | [cloud.adb.sh](https://cloud.adb.sh) |
| Matrix\* | [adb.sh](https://adb.sh/_matrix/static/) |
| Mail | [mail.adb.sh](https://mail.adb.sh) |
| Gotify UP\* | [push.cybre.town](https://push.cybre.town) |
### :globe_with_meridians: Other sites
| service | URL |
| --------------------------------- | -------------------------------------------------- |
| Cybre Town\* | [cybre.town](https://cybre.town) |
| Strobe Town\* | [strobe.town](https://strobe.town) |
| Strobe Town - Tickets (Pretix)\* | [tickets.strobe.town](https://tickets.strobe.town) |
| Strobe Town - Music (Funkwhale)\* | [music.strobe.town](https://music.strobe.town) |
## :mailbox_with_mail: Contact me
- Matrix: [@adb:adb.sh](https://matrix.to/#/@adb:adb.sh)
- Mail: info [at] this.domain
## :coffee: Buy me a coffee ^-^
- Liberapay: [liberapay/adb.sh](https://liberapay.com/adb.sh)
- Bitcoin: [BC1QGP24D6GKPM4TEZ4ZRT3KZGKHYUJQUV68PTAXKQ](bitcoin:BC1QGP24D6GKPM4TEZ4ZRT3KZGKHYUJQUV68PTAXKQ)
- PayPal: [paypal.me/ad2b](https://paypal.me/ad2b)

@ -1,54 +0,0 @@
---
meta:
- name: description
content: I do music and DJing
- name: keywords
content: Alban, David, Becker, music, techno, melodic techno, DJ, djing
---
# Music
i do music 'n' stuff
## DJ sets
### CSD Magdeburg Aftershow at Insel der Jugend 2023
<ExternalContentWrapper name="Mixcloud">
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Fcsd-magedburg-aftershow-at-insel-der-jugend%2F" frameborder="0" ></iframe>
</ExternalContentWrapper>
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/csd-magedburg-aftershow-at-insel-der-jugend/)
### Rainbow Rave - Alte Meierei | 27.05.2023
<ExternalContentWrapper name="Mixcloud">
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Frainbow-rave-alte-meierei%2F" frameborder="0" ></iframe>
</ExternalContentWrapper>
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/rainbow-rave-alte-meierei/)
### Insel der Jugend at Magdeburg - 0xADB b2b Supermomme | 30.04.2023
<ExternalContentWrapper name="Mixcloud">
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Finsel-der-jugend-at-magdeburg-0xadb-b2b-supermomme-3042023%2F" frameborder="0" ></iframe>
</ExternalContentWrapper>
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/insel-der-jugend-at-magdeburg-0xadb-b2b-supermomme-3042023/)
### Alte Meierei Kiel - opening set from 2022.11.26
<ExternalContentWrapper name="Mixcloud">
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Falte-meierei-kiel-opening-set-from-20221126%2F" frameborder="0" ></iframe>
</ExternalContentWrapper>
Listen on [Mixcloud]https://www.mixcloud.com/0xADB/alte-meierei-kiel-opening-set-from-20221126/)
### jam some techno
<ExternalContentWrapper name="YouTube">
<iframe width="100%" height="540" src="https://www.youtube-nocookie.com/embed/A0nvVXpzJD8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</ExternalContentWrapper>
watch on [YouTube](https://youtu.be/A0nvVXpzJD8)
### lemme stream some melodic techno or so
<ExternalContentWrapper name="YouTube">
<iframe width="100%" height="540" src="https://www.youtube-nocookie.com/embed/6bOJGkaX_5s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</ExternalContentWrapper>
watch on [YouTube](https://youtu.be/6bOJGkaX_5s)

@ -1,20 +0,0 @@
---
sidebar: true
excerpt: "Art-Net to DMX PCB"
imgUrl: "https://social.cybre.town/system/media_attachments/files/105/520/482/627/757/197/original/ba1084550d15d53f.jpeg"
meta:
- name: description
content: Art-Net to DMX PCB
- name: keywords
content: Alban, David, Becker, ArtNet, development, embedded systems, hardware, Arduino, KiCad, pcb
---
# ArtNet-Node
Art-Net to DMX PCB
![pcb stack](https://social.cybre.town/system/media_attachments/files/105/520/482/627/757/197/original/ba1084550d15d53f.jpeg)
[social.cybre.town](https://social.cybre.town/@adb/105520488438390411)
![some soldered pcbs](https://social.cybre.town/system/media_attachments/files/105/933/932/633/113/971/original/42bdd85a644fd2ee.png)
[social.cybre.town](https://social.cybre.town/@adb/105933977138735045)

@ -1,82 +0,0 @@
---
sidebar: true
excerpt: "a simple reactive runtime JS framework inspired by Vue"
meta:
- name: description
content: a simple reactive runtime JS framework inspired by Vue
- name: keywords
content: Alban, David, Becker, dynaticjs, dav, web, javascript, framework
---
# dynaticjs
a simple reactive runtime JS framework inspired by Vue
## about
- stack: js
- repo: [github.com](https://github.com/adb-sh/dynaticjs)
- boilerplate repo: [github.com](https://github.com/adb-sh/dynaticjs-boilerplate)
- npm: [npmjs.com](https://www.npmjs.com/package/dynaticjs)
## current features
- dynamic router
- components (recursive)
- data binding (from component to component)
- trigger rerender components on data change
- scoped references to DOM elements
## simple component example
```javascript
import Component from "dynaticjs/Component";
import { propFactory } from "dynaticjs/helpers.js";
import RouterLink from "dynaticjs/components/RouterLink.js";
import RouterView from "dynaticjs/components/RouterView.js";
import Home from "./pages/Home.js";
export default class App extends Component {
init() {
return {
components: {
RouterLink,
RouterView,
},
};
}
data() {
return {
routes: propFactory([
{
name: 'home',
title: 'Home',
path: '/',
Component: Home,
},
]),
};
}
render(state) {
return `
<div id="app">
<nav ref="nav">
<router-link class="btn btn-primary" to="home">Home</router-link>
<router-link class="btn btn-primary" to="about">About</router-link>
</nav>
<main>
<h1>DynaticJS Boilerplate</h1>
<router-view bind:routes="routes"></router-view>
</main>
</div>
`;
}
setup() {
console.log("Hello World :D");
console.log("#app element", this.$el); //corresponding DOM element
console.log("nav element", this.$refs.nav); //scoped reference to DOM element with the attribute `ref="nav"`
console.log("child components in App", this.$components) //references to child components
}
};
```
[full example](https://github.com/adb-sh/dynaticjs-boilerplate/blob/master/src/App.js)

@ -1,43 +0,0 @@
---
sidebar: true
excerpt: "the validation tool nobody asked for"
meta:
- name: description
content: the validation tool nobody asked for
- name: keywords
content: Alban, David, Becker, deno, web, javascript
---
# hoyams
the validation tool nobody asked for | hoyams = hold on you are missing something
- stack: deno, typescript
- repo: [github.com](https://github.com/adb-sh/hoyams)
- deno package: [deno.land](https://deno.land/x/hoyams)
## Concept
Rules are defined via a callback which retuns `true` or an error String. This is
so that you can define rules by using an or operator like this:
```javascript
new Rule((v) => typeof v === "string" || "is not a string");
```
or this:
```javascript
new Rule((v) =>
typeof v === "string" && !!v.match(/^\w+@\w+\.\w+$/) ||
"no valid email"
);
```
- If a executing a validation completes without an error an object with the same
structure as the object given is returned.
- For creating powerful nested object rules there are some primites given:
[How to use](https://deno.land/x/hoyams@v0.0.1#how-to-use)

@ -1,18 +0,0 @@
---
meta:
- name: description
content: recent projects from me
- name: keywords
content: Alban, David, Becker, projects, development, software, embedded systems, hardware
---
# Projects
<FolderList path="/projects/" v-slot="{ page }" class="m-0 p-0">
<div class="card my-2">
<div class="card-header"><router-link :to="page.regularPath">{{ page.title }}</router-link></div>
<div class="card-body">
{{ page.frontmatter.excerpt }}
</div>
</div>
</FolderList>

@ -1,20 +0,0 @@
---
sidebar: true
excerpt: "a simple matrix webapp for mobile and desktop"
imgUrl: "https://chat.adb.sh/media/screenshot-desktop.png"
meta:
- name: description
content: a simple matrix webapp for mobile and desktop
- name: keywords
content: Alban, David, Becker, matrix, matrix-chat, chat, federation, vue, web, javascript
---
# **[chat]** *matrix-chat*
a simple matrix webapp for mobile and desktop
![matrix-chat screenshot](../.vuepress/assets/images/matrix-chat.png)
- stack: Vue3, matrix-js-sdk
- matrix.org: [matrix.org](https://matrix.org/docs/projects/client/chat)
- repo: [git.cybre.town](https://git.cybre.town/adb/matrix-chat)

@ -1,24 +0,0 @@
---
sidebar: true
excerpt: "I'm running my services on my own server, because it's fun :D"
imgUrl: "../.vuepress/assets/images/server.jpg"
meta:
- name: description
content: my home server rack
- name: keywords
content: Alban, David, Becker, server, hosting, networking, development, devops
---
# WLED nightlight
a little wled 5x5 led matrix
- esp8266
- 5x5 ws2812b leds
![](../.vuepress/assets/images/nightlight-front.png)
![](../.vuepress/assets/images/nightlight-back.png)
- stack: kicad
- repo: [github.com](https://github.com/adb-sh/nightlight)

@ -1,34 +0,0 @@
---
sidebar: true
excerpt: "I'm running my services on my own server, because it's fun :D"
imgUrl: "../.vuepress/assets/images/server.jpg"
meta:
- name: description
content: my home server rack
- name: keywords
content: Alban, David, Becker, server, hosting, networking, development, devops
---
# My Server Rack
I'm running my services on my own server, because it's fun :D
![server rack](../.vuepress/assets/images/server.jpg)
## rack:
### PfSense router
- Pentium(R) Dual-Core CPU E5300 @ 2.60GHz
- 2GB RAM
- 8 interfaces
### 1. HP ProLiant DL380e G8
- 2x Intel(R) Xeon(R) CPU E5-2450L 0 @ 1.80GHz - (32 threads in summary)
- 32GB RAM
- Proxmox
- 4x 4TB HDD
- 1x 500GB SSD
### 2. HP ProLiant DL380e G8
- 2x Intel(R) Xeon(R) CPU E5-2450L 0 @ 1.80GHz - (32 threads in summary)
- 64GB RAM
- FreeNAS
- 2x 8TB HDD
- 1x 500GB SSD

@ -1,131 +0,0 @@
---
sidebar: true
excerpt: "a complete working docker-compose setup for the matrix synapse server with postgres"
meta:
- name: description
content: a complete working docker-compose setup for the matrix synapse server with postgres
- name: keywords
content: Alban, David, Becker, matrix, synapse, docker, docker compose, devops
---
# docker-compose matrix-synapse
a complete working docker-compose setup for the matrix synapse server with postgres
## clone the repo
```bash
git clone https://git.cybre.town/adb/docker-compose_matrix_synapse/
```
## create config files
* Change `your.domain` in the `create_config.sh` file and simply run the script from terminal.
* A temporary docker container will be created, that will configure the configs for you.
* You will find your finished configs at `/var/lib/docker/volumes/synapse-data/_data`.
* Copy this files to `./synapse_data/` in your docker-compose working directory.
for more details have a look at: [hub.docker.com/r/matrixdotorg/synapse](https://hub.docker.com/r/matrixdotorg/synapse)
## configure `./synapse_data/homserver.yaml`
### database
* comment the standard sqlite3 config
* just below add:
```yaml
database:
name: psycopg2
args:
user: matrix
password: your-secret-pw
database: synapse
host: db
cp_min: 5
cp_max: 10
```
* change the password
### registration
* to enable user registration comment out this line: `enable_registration: true`
## configure `docker-compose.yml`
* change the postgres password to the password you've set before.
## create docker containers
```bash
cd /your/docker-compose/working/directory
docker-compose -p matrix up -d
```
If you can see the congrats page at `http://127.0.0.1:8008/` everything is working. This might take a few minutes, as the database has to be created.
## nginx config
To manage SSL/TLS I'm using nginx.
Just add another path to your working SSL v-host server, like this:
```nginx
#matrix server
#For the federation port
listen 8448 ssl default_server;
listen [::]:8448 ssl default_server;
location /_matrix {
proxy_pass http://127.0.0.1:8008;
proxy_set_header X-Forwarded-For $remote_addr;
# Nginx by default only allows file uploads up to 1M in size
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
client_max_body_size 10M;
}
```
The full v-host server config might look like:
```nginx
server {
server_name your.domain;
#main web server
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
root /var/www/your.domain;
index index.html;
#matrix server
#For the federation port
listen 8448 ssl default_server;
listen [::]:8448 ssl default_server;
location /_matrix {
proxy_pass http://127.0.0.1:8008;
proxy_set_header X-Forwarded-For $remote_addr;
# Nginx by default only allows file uploads up to 1M in size
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
client_max_body_size 10M;
}
ssl_certificate /etc/letsencrypt/live/your.domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
if ($host = your.domain) {
return 302 https://$host$request_uri;
}
listen 80;
listen [::]:80;
server_name your.domain;
return 404;
}
```
//and that's it, good luck :D

@ -1,16 +0,0 @@
---
sidebar: true
excerpt: "a simple webdav client in Vue3"
meta:
- name: description
content: a simple webdav client in Vue3
- name: keywords
content: Alban, David, Becker, vuedav, cloud, dav, vue, web, javascript, node, typescript
---
# vuedav
a simple webdav client in Vue3
- stack: Vue3, nginx, docker, nodejs, typescript
- repo: [git.cybre.town](https://git.cybre.town/adb/vuedav)
Loading…
Cancel
Save