chore(katenary): Use the new organization repository
This commit is contained in:
6
.posthtmlrc
Normal file
6
.posthtmlrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugins": {
|
||||
"posthtml-doctype": { "doctype": "HTML 5" },
|
||||
"posthtml-include": {}
|
||||
}
|
||||
}
|
24
Makefile
Normal file
24
Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
RELEASE=website
|
||||
NS=katenary
|
||||
|
||||
build: dist chart
|
||||
|
||||
chart: dist
|
||||
katenary convert -f -p deploy
|
||||
|
||||
dist: $(wildcard src/* compose.yaml)
|
||||
rm -rf dist
|
||||
podman run --rm -it -u $(id -u):$(id -g) -v $(PWD):/app -w /app node:alpine sh -c "yarn install && yarn parcel build --no-source-maps"
|
||||
|
||||
deploy:
|
||||
helm -n $(NS) upgrade --install $(RELEASE) ./chart/ -f override.yaml --create-namespace
|
||||
sleep 1
|
||||
$(MAKE) add-redirect
|
||||
kubectl -n $(NS) rollout restart deployment $(RELEASE)-server
|
||||
|
||||
add-redirect:
|
||||
kubectl -n $(NS) apply -f <(./venv/bin/python add-domain.py)
|
||||
|
||||
serve:
|
||||
rm -rf dist
|
||||
podman compose up
|
74
add-domain.py
Normal file
74
add-domain.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Script to add a domain without tht "www" and force redirect to www with TLS
|
||||
|
||||
To apply the changes to the cluster, you can use the following command:
|
||||
|
||||
kubectl -n <NAMESPACE> apply -f <(python add-domain.py)
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def get_ingress(ns: str, name: str) -> dict:
|
||||
"""Get the ingress object from the cluster"""
|
||||
process = subprocess.Popen(
|
||||
["kubectl", "get", "ingress", "-n", ns, name, "-o", "yaml"],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
stdout, _ = process.communicate()
|
||||
return yaml.safe_load(stdout)
|
||||
|
||||
|
||||
def tranform(name: str, ns: str, domain: str) -> dict:
|
||||
"""Return the transformed ingress object"""
|
||||
|
||||
# get the ingress content
|
||||
ingress = get_ingress(ns, name)
|
||||
|
||||
# remove all nginx annotations
|
||||
ingress["metadata"]["annotations"] = {
|
||||
k: v for k, v in ingress["metadata"]["annotations"].items() if "nginx" not in k
|
||||
}
|
||||
|
||||
# change the name of the ingress
|
||||
ingress["metadata"]["name"] = f"{name}-redirect"
|
||||
|
||||
# add nginx.ingress.kubernetes.io/permanent-redirect annotation
|
||||
ingress["metadata"]["annotations"].update(
|
||||
{"nginx.ingress.kubernetes.io/permanent-redirect": f"https://www.{domain}"}
|
||||
)
|
||||
|
||||
# change hostname
|
||||
ingress["spec"]["tls"][0]["hosts"] = [domain]
|
||||
ingress["spec"]["rules"][0]["host"] = domain
|
||||
|
||||
# change the secret name
|
||||
ingress["spec"]["tls"][0]["secretName"] = f"{name}-redirect"
|
||||
|
||||
# cleanup the metadata
|
||||
ingress.pop("status")
|
||||
to_remove = [
|
||||
"creationTimestamp",
|
||||
"generation",
|
||||
"resourceVersion",
|
||||
"selfLink",
|
||||
"uid",
|
||||
]
|
||||
for meta in to_remove:
|
||||
ingress["metadata"].pop(meta) if meta in ingress["metadata"] else None
|
||||
|
||||
# print the new yaml content
|
||||
return ingress
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
name = os.getenv("NAME", "website-server") # name of the ingress
|
||||
ns = os.getenv("NAMESPACE", "katenary") # namespace
|
||||
domain = os.getenv("DOMAIN", "katenary.org") # domain name without www
|
||||
transformed = tranform(name, ns, domain)
|
||||
|
||||
print(yaml.dump(transformed))
|
14
compose.katenary.yaml
Normal file
14
compose.katenary.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
server:
|
||||
image: docker.io/nginx
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
- ./dist:/usr/share/nginx/html
|
||||
labels:
|
||||
katenary.v3/ingress: |-
|
||||
hostname: katenary.org
|
||||
port: 80
|
||||
|
||||
katenary.v3/configmap-files: |-
|
||||
- ./dist
|
17
compose.yaml
Normal file
17
compose.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
dev:
|
||||
image: docker.io/node:alpine
|
||||
volumes:
|
||||
- ./:/app:z
|
||||
working_dir: /app
|
||||
user: ${UID}:${GROUPS}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |-
|
||||
yarn install
|
||||
yarn parcel serve --dist-dir /tmp/dist
|
||||
ports:
|
||||
- 1234:1234
|
||||
labels:
|
||||
katenary.v3/ignore: true
|
BIN
src/bg-head.webp
Normal file
BIN
src/bg-head.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
src/icon.ico
Normal file
BIN
src/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
49
src/index.html
Normal file
49
src/index.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Katenary: Effortless Helm Chart Conversion"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Katenary, Helm, Kubernetes, Compose, Docker, Podman, Helm chart"
|
||||
/>
|
||||
<meta name="author" content="Patrice Ferlet (aka metal3d)" />
|
||||
<link rel="icon" href="icon.ico" />
|
||||
<title>Katenary - Effortless Helm Chart Conversion</title>
|
||||
<link rel="stylesheet" href="main.css" />
|
||||
|
||||
<link
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/panda-syntax-dark.min.css"
|
||||
/>
|
||||
|
||||
<script src="links.js" defer></script>
|
||||
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"></script>
|
||||
<script defer>
|
||||
hljs.highlightAll();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<include src="src/partials/navbar.html"></include>
|
||||
<include src="src/partials/header.html"></include>
|
||||
|
||||
<main>
|
||||
<include src="src/partials/features.html"></include>
|
||||
<include src="src/partials/how-it-works.html"></include>
|
||||
<include src="src/partials/how-to-use.html"></include>
|
||||
<include src="src/partials/tutorials.html"></include>
|
||||
<include src="src/partials/get-started.html"></include>
|
||||
</main>
|
||||
|
||||
<include src="src/partials/footer.html"></include>
|
||||
</body>
|
||||
</html>
|
60
src/links.js
Normal file
60
src/links.js
Normal file
@@ -0,0 +1,60 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const sections = document.querySelectorAll("main > section, body > header");
|
||||
const links = document.querySelectorAll("nav a:not([target=_blank])");
|
||||
const linksArray = Array.from(links);
|
||||
|
||||
let scrollingOnClick = false; // Deactivate the observer if the scroll is on a link click
|
||||
|
||||
// Intersection Observer
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (scrollingOnClick) return; // ignore if the scroll is manual
|
||||
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const id = entry.target.id;
|
||||
const link = linksArray.find((link) => link.href.includes(`#${id}`));
|
||||
|
||||
linksArray.forEach((link) => link.classList.remove("active"));
|
||||
if (link) link.classList.add("active");
|
||||
|
||||
// update URL
|
||||
history.replaceState(null, null, `#${id}`);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ rootMargin: "-50% 0px -50% 0px" },
|
||||
);
|
||||
|
||||
sections.forEach((section) => observer.observe(section));
|
||||
|
||||
// Gestion du clic sur un lien
|
||||
linksArray.forEach((link) => {
|
||||
link.addEventListener("click", (e) => {
|
||||
e.preventDefault(); // avoid default navigation
|
||||
|
||||
const targetId = link.getAttribute("href").slice(1);
|
||||
const targetSection = document.getElementById(targetId);
|
||||
|
||||
// deactivate observer temporarily
|
||||
scrollingOnClick = true;
|
||||
|
||||
// scroll to the target
|
||||
targetSection.scrollIntoView({ behavior: "smooth" });
|
||||
|
||||
// update link state
|
||||
linksArray.forEach((link) => link.classList.remove("active"));
|
||||
link.classList.add("active");
|
||||
|
||||
// update URL
|
||||
history.replaceState(null, null, `#${targetId}`);
|
||||
|
||||
// on scroll end, reactivate the observer
|
||||
const onScrollEnd = () => {
|
||||
scrollingOnClick = false;
|
||||
window.removeEventListener("scroll", onScrollEnd); // Nettoyage
|
||||
};
|
||||
window.addEventListener("scroll", onScrollEnd);
|
||||
});
|
||||
});
|
||||
});
|
535
src/main.css
Normal file
535
src/main.css
Normal file
@@ -0,0 +1,535 @@
|
||||
/* styles.css */
|
||||
:root {
|
||||
--primary-color: #2a1827;
|
||||
--secondary-color: #6c757d;
|
||||
--dark-color: #343a40;
|
||||
--light-color: #f4f4f4;
|
||||
--white: #fff;
|
||||
--danger-color: #dc3545;
|
||||
--covered: 50%;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #333;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: var(--dark-color);
|
||||
background-image: url(./bg-head.webp);
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom;
|
||||
background-attachment: fixed;
|
||||
background-blend-mode: multiply;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 50px 20px;
|
||||
}
|
||||
|
||||
.header .container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
padding: 0;
|
||||
padding-bottom: 115px;
|
||||
}
|
||||
|
||||
main>section {
|
||||
flex: 1;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 3rem;
|
||||
margin: 0;
|
||||
background-image: url("https://github.com/Katenary/katenary/raw/refs/heads/develop/doc/docs/statics/logo-vertical.svg");
|
||||
color: transparent;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 265px;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 1.2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
color: var(--primary-color);
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #0056b3;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.features {
|
||||
background: var(--light-color);
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.features h2 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.feature-grid {
|
||||
/*
|
||||
display: grida;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
grid-auto-rows: 200px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
*/
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@keyframes slidingLeft {
|
||||
from {
|
||||
transform: translateX(-100vw);
|
||||
filter: opacity(0) blur(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateX(0);
|
||||
filter: opacity(1) blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slidingRight {
|
||||
from {
|
||||
transform: translateX(100vw);
|
||||
filter: opacity(0) blur(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateX(0);
|
||||
filter: opacity(1) blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
background: var(--white);
|
||||
border: 1px solid #ddd;
|
||||
flex: 1 1 200px;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
:root {
|
||||
--animation-slide: entry 0% contain 0%;
|
||||
}
|
||||
|
||||
.from-left {
|
||||
view-timeline: --reveal-blockl;
|
||||
view-timeline-axis: block;
|
||||
animation: linear slidingLeft forwards;
|
||||
animation-range: var(--animation-slide);
|
||||
animation-timeline: --reveal-blockl;
|
||||
}
|
||||
|
||||
.from-right {
|
||||
view-timeline: --reveal-blockr;
|
||||
view-timeline-axis: block;
|
||||
animation: linear slidingRight forwards;
|
||||
animation-range: var(--animation-slide);
|
||||
animation-timeline: --reveal-blockr;
|
||||
}
|
||||
}
|
||||
|
||||
.how-it-works {
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.how-to-use {
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tutorials {
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.how-it-works ol {
|
||||
list-style: decimal inside;
|
||||
text-align: left;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.image-placeholder {
|
||||
margin: 30px auto;
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.image-placeholder img {
|
||||
margin: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.get-started {
|
||||
background: var(--primary-color);
|
||||
color: var(--white);
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.get-started pre {
|
||||
background: var(--white);
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
margin: 20px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
div.video {
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
pre {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.example {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
section {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
section:nth-child(even) .example {
|
||||
text-align: right;
|
||||
flex-direction: row-reverse !important;
|
||||
}
|
||||
|
||||
section:nth-child(odd) .example {
|
||||
text-align: left;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
section:nth-child(even) .example h3 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.example>div {
|
||||
flex: 1 1 200px;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
code.hljs {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
p code {
|
||||
background: var(--dark-color);
|
||||
color: var(--light-color);
|
||||
padding: 1px 5px;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
section.alternate:nth-child(odd) {
|
||||
background: var(--light-color);
|
||||
color: var(--dark-color);
|
||||
}
|
||||
|
||||
section.alternate:nth-child(even) {
|
||||
background: var(--dark-color);
|
||||
color: var(--light-color);
|
||||
}
|
||||
|
||||
#menu-toggle {
|
||||
position: fixed;
|
||||
z-index: 11;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#menu-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: var(--white);
|
||||
color: var(--dark-color);
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navbar .container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
nav ul li a {
|
||||
color: var(--dark-color);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
nav ul li a:hover {
|
||||
color: var(--light-color);
|
||||
background: var(--dark-color);
|
||||
}
|
||||
|
||||
nav ul li a.active {
|
||||
color: var(--light-color) !important;
|
||||
background: var(--dark-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.navbar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.navbar:hover,
|
||||
#menu-toggle:focus~.navbar {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
opacity: 0.8;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 0px;
|
||||
color: var(--white);
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
background: var(--dark-color);
|
||||
color: var(--white);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
border: 1px solid var(--dark-color);
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.navbar:has(a:active) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: block;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav ul li a {
|
||||
color: var(--white);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background: #333;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
font-size: 0.9rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
footer section {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
flex: 1 1 250px;
|
||||
}
|
||||
|
||||
footer section p {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
footer ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
footer ul li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
footer .container {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
justify-content: space-between;
|
||||
align-items: start;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
footer .container>p {
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer section {
|
||||
flex: 1 1 auto;
|
||||
align-self: normal;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
footer section:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 5%;
|
||||
height: 90%;
|
||||
width: 1px;
|
||||
filter: opacity(0.5) blur(1px);
|
||||
}
|
||||
|
||||
footer section:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.large-icon {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
@keyframes bouncing {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.down {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
a.down {
|
||||
background: var(--white);
|
||||
color: var(--dark-color);
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
align-self: center;
|
||||
animation: bouncing 2s infinite;
|
||||
}
|
41
src/partials/features.html
Normal file
41
src/partials/features.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<section class="features" id="features">
|
||||
<div class="container">
|
||||
<h2>Why Katenary?</h2>
|
||||
<p>
|
||||
Simplify your deployment workflow by converting Compose files into
|
||||
production-ready Helm Charts with ease.
|
||||
</p>
|
||||
<div class="feature-grid from-left">
|
||||
<div class="feature-item">
|
||||
<h3>Automated Conversion</h3>
|
||||
<p>
|
||||
Generate complete Helm Charts from your Compose files effortlessly.
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<h3>Flexible Configuration</h3>
|
||||
<p>Customize deployments with `values.yaml` and environment labels.</p>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<h3>Dependency Management</h3>
|
||||
<p>
|
||||
Ensure proper service startup sequences using `depends_on` support.
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<h3>Open Source</h3>
|
||||
<p>Free, opensource, under the <strong>MIT license!</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video from-right">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/RrX5jNxS9IA?si=i0kRVFXOwT3ZqZdB"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
53
src/partials/footer.html
Normal file
53
src/partials/footer.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<section>
|
||||
<div>
|
||||
<h2>Special thanks</h2>
|
||||
<p>Content creation:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://blender.org">Blender</a> that helps a lot to create
|
||||
videos and animations
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://highlightjs.org">Highlight.js</a> for the code
|
||||
syntax highlighting
|
||||
</li>
|
||||
</ul>
|
||||
<p>For graphical elements</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://inkscape.org">Inkscape</a> for the icons and images
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://gimp.org">The Gimp</a> for many others image
|
||||
manipulation
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div>
|
||||
<h2>Links</h2>
|
||||
<p>For this website:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/Katenary/katenary">Katenary on GitHub</a>
|
||||
to follow, star, and contribute
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://matrix.to/#/!JuGCanxvQEESclXmfX:matrix.org?via=matrix.org"
|
||||
>Discussion on Matrix.org</a
|
||||
>
|
||||
the official Matrix channel for Katenary
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="container">
|
||||
<p>© 2024, 2025 Katenary. Open Source Project under MIT License.</p>
|
||||
</div>
|
||||
</footer>
|
12
src/partials/get-started.html
Normal file
12
src/partials/get-started.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<section class="get-started" id="get-started">
|
||||
<div class="container">
|
||||
<h2>Get Started</h2>
|
||||
<p>Download Katenary’s binary and start using it today.</p>
|
||||
<pre><code>sh <(curl -sSL https://raw.githubusercontent.com/Katenary/katenary/master/install.sh)</code></pre>
|
||||
<p>
|
||||
<a href="https://github.com/Katenary/katenary" class="btn-primary"
|
||||
>Go to GitHub</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
12
src/partials/header.html
Normal file
12
src/partials/header.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<header class="header">
|
||||
<div class="container">
|
||||
<h1>Katenary</h1>
|
||||
<p>Effortless Helm Chart Conversion for Kubernetes Deployments</p>
|
||||
<a
|
||||
href="#features"
|
||||
class="down-arrow large-icon down"
|
||||
title="Scroll down to learn more"
|
||||
><i class="fa fa-arrow-down"></i
|
||||
></a>
|
||||
</div>
|
||||
</header>
|
45
src/partials/how-it-works.html
Normal file
45
src/partials/how-it-works.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<section class="how-it-works" id="how-it-works">
|
||||
<div class="container">
|
||||
<h2>How It Works</h2>
|
||||
<p>
|
||||
Katenary simply read your <code>compose.yaml</code> file (or
|
||||
<code>docker-compose.yaml</code>) and use
|
||||
<strong>official libraries</strong> to read it and generate Kubernetes
|
||||
resources as YAML.
|
||||
</p>
|
||||
<p>
|
||||
Then, it adds templating conditions, values file, define a
|
||||
<code>Chart.yaml</code> file, adapt dependencies if needed, and many
|
||||
others things.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Using configuration files to be mounted?</strong> No problem,
|
||||
Katenary will create <code>ConfigMaps</code> if you declared that thes
|
||||
directories or files are statics.
|
||||
<br />
|
||||
<small
|
||||
>(Do not do this for sources of your project, use it for simple
|
||||
configuration files)</small
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
The result is a complete "Helm Chart" that can be installed, configured,
|
||||
packaged and shared.
|
||||
</p>
|
||||
<div class="image-placeholder">
|
||||
<img
|
||||
src="https://github.com/Katenary/katenary/raw/refs/heads/develop/doc/docs/statics/workflow.svg"
|
||||
alt="Katenary Workflow"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
Almost everything can be overriden as Ingresses, Dependencies, values,
|
||||
environment variables, secrets...
|
||||
</p>
|
||||
<ol>
|
||||
<li>Add optional labels to your Compose files.</li>
|
||||
<li>Run <code>katenary convert</code> from the command line.</li>
|
||||
<li>Deploy the generated Helm Chart in Kubernetes.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
92
src/partials/how-to-use.html
Normal file
92
src/partials/how-to-use.html
Normal file
@@ -0,0 +1,92 @@
|
||||
<section class="how-to-use" id="how-to-use">
|
||||
<div class="container">
|
||||
<h2>How to use?</h2>
|
||||
<p>
|
||||
Install the binary, and use <code>katenar convert</code> command line
|
||||
inside your project directory
|
||||
</p>
|
||||
<p>
|
||||
You can adapt your compose YAML file with labels, or add a
|
||||
<code>compose.katenary.yaml</code> file to override your project.
|
||||
</p>
|
||||
<p>
|
||||
You may also use a specific <code>katenary.yaml</code> file that accepts
|
||||
the directives without using labels.
|
||||
</p>
|
||||
<section class="alternate">
|
||||
<div class="container example">
|
||||
<div class="from-left">
|
||||
<h3>Only add labels! (if needed!)</h3>
|
||||
<p>
|
||||
You can adapt, configure, or change the conversion behaviour addind
|
||||
labels.
|
||||
</p>
|
||||
<p>
|
||||
It
|
||||
<strong
|
||||
>doesn't change the <code>docker compose</code> or
|
||||
<code>podman compose</code></strong
|
||||
>
|
||||
behaviour. It is only used while using
|
||||
<code>katenary compose</code> command line
|
||||
</p>
|
||||
<p>
|
||||
There are
|
||||
<a
|
||||
href="https://katenary.readthedocs.io/en/latest/labels/"
|
||||
target="_blank"
|
||||
>plenty of labels</a
|
||||
>
|
||||
to help you to customize and adapt the resulting Helm Chart.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<pre class="from-right"><code class="language-yaml">
|
||||
# your "docker-compose.yml", or "compose.yaml"
|
||||
services:
|
||||
web:
|
||||
image: docker.io/nginx:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
labels:
|
||||
# generate an ingress resource in the Helm Chart
|
||||
katenary.io/ingress: |-
|
||||
hostname: example.com
|
||||
port: 80
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="alternate">
|
||||
<div class="container example">
|
||||
<div class="from-right">
|
||||
<h3>Ease the deployment</h3>
|
||||
<p>
|
||||
Kubernetes somtimes lacks of automation. Katenary helps you to add
|
||||
what is needed, like having a
|
||||
<code>depends_on</code> feature.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<pre class="from-left"><code class="language-yaml">
|
||||
# your "docker-compose.yml", or "compose.yaml"
|
||||
services:
|
||||
db:
|
||||
image: docker.io/postgres:latest
|
||||
# ...
|
||||
labels:
|
||||
katenary.v3/ports: |-
|
||||
- 5432
|
||||
|
||||
web:
|
||||
image: php:fpm
|
||||
# ...
|
||||
depends_on:
|
||||
- db
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
24
src/partials/navbar.html
Normal file
24
src/partials/navbar.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<button class="btn-primary" id="menu-toggle">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<div class="navbar">
|
||||
<div class="container">
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#"><i class="fa fa-house"></i> Katenary</a>
|
||||
</li>
|
||||
<li><a href="#features">Why Katenary?</a></li>
|
||||
<li><a href="#how-it-works">How It Works</a></li>
|
||||
<li><a href="#how-to-use">How to use</a></li>
|
||||
<li><a href="#tutorials">Tutorials</a></li>
|
||||
<li><a href="#get-started">Get Started</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/Katenary/katenary" target="_blank"
|
||||
><i class="fab fa-github"></i> Katenary on GitHub</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
22
src/partials/tutorials.html
Normal file
22
src/partials/tutorials.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<section class="tutorials" id="tutorials">
|
||||
<div class="container">
|
||||
<h2>Watch the Tutorials</h2>
|
||||
<p>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kvVN8gPxqOA&list=PLrq-nCZV_rv6GRBFlA7WxUz2h3DM5teCi"
|
||||
target="_blank"
|
||||
>A playlist</a
|
||||
>
|
||||
is progressivelly filled to help the Katenary adoption. Take a look and
|
||||
learn how it is simple.
|
||||
</p>
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/kvVN8gPxqOA?si=tsPoMPh4PbKFutTx"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
</div>
|
||||
</section>
|
Reference in New Issue
Block a user