percher 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/percher.js +111049 -18287
- package/dist/package.json +13 -4
- package/dist/src/cli-utils.d.ts +9 -0
- package/dist/src/cli-utils.d.ts.map +1 -1
- package/dist/src/cli-utils.js +18 -0
- package/dist/src/cli-utils.js.map +1 -1
- package/dist/src/commands/account.d.ts.map +1 -1
- package/dist/src/commands/account.js +63 -7
- package/dist/src/commands/account.js.map +1 -1
- package/dist/src/commands/admin.d.ts +17 -0
- package/dist/src/commands/admin.d.ts.map +1 -0
- package/dist/src/commands/admin.js +92 -0
- package/dist/src/commands/admin.js.map +1 -0
- package/dist/src/commands/apps.d.ts.map +1 -1
- package/dist/src/commands/apps.js +60 -8
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/deploys.d.ts.map +1 -1
- package/dist/src/commands/deploys.js +12 -2
- package/dist/src/commands/deploys.js.map +1 -1
- package/dist/src/commands/migrate.d.ts +4 -0
- package/dist/src/commands/migrate.d.ts.map +1 -0
- package/dist/src/commands/migrate.js +142 -0
- package/dist/src/commands/migrate.js.map +1 -0
- package/dist/src/commands/sharing.d.ts +23 -0
- package/dist/src/commands/sharing.d.ts.map +1 -0
- package/dist/src/commands/sharing.js +162 -0
- package/dist/src/commands/sharing.js.map +1 -0
- package/dist/src/commands/transfers.d.ts +20 -0
- package/dist/src/commands/transfers.d.ts.map +1 -0
- package/dist/src/commands/transfers.js +117 -0
- package/dist/src/commands/transfers.js.map +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +42 -4
- package/dist/src/index.js.map +1 -1
- package/dist/templates/astro/Caddyfile +6 -0
- package/dist/templates/astro/Dockerfile +34 -0
- package/dist/templates/astro/astro.config.mjs +3 -0
- package/dist/templates/astro/package.json +14 -0
- package/dist/templates/astro/percher.toml +11 -0
- package/dist/templates/astro/src/pages/index.astro +15 -0
- package/dist/templates/bun/index.ts +23 -0
- package/dist/templates/bun/package.json +8 -0
- package/dist/templates/bun/percher.toml +10 -0
- package/dist/templates/django/Procfile +1 -0
- package/dist/templates/django/app/__init__.py +0 -0
- package/dist/templates/django/app/settings.py +44 -0
- package/dist/templates/django/app/urls.py +21 -0
- package/dist/templates/django/app/wsgi.py +5 -0
- package/dist/templates/django/manage.py +19 -0
- package/dist/templates/django/percher.toml +11 -0
- package/dist/templates/django/requirements.txt +2 -0
- package/dist/templates/dotnet/Dockerfile +18 -0
- package/dist/templates/dotnet/Program.cs +23 -0
- package/dist/templates/dotnet/app.csproj +9 -0
- package/dist/templates/dotnet/percher.toml +11 -0
- package/dist/templates/eleventy/.eleventy.js +12 -0
- package/dist/templates/eleventy/Caddyfile +6 -0
- package/dist/templates/eleventy/Dockerfile +34 -0
- package/dist/templates/eleventy/package.json +12 -0
- package/dist/templates/eleventy/percher.toml +11 -0
- package/dist/templates/eleventy/src/_includes/base.njk +12 -0
- package/dist/templates/eleventy/src/assets/style.css +12 -0
- package/dist/templates/eleventy/src/index.md +10 -0
- package/dist/templates/elysia/index.ts +8 -0
- package/dist/templates/elysia/package.json +12 -0
- package/dist/templates/elysia/percher.toml +11 -0
- package/dist/templates/express/index.ts +16 -0
- package/dist/templates/express/package.json +11 -0
- package/dist/templates/express/percher.toml +11 -0
- package/dist/templates/fastify/index.ts +13 -0
- package/dist/templates/fastify/package.json +11 -0
- package/dist/templates/fastify/percher.toml +11 -0
- package/dist/templates/flask/main.py +23 -0
- package/dist/templates/flask/percher.toml +11 -0
- package/dist/templates/flask/requirements.txt +1 -0
- package/dist/templates/go/Dockerfile +11 -0
- package/dist/templates/go/go.mod +3 -0
- package/dist/templates/go/main.go +53 -0
- package/dist/templates/go/percher.toml +11 -0
- package/dist/templates/hono/index.ts +12 -0
- package/dist/templates/hono/package.json +11 -0
- package/dist/templates/hono/percher.toml +11 -0
- package/dist/templates/htmx/index.ts +32 -0
- package/dist/templates/htmx/package.json +15 -0
- package/dist/templates/htmx/percher.toml +11 -0
- package/dist/templates/hugo/Caddyfile +6 -0
- package/dist/templates/hugo/Dockerfile +32 -0
- package/dist/templates/hugo/content/_index.md +7 -0
- package/dist/templates/hugo/hugo.toml +11 -0
- package/dist/templates/hugo/layouts/index.html +22 -0
- package/dist/templates/hugo/percher.toml +11 -0
- package/dist/templates/java/Dockerfile +15 -0
- package/dist/templates/java/Main.java +77 -0
- package/dist/templates/java/percher.toml +11 -0
- package/dist/templates/laravel/Dockerfile +15 -0
- package/dist/templates/laravel/composer.json +15 -0
- package/dist/templates/laravel/percher.toml +11 -0
- package/dist/templates/laravel/public/index.php +37 -0
- package/dist/templates/nextjs/app/api/health/route.ts +3 -0
- package/dist/templates/nextjs/app/layout.tsx +11 -0
- package/dist/templates/nextjs/app/page.tsx +10 -0
- package/dist/templates/nextjs/next.config.ts +5 -0
- package/dist/templates/nextjs/package.json +15 -0
- package/dist/templates/nextjs/percher.toml +15 -0
- package/dist/templates/node/index.js +26 -0
- package/dist/templates/node/index.ts +12 -0
- package/dist/templates/node/package.json +8 -0
- package/dist/templates/node/percher.toml +10 -0
- package/dist/templates/nuxt/app.vue +6 -0
- package/dist/templates/nuxt/nuxt.config.ts +4 -0
- package/dist/templates/nuxt/package.json +15 -0
- package/dist/templates/nuxt/percher.toml +15 -0
- package/dist/templates/nuxt/server/api/health.ts +1 -0
- package/dist/templates/phoenix/Dockerfile +15 -0
- package/dist/templates/phoenix/lib/application.ex +15 -0
- package/dist/templates/phoenix/lib/router.ex +39 -0
- package/dist/templates/phoenix/mix.exs +30 -0
- package/dist/templates/phoenix/percher.toml +11 -0
- package/dist/templates/preact/Caddyfile +7 -0
- package/dist/templates/preact/Dockerfile +34 -0
- package/dist/templates/preact/index.html +12 -0
- package/dist/templates/preact/package.json +19 -0
- package/dist/templates/preact/percher.toml +11 -0
- package/dist/templates/preact/src/main.tsx +13 -0
- package/dist/templates/preact/vite.config.ts +6 -0
- package/dist/templates/python/main.py +13 -0
- package/dist/templates/python/percher.toml +11 -0
- package/dist/templates/python/requirements.txt +2 -0
- package/dist/templates/rails/Dockerfile +11 -0
- package/dist/templates/rails/Gemfile +12 -0
- package/dist/templates/rails/config.ru +32 -0
- package/dist/templates/rails/percher.toml +11 -0
- package/dist/templates/remix/app/root.tsx +19 -0
- package/dist/templates/remix/app/routes/_index.tsx +10 -0
- package/dist/templates/remix/app/routes/health.tsx +3 -0
- package/dist/templates/remix/package.json +30 -0
- package/dist/templates/remix/percher.toml +15 -0
- package/dist/templates/remix/vite.config.ts +7 -0
- package/dist/templates/rust/Cargo.toml +19 -0
- package/dist/templates/rust/Dockerfile +14 -0
- package/dist/templates/rust/percher.toml +11 -0
- package/dist/templates/rust/src/main.rs +45 -0
- package/dist/templates/solid/Caddyfile +7 -0
- package/dist/templates/solid/Dockerfile +34 -0
- package/dist/templates/solid/index.html +12 -0
- package/dist/templates/solid/package.json +19 -0
- package/dist/templates/solid/percher.toml +11 -0
- package/dist/templates/solid/src/main.tsx +13 -0
- package/dist/templates/solid/vite.config.ts +6 -0
- package/dist/templates/static/index.html +15 -0
- package/dist/templates/static/percher.toml +6 -0
- package/dist/templates/static/style.css +32 -0
- package/dist/templates/sveltekit/package.json +19 -0
- package/dist/templates/sveltekit/percher.toml +15 -0
- package/dist/templates/sveltekit/src/app.html +12 -0
- package/dist/templates/sveltekit/src/routes/+page.svelte +2 -0
- package/dist/templates/sveltekit/src/routes/health/+server.ts +5 -0
- package/dist/templates/sveltekit/svelte.config.js +8 -0
- package/dist/templates/sveltekit/vite.config.js +6 -0
- package/dist/templates/vite-react/Caddyfile +7 -0
- package/dist/templates/vite-react/Dockerfile +34 -0
- package/dist/templates/vite-react/index.html +12 -0
- package/dist/templates/vite-react/package.json +22 -0
- package/dist/templates/vite-react/percher.toml +11 -0
- package/dist/templates/vite-react/src/main.tsx +20 -0
- package/dist/templates/vite-react/vite.config.ts +6 -0
- package/dist/templates/vite-vue/Caddyfile +7 -0
- package/dist/templates/vite-vue/Dockerfile +34 -0
- package/dist/templates/vite-vue/index.html +12 -0
- package/dist/templates/vite-vue/package.json +19 -0
- package/dist/templates/vite-vue/percher.toml +11 -0
- package/dist/templates/vite-vue/src/main.ts +12 -0
- package/dist/templates/vite-vue/vite.config.ts +6 -0
- package/package.json +13 -4
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
use axum::{http::header, response::Html, response::IntoResponse, routing::get, Router};
|
|
2
|
+
use std::env;
|
|
3
|
+
|
|
4
|
+
#[tokio::main]
|
|
5
|
+
async fn main() {
|
|
6
|
+
let app = Router::new()
|
|
7
|
+
.route("/", get(root))
|
|
8
|
+
.route("/health", get(health));
|
|
9
|
+
|
|
10
|
+
let port: u16 = env::var("PORT")
|
|
11
|
+
.ok()
|
|
12
|
+
.and_then(|s| s.parse().ok())
|
|
13
|
+
.unwrap_or(8080);
|
|
14
|
+
|
|
15
|
+
let listener = tokio::net::TcpListener::bind(("0.0.0.0", port))
|
|
16
|
+
.await
|
|
17
|
+
.expect("bind");
|
|
18
|
+
println!("listening on :{port}");
|
|
19
|
+
axum::serve(listener, app).await.expect("serve");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async fn root() -> Html<&'static str> {
|
|
23
|
+
Html(
|
|
24
|
+
r#"<!doctype html>
|
|
25
|
+
<html lang="en">
|
|
26
|
+
<head>
|
|
27
|
+
<meta charset="utf-8" />
|
|
28
|
+
<title>__APP_NAME__</title>
|
|
29
|
+
<style>
|
|
30
|
+
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 48px auto; padding: 0 24px; line-height: 1.6; }
|
|
31
|
+
h1 { letter-spacing: -0.5px; }
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<h1>__APP_NAME__</h1>
|
|
36
|
+
<p>A Rust app deployed on Percher.</p>
|
|
37
|
+
<p>Add routes in <code>src/main.rs</code> and push to redeploy.</p>
|
|
38
|
+
</body>
|
|
39
|
+
</html>"#,
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async fn health() -> impl IntoResponse {
|
|
44
|
+
([(header::CONTENT_TYPE, "application/json")], r#"{"ok":true}"#)
|
|
45
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Multi-stage build: a Bun stage compiles the static bundle, then a
|
|
2
|
+
# minimal Caddy image serves it. This project uses runtime = "docker"
|
|
3
|
+
# (not "static") because Percher's static runtime serves pre-built
|
|
4
|
+
# files only — it does not run a build command. Generated by Percher;
|
|
5
|
+
# safe to edit and own.
|
|
6
|
+
|
|
7
|
+
# --- Build stage: install deps and build the static bundle -----------
|
|
8
|
+
FROM oven/bun:1-alpine AS build
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
COPY . .
|
|
11
|
+
RUN bun install && bun run build
|
|
12
|
+
|
|
13
|
+
# --- Serve stage: minimal Caddy image --------------------------------
|
|
14
|
+
# caddy:2-alpine ships /usr/bin/caddy with cap_net_bind_service file
|
|
15
|
+
# caps. Percher runs every container with --security-opt
|
|
16
|
+
# no-new-privileges, which makes execve refuse a cap-bearing binary
|
|
17
|
+
# (an "operation not permitted" crash-loop). Copy Caddy onto a plain
|
|
18
|
+
# alpine base and strip the caps with setcap -r — Caddy never needs
|
|
19
|
+
# the cap here, it listens on :8080 (>= 1024).
|
|
20
|
+
FROM caddy:2-alpine AS caddy-source
|
|
21
|
+
FROM alpine:3.21
|
|
22
|
+
COPY --from=caddy-source /usr/bin/caddy /usr/bin/caddy
|
|
23
|
+
RUN apk add --no-cache libcap \
|
|
24
|
+
&& setcap -r /usr/bin/caddy \
|
|
25
|
+
&& apk del libcap \
|
|
26
|
+
&& rm -rf /var/cache/apk/*
|
|
27
|
+
COPY Caddyfile /etc/caddy/Caddyfile
|
|
28
|
+
COPY --from=build /app/dist /srv
|
|
29
|
+
# HOME points at the writable tmpfs so non-root Caddy can persist its
|
|
30
|
+
# XDG state (storage-clean lock, config autosave) under Percher's
|
|
31
|
+
# read-only root filesystem.
|
|
32
|
+
ENV HOME=/tmp
|
|
33
|
+
EXPOSE 8080
|
|
34
|
+
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"solid-js": "^1.8.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"vite": "^5.3.0",
|
|
16
|
+
"vite-plugin-solid": "^2.10.0",
|
|
17
|
+
"typescript": "^5.5.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { render } from "solid-js/web";
|
|
2
|
+
|
|
3
|
+
function App() {
|
|
4
|
+
return (
|
|
5
|
+
<main style={{ "font-family": "system-ui", padding: "40px" }}>
|
|
6
|
+
<h1>Hello from __APP_NAME__</h1>
|
|
7
|
+
<p>Solid + Vite, served as static from Percher.</p>
|
|
8
|
+
</main>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const root = document.getElementById("app");
|
|
13
|
+
if (root) render(() => <App />, root);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
<link rel="stylesheet" href="style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>__APP_NAME__</h1>
|
|
12
|
+
<p>Edit <code>index.html</code> and run <code>bunx percher push</code> to deploy.</p>
|
|
13
|
+
</main>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
* {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
9
|
+
min-height: 100vh;
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
background: #fafafa;
|
|
14
|
+
color: #111;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
main {
|
|
18
|
+
text-align: center;
|
|
19
|
+
padding: 2rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
h1 {
|
|
23
|
+
font-size: 2rem;
|
|
24
|
+
margin-bottom: 0.5rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
code {
|
|
28
|
+
background: #e8e8e8;
|
|
29
|
+
padding: 0.15em 0.4em;
|
|
30
|
+
border-radius: 4px;
|
|
31
|
+
font-size: 0.9em;
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite dev",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"start": "node build/index.js"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@sveltejs/adapter-node": "^5.2.0",
|
|
14
|
+
"@sveltejs/kit": "^2.5.0",
|
|
15
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
|
16
|
+
"svelte": "^5.0.0",
|
|
17
|
+
"vite": "^5.4.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
%sveltekit.head%
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div>%sveltekit.body%</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Multi-stage build: a Bun stage compiles the static bundle, then a
|
|
2
|
+
# minimal Caddy image serves it. This project uses runtime = "docker"
|
|
3
|
+
# (not "static") because Percher's static runtime serves pre-built
|
|
4
|
+
# files only — it does not run a build command. Generated by Percher;
|
|
5
|
+
# safe to edit and own.
|
|
6
|
+
|
|
7
|
+
# --- Build stage: install deps and build the static bundle -----------
|
|
8
|
+
FROM oven/bun:1-alpine AS build
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
COPY . .
|
|
11
|
+
RUN bun install && bun run build
|
|
12
|
+
|
|
13
|
+
# --- Serve stage: minimal Caddy image --------------------------------
|
|
14
|
+
# caddy:2-alpine ships /usr/bin/caddy with cap_net_bind_service file
|
|
15
|
+
# caps. Percher runs every container with --security-opt
|
|
16
|
+
# no-new-privileges, which makes execve refuse a cap-bearing binary
|
|
17
|
+
# (an "operation not permitted" crash-loop). Copy Caddy onto a plain
|
|
18
|
+
# alpine base and strip the caps with setcap -r — Caddy never needs
|
|
19
|
+
# the cap here, it listens on :8080 (>= 1024).
|
|
20
|
+
FROM caddy:2-alpine AS caddy-source
|
|
21
|
+
FROM alpine:3.21
|
|
22
|
+
COPY --from=caddy-source /usr/bin/caddy /usr/bin/caddy
|
|
23
|
+
RUN apk add --no-cache libcap \
|
|
24
|
+
&& setcap -r /usr/bin/caddy \
|
|
25
|
+
&& apk del libcap \
|
|
26
|
+
&& rm -rf /var/cache/apk/*
|
|
27
|
+
COPY Caddyfile /etc/caddy/Caddyfile
|
|
28
|
+
COPY --from=build /app/dist /srv
|
|
29
|
+
# HOME points at the writable tmpfs so non-root Caddy can persist its
|
|
30
|
+
# XDG state (storage-clean lock, config autosave) under Percher's
|
|
31
|
+
# read-only root filesystem.
|
|
32
|
+
ENV HOME=/tmp
|
|
33
|
+
EXPOSE 8080
|
|
34
|
+
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"react": "^18.3.0",
|
|
13
|
+
"react-dom": "^18.3.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/react": "^18.3.0",
|
|
17
|
+
"@types/react-dom": "^18.3.0",
|
|
18
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
19
|
+
"typescript": "^5.5.0",
|
|
20
|
+
"vite": "^5.3.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { StrictMode } from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
|
|
4
|
+
function App() {
|
|
5
|
+
return (
|
|
6
|
+
<main style={{ fontFamily: "system-ui", padding: 40 }}>
|
|
7
|
+
<h1>Hello from __APP_NAME__</h1>
|
|
8
|
+
<p>React + Vite, served as static from Percher.</p>
|
|
9
|
+
</main>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const root = document.getElementById("app");
|
|
14
|
+
if (root) {
|
|
15
|
+
createRoot(root).render(
|
|
16
|
+
<StrictMode>
|
|
17
|
+
<App />
|
|
18
|
+
</StrictMode>,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Multi-stage build: a Bun stage compiles the static bundle, then a
|
|
2
|
+
# minimal Caddy image serves it. This project uses runtime = "docker"
|
|
3
|
+
# (not "static") because Percher's static runtime serves pre-built
|
|
4
|
+
# files only — it does not run a build command. Generated by Percher;
|
|
5
|
+
# safe to edit and own.
|
|
6
|
+
|
|
7
|
+
# --- Build stage: install deps and build the static bundle -----------
|
|
8
|
+
FROM oven/bun:1-alpine AS build
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
COPY . .
|
|
11
|
+
RUN bun install && bun run build
|
|
12
|
+
|
|
13
|
+
# --- Serve stage: minimal Caddy image --------------------------------
|
|
14
|
+
# caddy:2-alpine ships /usr/bin/caddy with cap_net_bind_service file
|
|
15
|
+
# caps. Percher runs every container with --security-opt
|
|
16
|
+
# no-new-privileges, which makes execve refuse a cap-bearing binary
|
|
17
|
+
# (an "operation not permitted" crash-loop). Copy Caddy onto a plain
|
|
18
|
+
# alpine base and strip the caps with setcap -r — Caddy never needs
|
|
19
|
+
# the cap here, it listens on :8080 (>= 1024).
|
|
20
|
+
FROM caddy:2-alpine AS caddy-source
|
|
21
|
+
FROM alpine:3.21
|
|
22
|
+
COPY --from=caddy-source /usr/bin/caddy /usr/bin/caddy
|
|
23
|
+
RUN apk add --no-cache libcap \
|
|
24
|
+
&& setcap -r /usr/bin/caddy \
|
|
25
|
+
&& apk del libcap \
|
|
26
|
+
&& rm -rf /var/cache/apk/*
|
|
27
|
+
COPY Caddyfile /etc/caddy/Caddyfile
|
|
28
|
+
COPY --from=build /app/dist /srv
|
|
29
|
+
# HOME points at the writable tmpfs so non-root Caddy can persist its
|
|
30
|
+
# XDG state (storage-clean lock, config autosave) under Percher's
|
|
31
|
+
# read-only root filesystem.
|
|
32
|
+
ENV HOME=/tmp
|
|
33
|
+
EXPOSE 8080
|
|
34
|
+
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__APP_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"vue": "^3.4.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@vitejs/plugin-vue": "^5.0.0",
|
|
16
|
+
"typescript": "^5.5.0",
|
|
17
|
+
"vite": "^5.3.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createApp, h } from "vue";
|
|
2
|
+
|
|
3
|
+
const App = {
|
|
4
|
+
render() {
|
|
5
|
+
return h("main", { style: "font-family: system-ui; padding: 40px;" }, [
|
|
6
|
+
h("h1", "Hello from __APP_NAME__"),
|
|
7
|
+
h("p", "Vue + Vite, served as static from Percher."),
|
|
8
|
+
]);
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
createApp(App).mount("#app");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "percher",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "CLI for the Percher hosting platform — publish apps with one command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
"default": "./dist/src/index.js"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"files": [
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
19
21
|
"scripts": {
|
|
20
|
-
"build": "tsc -p tsconfig.json && bun build bin/percher.ts --outfile dist/bin/percher.js --target node --format esm && node -e \"require('fs').chmodSync('dist/bin/percher.js',0o755)\"",
|
|
22
|
+
"build": "tsc -p tsconfig.json && bun build bin/percher.ts --outfile dist/bin/percher.js --target node --format esm && node scripts/copy-templates.mjs && node -e \"require('fs').chmodSync('dist/bin/percher.js',0o755)\"",
|
|
21
23
|
"test": "bun test",
|
|
22
24
|
"typecheck": "tsc --noEmit"
|
|
23
25
|
},
|
|
@@ -41,5 +43,12 @@
|
|
|
41
43
|
"type": "git",
|
|
42
44
|
"url": "https://github.com/mattiasmalmborg/percher"
|
|
43
45
|
},
|
|
44
|
-
"keywords": [
|
|
46
|
+
"keywords": [
|
|
47
|
+
"hosting",
|
|
48
|
+
"deploy",
|
|
49
|
+
"cli",
|
|
50
|
+
"paas",
|
|
51
|
+
"bun",
|
|
52
|
+
"ai"
|
|
53
|
+
]
|
|
45
54
|
}
|