init from gitlab
This commit is contained in:
10
web/.gitignore
vendored
Normal file
10
web/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
1
web/.npmrc
Normal file
1
web/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
engine-strict=true
|
||||
1980
web/package-lock.json
generated
Normal file
1980
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
web/package.json
Normal file
25
web/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^1.0.0",
|
||||
"@sveltejs/adapter-static": "^1.0.6",
|
||||
"@sveltejs/kit": "^1.0.0",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"postcss": "^8.4.21",
|
||||
"svelte": "^3.54.0",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"vite": "^4.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"daisyui": "^2.50.0"
|
||||
}
|
||||
}
|
||||
6
web/postcss.config.cjs
Normal file
6
web/postcss.config.cjs
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
3
web/src/app.css
Normal file
3
web/src/app.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
12
web/src/app.html
Normal file
12
web/src/app.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
6
web/src/components/Hint.svelte
Normal file
6
web/src/components/Hint.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="alert shadow-lg">
|
||||
<div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-info flex-shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
<span><slot /></span>
|
||||
</div>
|
||||
</div>
|
||||
30
web/src/components/Navbar.svelte
Normal file
30
web/src/components/Navbar.svelte
Normal file
@@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import { base } from "$app/paths";
|
||||
|
||||
export let hideGetStarted = false;
|
||||
</script>
|
||||
|
||||
<div class="navbar bg-neutral text-neutral-content flex items-center justify-between p-4 mx-auto">
|
||||
<slot name="sidebar-toggle" />
|
||||
<div class="flex-1">
|
||||
<a href={base + "/"} class="btn btn-ghost normal-case text-xl">shokku</a>
|
||||
</div>
|
||||
<div class="flex-none">
|
||||
<ul class="menu menu-horizontal px-3 gap-2">
|
||||
<li>
|
||||
<a href="https://github.com/texm/shokku" target="_blank" rel="noreferrer">
|
||||
<svg class="h-6 w-6" viewBox="0 0 128 128" stroke="currentColor">
|
||||
<g fill="currentColor">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"></path><path d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class:hidden={hideGetStarted}>
|
||||
<a class="btn btn-primary text-primary-content" href={`${base}/docs`}>
|
||||
Read the docs
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
4
web/src/routes/+layout.js
Normal file
4
web/src/routes/+layout.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
export const prerender = !dev;
|
||||
export const csr = dev;
|
||||
9
web/src/routes/+layout.svelte
Normal file
9
web/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script>
|
||||
import "$src/app.css";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Shokku</title>
|
||||
</svelte:head>
|
||||
|
||||
<slot />
|
||||
19
web/src/routes/+page.svelte
Normal file
19
web/src/routes/+page.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script>
|
||||
import Navbar from "$components/Navbar.svelte";
|
||||
import Hero from "./Hero.svelte";
|
||||
import Features from "./Features.svelte";
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-screen">
|
||||
<div class="flex-shrink">
|
||||
<Navbar />
|
||||
</div>
|
||||
|
||||
<div class="flex-grow bg-base-100">
|
||||
<Hero />
|
||||
</div>
|
||||
|
||||
<div class="bg-base-300 justify-center p-8">
|
||||
<Features />
|
||||
</div>
|
||||
</div>
|
||||
22
web/src/routes/Features.svelte
Normal file
22
web/src/routes/Features.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script>
|
||||
const features = [
|
||||
{title: "Free and Open Source", ref: "", description: "description"},
|
||||
{title: "Github Integration", ref: "", description: "description"},
|
||||
{title: "Services Support", ref: "", description: "description"},
|
||||
{title: "Services Support", ref: "", description: "description"},
|
||||
]
|
||||
</script>
|
||||
|
||||
<div class="grid grid-flow-row sm:grid-flow-col sm:auto-cols-fr gap-4">
|
||||
{#each features as feature}
|
||||
<div class="card bg-base-200 hover:bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{feature.title}</h2>
|
||||
<p>{feature.description}</p>
|
||||
<!--div class="card-actions justify-end">
|
||||
<button class="btn btn-ghost">Learn More</button>
|
||||
</div-->
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
33
web/src/routes/Hero.svelte
Normal file
33
web/src/routes/Hero.svelte
Normal file
@@ -0,0 +1,33 @@
|
||||
<script>
|
||||
import {base} from "$app/paths";
|
||||
import Icons from "./Icons.svelte";
|
||||
|
||||
const demoUrl = "https://demo.example.com"
|
||||
</script>
|
||||
|
||||
<div class="hero h-full">
|
||||
<div class="hero-content text-center flex-col py-10 px-0">
|
||||
<div class="max-w-md mb-4">
|
||||
<h1 class="text-5xl font-bold mb-2">A web interface for Dokku</h1>
|
||||
<p class="text-xl">
|
||||
an open-source self-hostable web UI to help
|
||||
<strong>configure</strong> and <strong>deploy</strong>
|
||||
your apps and services with <a class="link" href="https://dokku.com/">Dokku</a>
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col gap-4 mb-4 p-4">
|
||||
<Icons />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-4 justify-center">
|
||||
<a href="{base}/docs">
|
||||
<button class="btn btn-primary text-primary-content">Get Started</button>
|
||||
</a>
|
||||
|
||||
<a href={demoUrl}>
|
||||
<button class="btn btn-secondary text-secondary-content">Try the Demo</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
67
web/src/routes/Icons.svelte
Normal file
67
web/src/routes/Icons.svelte
Normal file
File diff suppressed because one or more lines are too long
15
web/src/routes/Screenshots.svelte
Normal file
15
web/src/routes/Screenshots.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script>
|
||||
const carouselImages = [
|
||||
{alt: "dashboard screenshot", src: "/images/dashboard-light.webp"},
|
||||
{alt: "app overview", src: "/images/app-overview.webp"},
|
||||
{alt: "service overview", src: "/images/service-overview.webp"},
|
||||
]
|
||||
|
||||
const nextIdx = i => ((i + 1) % carouselImages.length);
|
||||
const prevIdx = i => (carouselImages - i)
|
||||
</script>
|
||||
|
||||
<div class="mockup-window rounded-xl bg-base-200 shadow-secondary w-3/5 h-auto">
|
||||
<img class="inline dark:hidden" alt="dashboard screenshot" src="/images/dashboard-dark.webp" />
|
||||
<img class="hidden dark:inline" alt="dashboard screenshot" src="/images/dashboard-light.webp" />
|
||||
</div>
|
||||
87
web/src/routes/docs/+layout.svelte
Normal file
87
web/src/routes/docs/+layout.svelte
Normal file
@@ -0,0 +1,87 @@
|
||||
<script>
|
||||
import {base} from "$app/paths";
|
||||
import {page} from "$app/stores";
|
||||
import Navbar from "$components/Navbar.svelte";
|
||||
import ProgressButtons from "./ProgressButtons.svelte";
|
||||
import {browser} from "$app/environment";
|
||||
import {onMount} from "svelte";
|
||||
|
||||
const sidebarPages = [
|
||||
{section: "Getting Started", ref: "/docs/intro", label: "Introduction"},
|
||||
{ref: "/docs/installation", label: "Install"},
|
||||
{ref: "/docs/setup", label: "Setup"},
|
||||
{section: "Usage", ref: "/docs/apps", label: "Apps"},
|
||||
// {ref: "/docs/apps/create", label: "Create App", level: 1},
|
||||
{ref: "/docs/services", label: "Services"},
|
||||
{ref: "/docs/settings", label: "Settings"},
|
||||
{section: "Maintenance", ref: "/docs/upgrading", label: "Upgrading"},
|
||||
{ref: "/docs/uninstall", label: "Uninstall"},
|
||||
{ref: "/docs/support", label: "Support"},
|
||||
];
|
||||
|
||||
let currentPage, prevPage, nextPage;
|
||||
$: if ($page.route.id) {
|
||||
currentPage = sidebarPages.findIndex(p => p.ref === $page.route.id);
|
||||
prevPage = (currentPage > 0) ? sidebarPages[currentPage - 1] : null;
|
||||
nextPage = (currentPage < sidebarPages.length - 1) ? sidebarPages[currentPage + 1] : null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Shokku Docs - {sidebarPages[currentPage].label}</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex flex-col h-screen">
|
||||
<div class="flex-shrink">
|
||||
<Navbar hideGetStarted={true}>
|
||||
<div slot="sidebar-toggle" class="flex-none lg:hidden">
|
||||
<label for="sidebar" class="btn btn-square btn-ghost drawer-button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
||||
class="inline-block w-5 h-5 stroke-current">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"></path>
|
||||
</svg>
|
||||
</label>
|
||||
</div>
|
||||
</Navbar>
|
||||
</div>
|
||||
|
||||
<div class="drawer drawer-mobile h-auto flex-grow">
|
||||
<input id="sidebar" type="checkbox" class="drawer-toggle" />
|
||||
|
||||
<div class="drawer-content flex flex-col">
|
||||
<div class="p-8">
|
||||
<article class="prose">
|
||||
<h1 class="mb-0">{sidebarPages[currentPage].label}</h1>
|
||||
<hr class="mt-4 mb-8" />
|
||||
<slot />
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="divider mt-2 mb-0"></div>
|
||||
|
||||
<ProgressButtons previous={prevPage} next={nextPage} />
|
||||
</div>
|
||||
|
||||
<div class="drawer-side">
|
||||
<label for="sidebar" class="drawer-overlay"></label>
|
||||
|
||||
<ul class="menu w-80 bg-base-200 text-base-content pt-2">
|
||||
{#each sidebarPages as p, i}
|
||||
{#if p.section}
|
||||
<li class="menu-title py-1">
|
||||
<span>{p.section}</span>
|
||||
</li>
|
||||
{/if}
|
||||
<li class:bordered={currentPage === i}>
|
||||
<a href={base + p.ref}>
|
||||
<span class:pl-5={p.level === 1}>
|
||||
{p.label}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
6
web/src/routes/docs/+page.js
Normal file
6
web/src/routes/docs/+page.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
import { base } from "$app/paths";
|
||||
|
||||
export function load() {
|
||||
throw redirect(307, `${base}/docs/intro`);
|
||||
}
|
||||
35
web/src/routes/docs/ProgressButtons.svelte
Normal file
35
web/src/routes/docs/ProgressButtons.svelte
Normal file
@@ -0,0 +1,35 @@
|
||||
<script>
|
||||
import { base } from "$app/paths";
|
||||
|
||||
export let next;
|
||||
export let previous;
|
||||
</script>
|
||||
|
||||
<div class="flex w-full justify-between pl-6 pr-10 my-6">
|
||||
<div>
|
||||
{#if previous}
|
||||
<a href={base + previous.ref} class="btn btn-md md:btn-lg btn-ghost gap-2 normal-case lg:gap-3">
|
||||
<svg class="h-8 w-8 fill-current md:h-8 md:w-8" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z"></path></svg>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="text-base-content/50 hidden text-xs font-normal md:block">
|
||||
Prev
|
||||
</span>
|
||||
<span>{previous.label}</span>
|
||||
</div>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
{#if next}
|
||||
<a href={base + next.ref} class="btn btn-md md:btn-lg gap-2 normal-case lg:gap-3">
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="text-neutral-content/50 hidden text-xs font-normal md:block">
|
||||
Next
|
||||
</span>
|
||||
<span>{next.label}</span>
|
||||
</div>
|
||||
<svg class="h-8 w-8 fill-current md:h-8 md:w-8" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></path></svg>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
42
web/src/routes/docs/apps/+page.svelte
Normal file
42
web/src/routes/docs/apps/+page.svelte
Normal file
@@ -0,0 +1,42 @@
|
||||
<script>
|
||||
import {base} from "$app/paths";
|
||||
|
||||
const gitPushUrl = "https://dokku.com/docs/deployment/application-deployment/#deploy-the-app"
|
||||
const remoteRepoDocs = "https://dokku.com/docs/deployment/methods/git/#initializing-an-app-repository-from-a-remote-repository"
|
||||
const dockerImageDocs = "https://dokku.com/docs/deployment/methods/git/#initializing-an-app-repository-from-a-docker-image"
|
||||
</script>
|
||||
|
||||
<h2>Creating an App</h2>
|
||||
<p>
|
||||
Once setup, the initial page you see is the <i>Dashboard</i>. From
|
||||
here you can create apps and services, or view any existing ones.
|
||||
After you have chosen a valid name for your app, you will proceed to
|
||||
setup. Currently apps can be setup in three different ways:
|
||||
</p>
|
||||
|
||||
<h2>Create New Git Repo</h2>
|
||||
<p>
|
||||
This option creates a git repo on the host, and sets a branch to deploy
|
||||
from. Once configured, you will need to add the remote to your local git
|
||||
repo, and push to deploy following <a href={gitPushUrl}>these instructions</a>.
|
||||
</p>
|
||||
|
||||
<h2>Sync Existing Git Repo</h2>
|
||||
<p>
|
||||
This option configures a remote repository to clone using a specific
|
||||
<i>git ref</i> (eg the <i>main</i> branch, or a specific commit), which can
|
||||
then be automatically built and deployed. See the Dokku docs on this method
|
||||
<a href={remoteRepoDocs}>here</a>.
|
||||
<br />
|
||||
If the repo is private, ensure you have configured access following the instructions
|
||||
<a href={`${base}/docs/settings`}>here</a>.
|
||||
</p>
|
||||
|
||||
<h2>Docker Image</h2>
|
||||
<p>
|
||||
This option enables pulling a Docker image. See the Dokku docs for caveats
|
||||
<a href={dockerImageDocs}>here</a>.
|
||||
<br />
|
||||
If the image is held in a private registry, ensure you have configured access by
|
||||
following the instructions <a href={`${base}/docs/settings`}>here</a>.
|
||||
</p>
|
||||
89
web/src/routes/docs/installation/+page.svelte
Normal file
89
web/src/routes/docs/installation/+page.svelte
Normal file
@@ -0,0 +1,89 @@
|
||||
<script>
|
||||
const scriptInstallCommands = [
|
||||
`wget "https://shokku.app/install.sh"`,
|
||||
`export SHOKKU_LETSENCRYPT_EMAIL="foo@example.com"`,
|
||||
`sudo bash install.sh`,
|
||||
]
|
||||
|
||||
const manualInstallCommands = [
|
||||
`todo`,
|
||||
]
|
||||
</script>
|
||||
|
||||
<h2>Prequisites</h2>
|
||||
<h3>Dokku</h3>
|
||||
<p>
|
||||
Shokku requires an underlying Dokku installation.
|
||||
You are recommended to manually install & configure it following
|
||||
<a href="https://dokku.com/docs/getting-started/installation/">the official documentation</a>.
|
||||
<br />
|
||||
If an existing installation is not detected during the setup process, it
|
||||
will be automatically installed and configured.
|
||||
</p>
|
||||
|
||||
<h3>SSL</h3>
|
||||
<p>
|
||||
Shokku will only work over HTTPS, so SSL must be configured. This can be via:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Automatic (LetsEncrypt)</strong> <br />
|
||||
If a global email has been set, it will automatically be used. Otherwise,
|
||||
ensure the <code>SHOKKU_LETSENCRYPT_EMAIL</code> environment variable is set during
|
||||
installation to a valid email.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Manual</strong>
|
||||
<br />
|
||||
Set the <code>SHOKKU_CERT</code> environment variable to point to a tarball containing the
|
||||
certificate contents. Tarball creation instructions can be found
|
||||
<a href="https://dokku.com/docs/configuration/ssl/#certificate-setting">here</a>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--div class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
|
||||
<input type="checkbox" />
|
||||
<div class="collapse-title text-lg font-medium">
|
||||
Default installation configuration
|
||||
</div>
|
||||
<div class="collapse-content">
|
||||
<p>nginx, letsencrypt, etc</p>
|
||||
</div>
|
||||
</div-->
|
||||
|
||||
<h2>Install Using Script</h2>
|
||||
|
||||
<div class="mockup-code">
|
||||
{#each scriptInstallCommands as cmd, i}
|
||||
<pre data-prefix="{i}" class="m-0 my-1 p-0"><code>{cmd}</code></pre>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<h2 class="flex items-center gap-2">
|
||||
<img alt="digitalocean icon" class="w-8 h-8"
|
||||
src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/digitalocean/digitalocean-original.svg" />
|
||||
DigitalOcean 1-Click Install
|
||||
</h2>
|
||||
<p>
|
||||
TODO: link to digitalocean marketplace
|
||||
</p>
|
||||
|
||||
<h2>Manual Installation</h2>
|
||||
<div class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
|
||||
<input type="checkbox" />
|
||||
<div class="collapse-title text-xl font-medium">
|
||||
Instructions
|
||||
</div>
|
||||
<div class="collapse-content">
|
||||
<p>
|
||||
If you don't feel comfortable using some random script from the internet,
|
||||
the installation can be manually performed fairly easily:
|
||||
</p>
|
||||
<div class="mockup-code">
|
||||
{#each manualInstallCommands as cmd, i}
|
||||
<pre data-prefix="{i}" class="m-0 my-1 p-0"><code>{cmd}</code></pre>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
38
web/src/routes/docs/intro/+page.svelte
Normal file
38
web/src/routes/docs/intro/+page.svelte
Normal file
@@ -0,0 +1,38 @@
|
||||
<p>
|
||||
Shokku is an interface for <a href="https://dokku.com" class="link">Dokku</a> - a
|
||||
self-hostable PaaS/alternative to Heroku.
|
||||
<br />
|
||||
It is recommended you are somewhat familiar with the underlying Dokku project
|
||||
(<a href="https://dokku.com/docs" class="link">read the docs</a>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is not associated with Dokku.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is open-source and freely available, the repository is hosted on Github at
|
||||
<a class="link" href="https://github.com/texm/shokku">texm/shokku</a>.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
Features
|
||||
</h2>
|
||||
<p>
|
||||
Shokku aims to be as simple to install and operate as Dokku, providing access to
|
||||
most functionality without needing to use the terminal or manage SSH access for users.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Works with your existing Dokku installation, or configures one during setup</li>
|
||||
<li>Build, deploy, and manage almost any kind of application easily</li>
|
||||
<li>Easy creation of <code>Redis, PostgreSQL, MySQL, and MongoDB</code> services</li>
|
||||
<li>Reverse proxy and automatic SSL via LetsEncrypt</li>
|
||||
<li>Github Integration</li>
|
||||
<ul>
|
||||
<li>Single-user or organisation installation</li>
|
||||
<li>User management / Authentication</li>
|
||||
<li>Repo-aware smart suggestions</li>
|
||||
</ul>
|
||||
<li>Optional API Access</li>
|
||||
</ul>
|
||||
50
web/src/routes/docs/services/+page.svelte
Normal file
50
web/src/routes/docs/services/+page.svelte
Normal file
@@ -0,0 +1,50 @@
|
||||
<script>
|
||||
const configOptions = [
|
||||
{name: "Config Options", default: "", description: "Extra CLI arguments to pass to the container creation"},
|
||||
{name: "Environment Variables", default: "", description: "Environment variables to start the service with"},
|
||||
{name: "Image", default: "", description: "Custom image name to use"},
|
||||
{name: "Version", default: "latest", description: "Image version to use"},
|
||||
{name: "Memory", default: "", description: "Container memory limit in MB"},
|
||||
{name: "Shared Memory", default: "", description: "Override shared memory size for container in MB"},
|
||||
{name: "Password", default: "", description: "Override user-level service password"},
|
||||
{name: "Root Password", default: "", description: "Override root-level service password"},
|
||||
]
|
||||
</script>
|
||||
|
||||
<h2>Creating a service</h2>
|
||||
<p>
|
||||
Currently you can create 4 types of service:
|
||||
<strong>MySQL</strong>, <strong>PostgreSQL</strong>,
|
||||
<strong>MongoDB</strong>, and <strong>Redis</strong>.
|
||||
|
||||
They all support the same configuration options.
|
||||
</p>
|
||||
|
||||
<h3>Configuration</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each configOptions as opt}
|
||||
<tr>
|
||||
<td>{opt.name}</td>
|
||||
<td>{opt.default}</td>
|
||||
<td>{opt.description}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2>Linking a service</h2>
|
||||
<p>
|
||||
Services need to be <i>linked</i> to an app. Once this is done, the connection
|
||||
information will be available in the UI, and injected as an environment variable
|
||||
to the app (eg <code>REDIS_URL</code>)
|
||||
</p>
|
||||
1
web/src/routes/docs/settings/+page.svelte
Normal file
1
web/src/routes/docs/settings/+page.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<p>todo</p>
|
||||
49
web/src/routes/docs/setup/+page.svelte
Normal file
49
web/src/routes/docs/setup/+page.svelte
Normal file
@@ -0,0 +1,49 @@
|
||||
<script>
|
||||
const ghAppUrl = "https://docs.github.com/en/apps/creating-github-apps/creating-github-apps/about-apps"
|
||||
const manifestUrl = "https://docs.github.com/en/apps/creating-github-apps/creating-github-apps/creating-a-github-app-from-a-manifest";
|
||||
// TODO
|
||||
const codeManifestUrl = "https://github.com/texm/shokku"
|
||||
</script>
|
||||
|
||||
<h2>Get Setup Key</h2>
|
||||
<p>
|
||||
Once installation is finished, a <i>setup key</i> will be output to
|
||||
the console. Copy this, you will need it for the initial web setup.
|
||||
</p>
|
||||
|
||||
<h2>Choose Setup Method</h2>
|
||||
<h3>Github</h3>
|
||||
<p>
|
||||
Setting up with Github creates a <a href={ghAppUrl}>Github App</a> to
|
||||
act on behalf of your installation. This means authentication will use
|
||||
Github OAuth, and information about your repositories can be automatically
|
||||
fetched via the Github API.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The app is created using a <a href={manifestUrl}>manifest</a> - you can
|
||||
view the configuration <a href={codeManifestUrl}>here</a>.
|
||||
|
||||
You can choose to install the app on your account, or for an organisation.
|
||||
</p>
|
||||
|
||||
<h4>Organisation Install</h4>
|
||||
<p>
|
||||
If you install on behalf of an organisation, all members of the organisation
|
||||
will be able to authenticate and use Shokku. There is currently no role-based
|
||||
access, so ensure you trust your fellow org members as admins!
|
||||
</p>
|
||||
|
||||
<h3>Username/Password</h3>
|
||||
<p>
|
||||
You can also use username/password authentication.
|
||||
Currently this is limited to a single user.
|
||||
</p>
|
||||
|
||||
<h4>TOTP 2FA</h4>
|
||||
<p>
|
||||
Use of TOTP is <strong>strongly recommended</strong>.
|
||||
A QR code/secret will be generated, along with a recovery code to be used should
|
||||
you lose access to your account. If you choose not to enable this during installation,
|
||||
it can be configured later in Settings.
|
||||
</p>
|
||||
10
web/src/routes/docs/support/+page.svelte
Normal file
10
web/src/routes/docs/support/+page.svelte
Normal file
@@ -0,0 +1,10 @@
|
||||
<p>
|
||||
For bugs, feature requests, or general questions: open an
|
||||
<a href="https://github.com/texm/shokku/issues">issue in the Github Repo</a>.
|
||||
</p>
|
||||
|
||||
<h2>Commercial Support</h2>
|
||||
<p>
|
||||
There is no commercial support for Shokku. Consider
|
||||
<a href="https://pro.dokku.com/">Dokku Pro</a>.
|
||||
</p>
|
||||
31
web/src/routes/docs/uninstall/+page.svelte
Normal file
31
web/src/routes/docs/uninstall/+page.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<script>
|
||||
import Hint from "$components/Hint.svelte";
|
||||
|
||||
const commands = [
|
||||
"dokku apps:destroy --force shokku",
|
||||
"dokku ssh-keys:remove shokkuadmin",
|
||||
"rm -r /var/lib/dokku/data/storage/shokku",
|
||||
]
|
||||
</script>
|
||||
|
||||
<p>
|
||||
To completely uninstall Shokku, run the following commands
|
||||
</p>
|
||||
|
||||
<div class="mockup-code mb-4">
|
||||
{#each commands as cmd, i}
|
||||
<pre data-prefix="{i}" class="m-0 my-1 p-0"><code>{cmd}</code></pre>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<Hint>
|
||||
This will not uninstall Dokku, or remove any apps/services
|
||||
you have created/deployed.
|
||||
</Hint>
|
||||
|
||||
<h2>Delete Github App</h2>
|
||||
<p>
|
||||
If you have completed setup with a github app, head to your
|
||||
<a href="https://github.com/settings/apps">Github Developer Settings</a>, click
|
||||
<i>Edit</i>, then <i>Advanced</i> in the sidebar, then <i>Delete Github App</i>.
|
||||
</p>
|
||||
22
web/src/routes/docs/upgrading/+page.svelte
Normal file
22
web/src/routes/docs/upgrading/+page.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script>
|
||||
import Hint from "$components/Hint.svelte";
|
||||
|
||||
// TODO: update this
|
||||
const shokkuImage = "repo/shokku";
|
||||
const manualCmds = [
|
||||
`export SHOKKU_VERSION=latest`,
|
||||
`docker pull "${shokkuImage}:$SHOKKU_VERSION"`,
|
||||
`dokku git:from-image shokku $(docker inspect --format='{{index .RepoDigests 0}}' "${shokkuImage}:$SHOKKU_VERSION")`
|
||||
];
|
||||
</script>
|
||||
|
||||
<Hint>
|
||||
Due to how Dokku tracks app changes, tracking the <i>latest</i> image tag will result
|
||||
in no changes being detected. Instead we use the image digest.
|
||||
</Hint>
|
||||
|
||||
<div class="mockup-code mt-4">
|
||||
{#each manualCmds as cmd, i}
|
||||
<pre data-prefix="{i}" class="m-0 my-1 p-0"><code>{cmd}</code></pre>
|
||||
{/each}
|
||||
</div>
|
||||
0
web/static/.nojekyll
Normal file
0
web/static/.nojekyll
Normal file
BIN
web/static/favicon.png
Normal file
BIN
web/static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
web/static/images/app-overview.webp
Normal file
BIN
web/static/images/app-overview.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
web/static/images/dashboard-dark.webp
Normal file
BIN
web/static/images/dashboard-dark.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
web/static/images/dashboard-light.webp
Normal file
BIN
web/static/images/dashboard-light.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
web/static/images/service-overview.webp
Normal file
BIN
web/static/images/service-overview.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
22
web/svelte.config.js
Normal file
22
web/svelte.config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
const dev = process.argv.includes('dev');
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
pages: 'build',
|
||||
assets: 'build',
|
||||
fallback: null,
|
||||
precompress: false,
|
||||
strict: true
|
||||
}),
|
||||
paths: {
|
||||
// base: dev ? '' : '/shokku',
|
||||
},
|
||||
},
|
||||
preprocess: vitePreprocess(),
|
||||
};
|
||||
|
||||
export default config;
|
||||
13
web/tailwind.config.cjs
Normal file
13
web/tailwind.config.cjs
Normal file
@@ -0,0 +1,13 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
plugins: [
|
||||
require('@tailwindcss/typography'),
|
||||
require("daisyui")
|
||||
],
|
||||
daisyui: {
|
||||
logs: false,
|
||||
darkTheme: "business",
|
||||
themes: ["corporate", "business"],
|
||||
},
|
||||
}
|
||||
14
web/vite.config.js
Normal file
14
web/vite.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import path from "path";
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
|
||||
const config = {
|
||||
plugins: [sveltekit()],
|
||||
resolve: {
|
||||
alias: {
|
||||
$src: path.resolve("./src"),
|
||||
$components: path.resolve("./src/components"),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
Reference in New Issue
Block a user