percher 0.3.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 +111952 -18543
- package/dist/package.json +15 -6
- 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 +75 -7
- 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/status.d.ts +4 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +53 -0
- package/dist/src/commands/status.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 +44 -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 +15 -6
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
// Minimal router — swap in Laravel's bootstrap/app.php once you run
|
|
3
|
+
// `composer create-project laravel/laravel .` to upgrade to the full framework.
|
|
4
|
+
|
|
5
|
+
$uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
|
|
6
|
+
|
|
7
|
+
if ($uri === "/health") {
|
|
8
|
+
header("Content-Type: application/json");
|
|
9
|
+
echo json_encode(["ok" => true]);
|
|
10
|
+
exit;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if ($uri === "/") {
|
|
14
|
+
header("Content-Type: text/html; charset=utf-8");
|
|
15
|
+
echo <<<HTML
|
|
16
|
+
<!doctype html>
|
|
17
|
+
<html lang="en">
|
|
18
|
+
<head>
|
|
19
|
+
<meta charset="utf-8" />
|
|
20
|
+
<title>__APP_NAME__</title>
|
|
21
|
+
<style>
|
|
22
|
+
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 48px auto; padding: 0 24px; line-height: 1.6; }
|
|
23
|
+
h1 { letter-spacing: -0.5px; }
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<h1>__APP_NAME__</h1>
|
|
28
|
+
<p>A PHP app deployed on Percher.</p>
|
|
29
|
+
<p>To upgrade to full Laravel: <code>composer create-project laravel/laravel .</code></p>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
32
|
+
HTML;
|
|
33
|
+
exit;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
http_response_code(404);
|
|
37
|
+
echo "Not found";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default function Home() {
|
|
2
|
+
return (
|
|
3
|
+
<main style={{ fontFamily: "system-ui", padding: "2rem", maxWidth: 600, margin: "0 auto" }}>
|
|
4
|
+
<h1>__APP_NAME__</h1>
|
|
5
|
+
<p>
|
|
6
|
+
Edit <code>app/page.tsx</code> and run <code>bunx percher push</code> to deploy.
|
|
7
|
+
</p>
|
|
8
|
+
</main>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"next": "^15.0.0",
|
|
12
|
+
"react": "^19.0.0",
|
|
13
|
+
"react-dom": "^19.0.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const http = require("node:http");
|
|
2
|
+
|
|
3
|
+
const port = Number(process.env.PORT ?? 3000);
|
|
4
|
+
|
|
5
|
+
const server = http.createServer((req, res) => {
|
|
6
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
7
|
+
|
|
8
|
+
if (url.pathname === "/health") {
|
|
9
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
10
|
+
res.end(JSON.stringify({ status: "ok" }));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (url.pathname === "/") {
|
|
15
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
16
|
+
res.end("Hello from __APP_NAME__!");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
21
|
+
res.end("Not found");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
server.listen(port, "0.0.0.0", () => {
|
|
25
|
+
console.log(`[__APP_NAME__] listening on http://0.0.0.0:${port}`);
|
|
26
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const server = Bun.serve({
|
|
2
|
+
port: Number(process.env.PORT ?? 3000),
|
|
3
|
+
fetch(req) {
|
|
4
|
+
const url = new URL(req.url);
|
|
5
|
+
if (url.pathname === "/health") {
|
|
6
|
+
return Response.json({ status: "ok" });
|
|
7
|
+
}
|
|
8
|
+
return new Response("Hello from __APP_NAME__!");
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log(`Listening on http://localhost:${server.port}`);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "nuxt build",
|
|
8
|
+
"dev": "nuxt dev",
|
|
9
|
+
"start": "node .output/server/index.mjs"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"nuxt": "^3.13.0",
|
|
13
|
+
"vue": "^3.4.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default defineEventHandler(() => ({ status: "ok" }));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
FROM elixir:1.17-alpine
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
RUN apk add --no-cache build-base \
|
|
4
|
+
&& addgroup -S app && adduser -S app -G app \
|
|
5
|
+
&& mkdir -p /home/app/.mix \
|
|
6
|
+
&& chown -R app:app /home/app /app
|
|
7
|
+
USER app
|
|
8
|
+
RUN mix local.hex --force && mix local.rebar --force
|
|
9
|
+
COPY --chown=app:app mix.exs ./
|
|
10
|
+
RUN mix deps.get
|
|
11
|
+
COPY --chown=app:app . .
|
|
12
|
+
RUN mix compile
|
|
13
|
+
ENV PORT=4000
|
|
14
|
+
EXPOSE 4000
|
|
15
|
+
CMD ["mix", "run", "--no-halt"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
defmodule PercherApp.Application do
|
|
2
|
+
use Application
|
|
3
|
+
|
|
4
|
+
@impl true
|
|
5
|
+
def start(_type, _args) do
|
|
6
|
+
port = String.to_integer(System.get_env("PORT") || "4000")
|
|
7
|
+
|
|
8
|
+
children = [
|
|
9
|
+
{Bandit, plug: PercherApp.Router, port: port}
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
opts = [strategy: :one_for_one, name: PercherApp.Supervisor]
|
|
13
|
+
Supervisor.start_link(children, opts)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
defmodule PercherApp.Router do
|
|
2
|
+
use Plug.Router
|
|
3
|
+
|
|
4
|
+
plug(:match)
|
|
5
|
+
plug(:dispatch)
|
|
6
|
+
|
|
7
|
+
get "/health" do
|
|
8
|
+
send_resp(conn, 200, Jason.encode!(%{ok: true}))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
get "/" do
|
|
12
|
+
html = """
|
|
13
|
+
<!doctype html>
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="utf-8" />
|
|
17
|
+
<title>__APP_NAME__</title>
|
|
18
|
+
<style>
|
|
19
|
+
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 48px auto; padding: 0 24px; line-height: 1.6; }
|
|
20
|
+
h1 { letter-spacing: -0.5px; }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<h1>__APP_NAME__</h1>
|
|
25
|
+
<p>An Elixir app deployed on Percher.</p>
|
|
26
|
+
<p>To upgrade to full Phoenix, run <code>mix phx.new .</code> in this directory (replaces the current skeleton).</p>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
conn
|
|
32
|
+
|> put_resp_content_type("text/html; charset=utf-8")
|
|
33
|
+
|> send_resp(200, html)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
match _ do
|
|
37
|
+
send_resp(conn, 404, "Not found")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
defmodule PercherApp.MixProject do
|
|
2
|
+
use Mix.Project
|
|
3
|
+
|
|
4
|
+
def project do
|
|
5
|
+
[
|
|
6
|
+
app: :percher_app,
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
elixir: "~> 1.17",
|
|
9
|
+
start_permanent: Mix.env() == :prod,
|
|
10
|
+
deps: deps()
|
|
11
|
+
]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def application do
|
|
15
|
+
[
|
|
16
|
+
extra_applications: [:logger],
|
|
17
|
+
mod: {PercherApp.Application, []}
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Minimal Plug + Bandit. Run `mix phx.new .` once you're ready to upgrade
|
|
22
|
+
# to the full Phoenix framework — you'll replace this project skeleton.
|
|
23
|
+
defp deps do
|
|
24
|
+
[
|
|
25
|
+
{:plug, "~> 1.16"},
|
|
26
|
+
{:bandit, "~> 1.5"},
|
|
27
|
+
{:jason, "~> 1.4"}
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -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
|
+
"preact": "^10.22.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@preact/preset-vite": "^2.9.0",
|
|
16
|
+
"vite": "^5.3.0",
|
|
17
|
+
"typescript": "^5.5.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { render } from "preact";
|
|
2
|
+
|
|
3
|
+
function App() {
|
|
4
|
+
return (
|
|
5
|
+
<main style={{ fontFamily: "system-ui", padding: 40 }}>
|
|
6
|
+
<h1>Hello from __APP_NAME__</h1>
|
|
7
|
+
<p>Preact + 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,11 @@
|
|
|
1
|
+
FROM ruby:3.3-alpine
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
RUN apk add --no-cache build-base \
|
|
4
|
+
&& addgroup -S app && adduser -S app -G app
|
|
5
|
+
COPY --chown=app:app Gemfile ./
|
|
6
|
+
RUN bundle install --jobs 4 --retry 3
|
|
7
|
+
COPY --chown=app:app . .
|
|
8
|
+
RUN chown -R app:app /app /usr/local/bundle
|
|
9
|
+
USER app
|
|
10
|
+
EXPOSE 3000
|
|
11
|
+
CMD ["bundle", "exec", "rackup", "-o", "0.0.0.0", "-p", "3000"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
ruby "~> 3.3"
|
|
4
|
+
|
|
5
|
+
# Minimal Rack app — run `rails new . --force` (with rails + sqlite3 gems added)
|
|
6
|
+
# to upgrade to a full Rails project once you're ready.
|
|
7
|
+
gem "rack", "~> 3.1"
|
|
8
|
+
gem "rackup", "~> 2.1"
|
|
9
|
+
# rackup 2.x no longer ships a default handler — pick one explicitly.
|
|
10
|
+
# webrick is the lightest stdlib option for the starter; swap to puma
|
|
11
|
+
# / falcon when scaling.
|
|
12
|
+
gem "webrick", "~> 1.8"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
app = lambda do |env|
|
|
4
|
+
case env["PATH_INFO"]
|
|
5
|
+
when "/health"
|
|
6
|
+
[200, { "content-type" => "application/json" }, [JSON.generate({ ok: true })]]
|
|
7
|
+
when "/"
|
|
8
|
+
html = <<~HTML
|
|
9
|
+
<!doctype html>
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="utf-8" />
|
|
13
|
+
<title>__APP_NAME__</title>
|
|
14
|
+
<style>
|
|
15
|
+
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 48px auto; padding: 0 24px; line-height: 1.6; }
|
|
16
|
+
h1 { letter-spacing: -0.5px; }
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<h1>__APP_NAME__</h1>
|
|
21
|
+
<p>A Ruby app deployed on Percher.</p>
|
|
22
|
+
<p>To upgrade to full Rails, add <code>rails</code> to the Gemfile and run <code>bundle install && rails new . --force --skip-bundle</code>.</p>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
25
|
+
HTML
|
|
26
|
+
[200, { "content-type" => "text/html; charset=utf-8" }, [html]]
|
|
27
|
+
else
|
|
28
|
+
[404, { "content-type" => "text/plain" }, ["Not found"]]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
run app
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
|
|
2
|
+
|
|
3
|
+
export default function App() {
|
|
4
|
+
return (
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charSet="utf-8" />
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
9
|
+
<Meta />
|
|
10
|
+
<Links />
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<Outlet />
|
|
14
|
+
<ScrollRestoration />
|
|
15
|
+
<Scripts />
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "remix vite:build",
|
|
8
|
+
"dev": "remix vite:dev",
|
|
9
|
+
"start": "remix-serve ./build/server/index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@remix-run/node": "^2.13.0",
|
|
13
|
+
"@remix-run/react": "^2.13.0",
|
|
14
|
+
"@remix-run/serve": "^2.13.0",
|
|
15
|
+
"isbot": "^5.1.0",
|
|
16
|
+
"react": "^18.3.0",
|
|
17
|
+
"react-dom": "^18.3.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@remix-run/dev": "^2.13.0",
|
|
21
|
+
"@types/react": "^18.3.0",
|
|
22
|
+
"@types/react-dom": "^18.3.0",
|
|
23
|
+
"typescript": "^5.5.0",
|
|
24
|
+
"vite": "^5.3.0",
|
|
25
|
+
"vite-tsconfig-paths": "^5.0.0"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|