Skip to content

Commit d221b49

Browse files
authored
Add Zerops example (#461)
1 parent f5ac4b3 commit d221b49

File tree

13 files changed

+402
-0
lines changed

13 files changed

+402
-0
lines changed

zerops-example/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
3+
/.cache
4+
/build
5+
.env

zerops-example/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Zerops + Remix - Nodejs - [Preview](https://remixrun.zerops.dev/)
2+
3+
![Header Image](header.png)
4+
5+
A nodejs Remix example for Zerops which you can deploy in 2 simple steps.
6+
7+
## Instructions to Deploy on Zerops
8+
9+
1. Navigate to the Zerops Dashboard and locate the import project button on the sidebar.
10+
11+
2. Paste the Project Yaml
12+
13+
```yaml
14+
project:
15+
name: zerops-remix
16+
17+
services:
18+
- hostname: remixnode
19+
type: nodejs@18
20+
buildFromGit: https://github.com/fxck/zerops-remix-nodejs
21+
ports:
22+
- port: 3000
23+
httpSupport: true
24+
enableSubdomainAccess: true
25+
minContainers: 1
26+
```
27+
28+
If you still find yourself stuck in the process join our [Discord community](https://discord.gg/5ptAqtpyvh).
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
5+
const CopyIcon = () => (
6+
<svg
7+
xmlns="http://www.w3.org/2000/svg"
8+
width="20"
9+
height="20"
10+
viewBox="0 0 24 24"
11+
fill="none"
12+
stroke="currentColor"
13+
strokeWidth="2"
14+
strokeLinecap="round"
15+
strokeLinejoin="round"
16+
>
17+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
18+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
19+
</svg>
20+
);
21+
22+
const CheckIcon = () => (
23+
<svg
24+
xmlns="http://www.w3.org/2000/svg"
25+
width="20"
26+
height="20"
27+
viewBox="0 0 24 24"
28+
fill="none"
29+
stroke="currentColor"
30+
strokeWidth="2"
31+
strokeLinecap="round"
32+
strokeLinejoin="round"
33+
>
34+
<polyline points="20 6 9 17 4 12"></polyline>
35+
</svg>
36+
);
37+
38+
export function Code({ code }: { code: string }) {
39+
const [icon, setIcon] = useState(CopyIcon);
40+
41+
const copy = async () => {
42+
await navigator?.clipboard?.writeText(code);
43+
setIcon(CheckIcon);
44+
setTimeout(() => setIcon(CopyIcon), 2000);
45+
};
46+
47+
return (
48+
<pre>
49+
<code>{code}</code>
50+
<button onClick={copy}>{icon}</button>
51+
</pre>
52+
);
53+
}

zerops-example/app/root.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {
2+
Links,
3+
Meta,
4+
Outlet,
5+
Scripts,
6+
ScrollRestoration,
7+
} from "@remix-run/react";
8+
9+
import styles from "./styles/main.css?url";
10+
11+
export const links = () => {
12+
return [{ rel: "stylesheet", href: styles }];
13+
};
14+
15+
export function Layout({ children }: { children: React.ReactNode }) {
16+
return (
17+
<html lang="en">
18+
<head>
19+
<meta charSet="utf-8" />
20+
<meta name="viewport" content="width=device-width, initial-scale=1" />
21+
<Meta />
22+
<Links />
23+
</head>
24+
<body className="font-opensans">
25+
{children}
26+
<ScrollRestoration />
27+
<Scripts />
28+
</body>
29+
</html>
30+
);
31+
}
32+
33+
export default function App() {
34+
return <Outlet />;
35+
}

zerops-example/app/routes/_index.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type { MetaFunction } from "@remix-run/node";
2+
3+
import { Code } from "~/components/Code";
4+
5+
import styles from "../styles/main.css?url";
6+
7+
export const meta: MetaFunction = () => {
8+
return [
9+
{ title: "Remix with Zerops" },
10+
{ name: "description", content: "Say hello to remix with zerops!" },
11+
];
12+
};
13+
14+
export const links = () => {
15+
return [{ rel: "stylesheet", href: styles }];
16+
};
17+
18+
export default function Index() {
19+
const Yaml = `project:
20+
name: zerops-remix
21+
22+
services:
23+
- hostname: remixnode
24+
type: nodejs@18
25+
buildFromGit: https://github.com/fxck/zerops-remix-nodejs
26+
ports:
27+
- port: 3000
28+
httpSupport: true
29+
enableSubdomainAccess: true
30+
minContainers: 1`.trim();
31+
32+
return (
33+
<div>
34+
<div>
35+
<div>
36+
<h1>Say Hello to Remix with Zerops</h1>
37+
<h3>Step 1</h3>
38+
<p>
39+
Go to{" "}
40+
<a href="https://app.zerops.io/dashboard/projects" target="_blank" rel="noreferrer">
41+
Zerops Dashboard
42+
</a>{" "}
43+
and Click on the 'Import Project' button on the sidebar.
44+
</p>
45+
<h3>Step 2</h3>
46+
<p>
47+
Copy the YAML code mentioned below and paste it to import this
48+
example. Alternatively, you can clone zerops-solid-static to your
49+
Git Hub profile and then replace the repository URL in the
50+
buildFromGit parameter.
51+
</p>
52+
<Code code={Yaml} />
53+
<p>
54+
If you still find yourself stuck in the process join our.
55+
<a href="https://discord.gg/5ptAqtpyvh" target="_blank" rel="noreferrer">
56+
Discord community
57+
</a>
58+
</p>
59+
</div>
60+
</div>
61+
<p>
62+
Powered by{" "}
63+
<a href="https://zerops.io" target="_blank" rel="noreferrer">
64+
Zerops
65+
</a>
66+
</p>
67+
</div>
68+
);
69+
}

zerops-example/app/styles/main.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
p {
2+
color: #585858;
3+
}
4+
5+
a {
6+
color: #5282ee;
7+
font-weight: 600;
8+
}
9+
10+
a:hover {
11+
color: #4579f1;
12+
}
13+
14+
pre {
15+
background: #f7f7f7;
16+
padding: 1rem;
17+
}
18+
19+
code {
20+
color: #585858;
21+
}
22+
23+
button {
24+
border: none;
25+
border-radius: 0.25rem;
26+
color: #fff;
27+
background-color: #585858;
28+
padding: 0.25rem;
29+
cursor: pointer;
30+
}

zerops-example/header.png

15.3 KB
Loading

zerops-example/package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "zerops-example",
3+
"private": true,
4+
"sideEffects": false,
5+
"type": "module",
6+
"scripts": {
7+
"build": "remix vite:build",
8+
"dev": "remix vite:dev",
9+
"start": "cross-env NODE_ENV=production node ./server.js"
10+
},
11+
"dependencies": {
12+
"@remix-run/express": "^2.8.1",
13+
"@remix-run/node": "^2.8.1",
14+
"@remix-run/react": "^2.8.1",
15+
"compression": "^1.7.4",
16+
"express": "^4.18.2",
17+
"isbot": "^4.1.0",
18+
"morgan": "^1.10.0",
19+
"react": "^18.2.0",
20+
"react-dom": "^18.2.0"
21+
},
22+
"devDependencies": {
23+
"@remix-run/dev": "^2.8.1",
24+
"@types/compression": "^1.7.5",
25+
"@types/express": "^4.17.20",
26+
"@types/morgan": "^1.9.9",
27+
"@types/react": "^18.2.20",
28+
"@types/react-dom": "^18.2.7",
29+
"cross-env": "^7.0.3",
30+
"typescript": "^5.1.6",
31+
"vite": "^5.1.0",
32+
"vite-tsconfig-paths": "^4.2.1"
33+
},
34+
"engines": {
35+
"node": ">=18.0.0"
36+
}
37+
}

zerops-example/public/favicon.ico

16.6 KB
Binary file not shown.

zerops-example/server.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { createRequestHandler } from "@remix-run/express";
2+
import { installGlobals } from "@remix-run/node";
3+
import compression from "compression";
4+
import express from "express";
5+
import morgan from "morgan";
6+
7+
installGlobals();
8+
9+
const viteDevServer =
10+
process.env.NODE_ENV === "production"
11+
? undefined
12+
: await import("vite").then((vite) =>
13+
vite.createServer({
14+
server: { middlewareMode: true },
15+
}),
16+
);
17+
18+
const remixHandler = createRequestHandler({
19+
build: viteDevServer
20+
? () => viteDevServer.ssrLoadModule("virtual:remix/server-build")
21+
: await import("./build/server/index.js"),
22+
});
23+
24+
const app = express();
25+
26+
app.use(compression());
27+
28+
// http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header
29+
app.disable("x-powered-by");
30+
31+
// handle asset requests
32+
if (viteDevServer) {
33+
app.use(viteDevServer.middlewares);
34+
} else {
35+
// Vite fingerprints its assets so we can cache forever.
36+
app.use(
37+
"/assets",
38+
express.static("build/client/assets", { immutable: true, maxAge: "1y" }),
39+
);
40+
}
41+
42+
// Everything else (like favicon.ico) is cached for an hour. You may want to be
43+
// more aggressive with this caching.
44+
app.use(express.static("build/client", { maxAge: "1h" }));
45+
46+
app.use(morgan("tiny"));
47+
48+
// handle SSR requests
49+
app.all("*", remixHandler);
50+
51+
const port = process.env.PORT || 3000;
52+
app.listen(port, () =>
53+
console.log(`Express server listening at http://localhost:${port}`),
54+
);

0 commit comments

Comments
 (0)