Updated public site

Updated gitea config
added immich stub
added config to allow override of landing page
added nodejs
This commit is contained in:
Ellis Rahhal 2024-11-22 23:59:44 -08:00
parent 3b6e6dd590
commit e42c42f2db
24 changed files with 1127 additions and 11 deletions

View file

@ -1,7 +1,7 @@
## @TODO: Look at the following for a VM test setup
## https://github.com/nix-community/disko/blob/master/module.nix
{ config, lib, extendModules, ... }:
{ config, lib, pkgs, extendModules, ... }:
# let
# vmVariantWithHomefree = extendModules {
@ -454,6 +454,14 @@
};
});
};
landing-page = {
path = lib.mkOption {
type = lib.types.str;
default = "${pkgs.homefree-site}/lib/node_modules/homefree-site/public";
description = "Path to landing page";
};
};
};
# options.virtualisation.vmVariantWithHomefree = lib.mkOption {

View file

@ -252,6 +252,7 @@
neofetch
nil
nix-index
nodejs
openssl
# openjdk16-bootstrap
p7zip

View file

@ -4,9 +4,17 @@ let
respond "Hello, world! I am being accessed from {scheme}."
'';
proxiedHostConfig = config.homefree.proxied-hosts;
site = pkgs.callPackage ../site { };
homefree-site = pkgs.callPackage ../site { };
in
{
## add homefree default site as a package
nixpkgs.overlays = [
(final: prev: {
homefree-site = homefree-site;
})
];
systemd.services.caddy = {
after = [ "network.target" "network-online.target" "unbound.service" ];
requires = [ "network-online.target" "unbound.service" ];
@ -65,11 +73,11 @@ in
{
"http://localhost, https://localhost, https://${config.homefree.system.domain}, https://www.${config.homefree.system.domain}" = {
logFormat = ''
output file ${config.services.caddy.logDir}/access-homefree-site.log
output file ${config.services.caddy.logDir}/access-landing-page.log
'';
extraConfig = ''
bind 10.0.0.1 192.168.2.1 ${config.homefree.system.domain}
root * ${site}/lib/node_modules/homefree-site/_site/
root * ${config.homefree.landing-page.path}
file_server
'';
};

View file

@ -45,13 +45,27 @@ in
systemd.network = {
networks = {
# "01-${wan-interface}" = {
# name = wan-interface;
# networkConfig = {
# DHCP = "yes";
# IPv6AcceptRA = "yes";
# ## systemd-networkd will assign an address to the LAN interface
# IPv6SendRA = "no";
# IPv6PrivacyExtensions = "kernel";
# };
# dhcpV6Config = {
# PrefixDelegation = "yes";
# Without = "WithoutPrefixDelegation";
# };
# };
"01-${lan-interface}" = {
name = lan-interface;
networkConfig = {
Description = "LAN link";
Address = "10.0.0.1/24";
LinkLocalAddressing = "yes";
IPv6AcceptRA = "yes";
IPv6AcceptRA = "no";
# Announce a prefix here and act as a router.
IPv6SendRA = "yes";
# Use a DHCPv6-PD delegated prefix (DHCPv6PrefixDelegation.SubnetId)
@ -63,6 +77,13 @@ in
EmitDNS = "no";
EmitDomains = "no";
};
ipv6Prefixes = [
{
ipv6PrefixConfig = {
Prefix = "::/64";
};
}
];
};
};
};

View file

@ -14,6 +14,12 @@
START_SSH_SERVER = true;
SSH_PORT = 3022;
};
migrations = {
ALLOWED_DOMAINS = "*";
ALLOW_LOCALNETWORKS = true;
SKIP_TLS_VERIFY = true;
};
# service.DISABLE_REGISTRATION = true;
};
};

10
services/immich.nix Normal file
View file

@ -0,0 +1,10 @@
{ ... }:
{
services.immich = {
enable = true;
environment.IMMICH_MACHINE_LEARNING_URL = "http://localhost:3003";
};
## Enable VA-API support
users.users.immich.extraGroups = [ "video" "render" ];
}

View file

@ -4,5 +4,5 @@ buildNpmPackage {
name = "site";
src = ./.;
# npmDepsHash = lib.fakeHash;
npmDepsHash = "sha256-w/uQ+FVHu9/pwwgKAvManocPKUAOHcFmBIG18pUDu14=";
npmDepsHash = "sha256-+laHFZIwVqx9A8lim6amX5HdfCFkgFiU5QHHScV5lSY=";
}

34
site/eleventy.config.js Normal file
View file

@ -0,0 +1,34 @@
// import EleventyI18nPlugin from '@11ty/eleventy';
// import pluginRss from '@11ty/eleventy-plugin-rss';
// import syntaxHighlight from '@11ty/eleventy-plugin-syntaxhighlight';
export default async function (eleventyConfig) {
// eleventyConfig.addPlugin(EleventyI18nPlugin, {
// defaultLanguage: 'en',
// errorMode: 'allow-fallback',
// });
//
// eleventyConfig.addPlugin(pluginRss);
//
// eleventyConfig.addPlugin(syntaxHighlight, {
// preAttributes: {
// tabindex: 0,
// },
// });
eleventyConfig.addPassthroughCopy("src/css");
eleventyConfig.addPassthroughCopy("src/images");
return {
htmlTemplateEngine: 'njk',
markdownTemplateEngine: 'njk',
dir: {
input: 'src',
data: 'data',
includes: 'includes',
layouts: 'layouts',
output: "public",
},
pathPrefix: '',
};
}

View file

@ -1 +0,0 @@
# HomeFree

47
site/package-lock.json generated
View file

@ -1,11 +1,16 @@
{
"name": "site",
"name": "homefree-site",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "homefree-site",
"version": "0.0.1",
"dependencies": {
"@11ty/eleventy": "^3.0.0"
"@11ty/eleventy": "^3.0.0",
"@11ty/eleventy-plugin-rss": "^2.0.2",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0"
}
},
"node_modules/@11ty/dependency-tree": {
@ -142,6 +147,35 @@
"url": "https://opencollective.com/11ty"
}
},
"node_modules/@11ty/eleventy-plugin-rss": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-rss/-/eleventy-plugin-rss-2.0.2.tgz",
"integrity": "sha512-BiPsNbCvaqAORsg2NA4YqcSvMy/PZiefDU3PtGgwYJQ7A5rkRq/gdod2nu1AzwBG/0c5Qe7D49BxV0SByq9vCw==",
"license": "MIT",
"dependencies": {
"@11ty/eleventy-utils": "^1.0.3",
"@11ty/posthtml-urls": "1.0.0",
"debug": "^4.3.5",
"posthtml": "^0.16.6"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
}
},
"node_modules/@11ty/eleventy-plugin-syntaxhighlight": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-syntaxhighlight/-/eleventy-plugin-syntaxhighlight-5.0.0.tgz",
"integrity": "sha512-y9BUmP1GofmbJgxM1+ky/UpFCpD8JSOeLeKItUs0WApgnrHk9haHziW7lS86lbArX5SiCVo4zTTw9x53gvRCaA==",
"license": "MIT",
"dependencies": {
"prismjs": "^1.29.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
}
},
"node_modules/@11ty/eleventy-utils": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-1.0.3.tgz",
@ -1845,6 +1879,15 @@
"node": ">=12"
}
},
"node_modules/prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",

View file

@ -2,10 +2,14 @@
"name": "homefree-site",
"version": "0.0.1",
"private": true,
"type": "module",
"dependencies": {
"@11ty/eleventy": "^3.0.0"
"@11ty/eleventy": "^3.0.0",
"@11ty/eleventy-plugin-rss": "^2.0.2",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0"
},
"scripts": {
"build": "eleventy"
"build": "eleventy",
"watch": "eleventy --serve"
}
}

7
site/robots.njk Normal file
View file

@ -0,0 +1,7 @@
---
permalink: robots.txt
eleventyExcludeFromCollections: true
---
User-agent: *
Disallow:
Sitemap: {{ [data.baseUrl, 'sitemap.xml'] | join('/') }}

17
site/sitemap.njk Normal file
View file

@ -0,0 +1,17 @@
---
permalink: sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for page in collections.all %}
{% if not page.data.draft and not page.url.endsWith("404") %}
<url>
<loc>{{ [data.baseUrl, page.url] | join }}</loc>
{% if page.date %}
<lastmod>{{ page.date | isodate }}</lastmod>
{%endif%}
</url>
{% endif %}
{% endfor %}
</urlset>

10
site/src/404.html Normal file
View file

@ -0,0 +1,10 @@
---
title: Not Found
layout: base.html
---
<div class="container">
<h1>Not Found</h1>
<p class="text-lg paragraph">
The requested page does not exist.
</p>
</div>

192
site/src/css/main-blue.css Normal file
View file

@ -0,0 +1,192 @@
:root {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--text-primary: #e2e8f0;
--text-secondary: #94a3b8;
--accent: #3b82f6;
--max-width: 1200px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "SF Pro Display", -apple-system, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.7;
font-weight: 400; /* More substantial body text */
}
.self-hosted-banner {
background: linear-gradient(90deg, #1e40af, #3b82f6); /* Darker gradient for better contrast */
color: #ffffff; /* Pure white text */
text-align: center;
padding: 0.75rem; /* Slightly taller */
font-size: 0.875rem;
letter-spacing: 0.05em;
text-transform: uppercase;
text-shadow: 0 1px 2px rgba(0,0,0,0.2); /* Subtle shadow for better readability */
}
.self-hosted-banner strong {
font-weight: 600; /* Bolder text for emphasis */
color: #ffffff; /* Ensure strong text is also white */
}
header {
background-color: var(--bg-secondary);
padding: 1rem 0;
position: sticky;
top: 0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.container {
max-width: var(--max-width);
margin: 0 auto;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.75rem;
font-weight: 500; /* More substantial logo */
color: var(--accent);
letter-spacing: -0.04em;
}
nav ul {
display: flex;
gap: 2.5rem;
list-style: none;
}
nav a {
color: var(--text-primary);
text-decoration: none;
transition: color 0.2s;
font-weight: 400; /* More balanced nav items */
font-size: 1rem;
letter-spacing: 0.02em;
}
nav a:hover {
color: var(--accent);
}
.hero {
padding: 6rem 0;
text-align: center;
}
.hero h1 {
font-size: 4rem;
margin-bottom: 1.5rem;
font-weight: 500; /* More substantial heading */
letter-spacing: -0.05em;
line-height: 1.1;
}
.hero p {
font-size: 1.5rem;
color: var(--text-secondary);
max-width: 700px;
margin: 0 auto;
font-weight: 400; /* More balanced hero text */
letter-spacing: -0.02em;
}
.features {
padding: 4rem 0;
background-color: var(--bg-secondary);
}
.features h2 {
font-size: 2.5rem;
font-weight: 500; /* More substantial section heading */
letter-spacing: -0.04em;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.feature-card {
padding: 2rem;
background-color: var(--bg-primary);
border-radius: 0.5rem;
transition: transform 0.2s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card h3 {
margin-bottom: 1rem;
color: var(--accent);
font-size: 1.5rem;
font-weight: 500; /* More substantial card headings */
letter-spacing: -0.03em;
}
.feature-card p {
font-size: 1rem;
line-height: 1.7;
color: var(--text-secondary);
font-weight: 400; /* More balanced card text */
}
.cta {
padding: 4rem 0;
text-align: center;
}
.button {
display: inline-block;
padding: 0.875rem 2.5rem;
background-color: var(--accent);
color: white;
text-decoration: none;
border-radius: 0.25rem;
transition: background-color 0.2s;
font-weight: 500; /* More substantial button text */
font-size: 1rem;
letter-spacing: 0.02em;
}
.button:hover {
background-color: #2563eb;
}
footer {
background-color: var(--bg-secondary);
padding: 2rem 0;
text-align: center;
color: var(--text-secondary);
font-size: 0.875rem;
font-weight: 400; /* More balanced footer text */
letter-spacing: 0.02em;
}
@media (max-width: 768px) {
.hero h1 {
font-size: 3rem;
}
nav ul {
gap: 1.5rem;
}
}

145
site/src/css/main-old.css Normal file
View file

@ -0,0 +1,145 @@
:root {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--text-primary: #e2e8f0;
--text-secondary: #94a3b8;
--accent: #3b82f6;
--max-width: 1200px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: system-ui, -apple-system, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
}
header {
background-color: var(--bg-secondary);
padding: 1.5rem 0;
position: sticky;
top: 0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.container {
max-width: var(--max-width);
margin: 0 auto;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
color: var(--accent);
}
nav ul {
display: flex;
gap: 2rem;
list-style: none;
}
nav a {
color: var(--text-primary);
text-decoration: none;
transition: color 0.2s;
}
nav a:hover {
color: var(--accent);
}
.hero {
padding: 6rem 0;
text-align: center;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 1.5rem;
}
.hero p {
font-size: 1.25rem;
color: var(--text-secondary);
max-width: 600px;
margin: 0 auto;
}
.features {
padding: 4rem 0;
background-color: var(--bg-secondary);
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.feature-card {
padding: 2rem;
background-color: var(--bg-primary);
border-radius: 0.5rem;
transition: transform 0.2s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card h3 {
margin-bottom: 1rem;
color: var(--accent);
}
.cta {
padding: 4rem 0;
text-align: center;
}
.button {
display: inline-block;
padding: 1rem 2rem;
background-color: var(--accent);
color: white;
text-decoration: none;
border-radius: 0.25rem;
transition: background-color 0.2s;
}
.button:hover {
background-color: #2563eb;
}
footer {
background-color: var(--bg-secondary);
padding: 2rem 0;
text-align: center;
color: var(--text-secondary);
}
@media (max-width: 768px) {
.hero h1 {
font-size: 2.5rem;
}
nav ul {
gap: 1rem;
}
}

405
site/src/css/main.css Normal file
View file

@ -0,0 +1,405 @@
:root {
--bg-primary: #0f1922; /* Darker blue-green */
--bg-secondary: #1a2a32; /* Dark blue-green */
--text-primary: #e2e8e0; /* Slightly green-tinted white */
--text-secondary: #94b8a8; /* Muted sage */
--accent: #10b981; /* Emerald green */
--max-width: 1200px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "SF Pro Display", -apple-system, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.7;
font-weight: 400;
}
/* Update link styling */
a:not(.button) {
color: var(--accent);
text-decoration: none;
transition: all 0.2s ease;
font-weight: 500;
border-bottom: 1px solid transparent;
}
a:not(.button):hover {
color: #34d399; /* Lighter green for hover */
border-bottom: 1px solid currentColor;
}
/* Override default visited state */
a:visited {
color: var(--accent); /* Keep same as normal state */
}
a:visited:hover {
color: #34d399; /* Keep same as normal hover state */
}
.self-hosted-banner {
background: linear-gradient(90deg, #065f46, #10b981); /* Dark to light green gradient */
color: #ffffff;
text-align: center;
padding: 0.75rem;
font-size: 0.875rem;
letter-spacing: 0.05em;
text-transform: uppercase;
text-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.self-hosted-banner strong {
font-weight: 600;
color: #ffffff;
}
/* Rest of the styles remain the same, just updating colors */
header {
background-color: var(--bg-secondary);
padding: 1rem 0;
position: sticky;
top: 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
z-index: 100;
}
a.button {
display: inline-block;
padding: 0.875rem 2.5rem;
background-color: var(--accent);
color: white;
text-decoration: none;
border-radius: 0.25rem;
transition: background-color 0.2s;
font-weight: 500;
font-size: 1rem;
letter-spacing: 0.02em;
border-bottom: none;
}
a.button:hover,
a.button:visited {
color: white;
border-bottom: none;
}
a.button:hover {
background-color: #059669; /* Slightly darker green */
}
/* All other styles remain exactly the same */
.container {
max-width: var(--max-width);
margin: 0 auto;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.75rem;
font-weight: 500;
color: var(--accent);
letter-spacing: -0.04em;
text-decoration: none;
border-bottom: none;
}
nav ul {
display: flex;
gap: 2.5rem;
list-style: none;
}
/* Keep the nav links and buttons clean without underlines */
nav a,
.button {
border-bottom: none;
}
nav a:hover,
.button:hover {
border-bottom: none;
}
nav a {
color: var(--text-primary);
text-decoration: none;
transition: color 0.2s;
font-weight: 400;
font-size: 1rem;
letter-spacing: 0.02em;
}
nav a:hover {
color: var(--accent);
}
.hero {
padding: 6rem 0;
text-align: center;
}
.hero h1 {
font-size: 4rem;
margin-bottom: 1.5rem;
font-weight: 500;
letter-spacing: -0.05em;
line-height: 1.1;
}
.hero p {
font-size: 1.5rem;
color: var(--text-secondary);
max-width: 700px;
margin: 0 auto;
font-weight: 400;
letter-spacing: -0.02em;
}
.features {
padding: 4rem 0;
background-color: var(--bg-secondary);
}
.features h2 {
font-size: 2.5rem;
font-weight: 500;
letter-spacing: -0.04em;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.feature-card {
padding: 2rem;
background-color: var(--bg-primary);
border-radius: 0.5rem;
transition: transform 0.2s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card h3 {
margin-bottom: 1rem;
color: var(--accent);
font-size: 1.5rem;
font-weight: 500;
letter-spacing: -0.03em;
}
.feature-card p {
font-size: 1rem;
line-height: 1.7;
color: var(--text-secondary);
font-weight: 400;
}
.cta {
padding: 4rem 0;
text-align: center;
}
.code-bg {
--code-bg: #151f28; /* Add this to your :root if not already present */
}
.quick-start {
width: 100%;
max-width: var(--max-width);
margin: 0 auto;
padding: 4rem 0;
display: flex;
flex-direction: column;
align-items: center;
}
.quick-start .container {
display: flex;
flex-direction: column;
align-items: center;
}
.quick-start h1 {
font-size: 3rem;
font-weight: 500;
letter-spacing: -0.05em;
margin-bottom: 1.5rem;
text-align: center;
background: linear-gradient(90deg, var(--accent), #34d399); /* Green gradient */
background-clip: text;
color: transparent;
text-shadow: 0 2px 10px rgba(16, 185, 129, 0.1); /* Subtle glow using accent color */
}
.quick-start-intro {
color: var(--text-secondary);
font-size: 1.25rem;
max-width: 800px;
margin-bottom: 3rem;
text-align: center;
margin-left: auto;
margin-right: auto;
}
.quick-start > h1,
.quick-start > .quick-start-intro,
.quick-start > .step {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.step {
margin-bottom: 2rem;
max-width: 800px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
.step:last-child {
margin-bottom: 0;
}
.step h2 {
font-size: 1.75rem;
font-weight: 500;
color: var(--accent);
display: flex;
width: 100%;
align-items: center;
justify-content: left;
gap: 1rem;
}
.step-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
background-color: var(--bg-secondary);
border-radius: 50%;
font-size: 1.25rem;
font-weight: 500;
}
.step p,
.step .code-block,
.step .note,
.step ul {
width: 100%;
text-align: left;
}
.step p {
margin-top: 1rem;
}
.code-block {
background-color: #1e1e1e;
padding: 1.5rem;
border-radius: 0.5rem;
margin: 1rem 0;
overflow-x: auto;
font-family: 'SF Mono', Menlo, Monaco, Consolas, monospace;
font-size: 0.9rem;
position: relative;
border: 1px solid #333; /* Subtle border */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); /* Depth effect */
z-index: 1;
}
.code-block code {
color: #e2e8f0;
display: block;
line-height: 1.5;
margin-top: 1.5rem;
}
/* Optional: Add a terminal-like top bar */
.code-block::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2rem;
background: #2a2a2a; /* Slightly lighter than main background */
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
border-bottom: 1px solid #333;
}
/* Add terminal circles */
.code-block::after {
content: '• • •';
position: absolute;
top: 0.6rem;
left: 1rem;
font-size: 0.8rem;
letter-spacing: 0.3rem;
color: #666;
}
.note {
background-color: var(--bg-secondary);
padding: 1rem 1.5rem;
border-left: 4px solid var(--accent);
border-radius: 0.25rem;
margin: 1rem 0;
}
.note strong {
color: var(--accent);
}
footer {
background-color: var(--bg-secondary);
margiun-top: 4rem;
padding: 2rem 0;
text-align: center;
color: var(--text-secondary);
font-size: 0.875rem;
font-weight: 400;
letter-spacing: 0.02em;
}
@media (max-width: 768px) {
.hero h1 {
font-size: 3rem;
}
nav ul {
gap: 1.5rem;
}
.quick-start h1 {
font-size: 2.5rem;
}
.step h2 {
font-size: 1.5rem;
}
}

15
site/src/css/noscript.css Normal file
View file

@ -0,0 +1,15 @@
#wrapper {
opacity: 1 !important;
}
#overlay {
opacity: 1 !important;
}
#header {
opacity: 1 !important;
}
#header nav li {
opacity: 1 !important;
}

16
site/src/data/data.json Normal file
View file

@ -0,0 +1,16 @@
{
"author": "Ellis Rahhal",
"authorUri": "https://homefree.host",
"languages": [ "en" ],
"languageLabels": {
"en": "English"
},
"title": {
"en": "Homefree Self Hosting"
},
"baseUrl": "http://localhost:8080",
"keywords": {
"en": "homefree, self-hosting, libre, homelab, router, nixos"
}
}

View file

@ -0,0 +1,5 @@
<footer>
<div class="container">
<p>&copy; 2024 HomeFree.</p>
</div>
</footer>

View file

@ -0,0 +1,15 @@
<div class="self-hosted-banner">
✨ This site is self-hosted using <strong>HomeFree</strong> - Try it yourself!
</div>
<header>
<nav class="container">
<div class="logo">
<a href="/" class="button">HomeFree</a>
</div>
<ul>
<li><a href="/#features">Features</a></li>
<li><a href="/quick-start">Docs</a></li>
<li><a href="https://git.homefree.host/homefree">Git</a></li>
</ul>
</nav>
</header>

38
site/src/index.html Normal file
View file

@ -0,0 +1,38 @@
---
title: HomeFree
layout: base.html
---
<section class="hero container">
<h1>HomeFree: Own Your Data</h1>
<p>Turnkey Personal Application Server and Router. Step out of Google and Apple's control.</p>
<div style="margin-top: 2rem;">
<a href="/quick-start" class="button">Get Started</a>
</div>
</section>
<section class="features" id="features">
<a href="#features"></a>
<div class="container">
<h2>Features</h2>
<div class="features-grid">
<div class="feature-card">
<h3>All-In-One</h3>
<p>Dynamic DNS, Ad Block, Automatic HTTPS, Firewall, VPN, and many applications, such as Photos, Calendar, Contacts, and more.</p>
</div>
<div class="feature-card">
<h3>Turnkey</h3>
<p>Easy enough for anyone to use. Plug it in and follow a simple web-based installation.</p>
</div>
<div class="feature-card">
<h3>Safe, Private, and All Yours</h3>
<p>Why should trillion dollar mega-corps own your data? Maintain data sovereignty. All your data encrypted and backed up privately.</p>
</div>
</div>
</div>
</section>
<section class="cta container">
<h2>Ready to Get Started?</h2>
<p style="margin: 1rem 0 2rem;">Currently in Technical Preview.</p>
<a href="https://git.homefree.host/homefree" class="button">Source Code</a>
</section>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<meta name="generator" content="{{ eleventy.generator }}">
<meta name="description" content="{{ title }}">
<meta name="author" content="{{ data.author }}">
<meta name="keywords" content="{{ data.keywords[lang] }}">
<link rel="stylesheet" href="/css/main.css">
<noscript><link rel="stylesheet" href="/css/noscript.css" /></noscript>
<title>{{ title }}</title>
</head>
<body>
{% include "elements/header.html" %}
<main>
{{ content | safe }}
</main>
{% include "elements/footer.html" %}
</body>
</html>

95
site/src/quick-start.html Normal file
View file

@ -0,0 +1,95 @@
---
title: HomeFree Quick Start
layout: base.html
---
<div class="quick-start container">
<h1>Quick Start Guide</h1>
<p class="quick-start-intro">
NOTE: HomeFree is still under heavy development, and not yet ready for use by non-technical users. This guide is
for users and developers comfortable installing and configuring software on Linux.
</p>
<div class="step">
<h2><span class="step-number">1</span>Acquire Hardware</h2>
<p>HomeFree has been tested on AMD and Intel-based x86 hardware. The minimum requirements are still in flux,
but you'll want a device that has at least 8Gb of memory and a decent CPU, since it will be running many
services. It also MUST have two ethernet ports, one for the WAN/connection to the public internet, and one
for your LAN/intranet.</p>
<p>This instance is running on an <a href="https://www.tomsguide.com/reviews/intel-NUC-9-Pro" target="_blank">Intel NUC 9 Pro NUC9VXQNX</a>,
but it surely will run on less expensive hardware.</b>
</div>
<div class="step">
<h2><span class="step-number">2</span>Get a Nix environment set up on your host machine.</h2>
<p>HomeFree must be deployed from another machine with Nix installed. If you are on NixOS, you should be good to go.
If you are on a different distribution of Linux, follow the <a href="https://nixos.org/download/" target="_blank">instructions</a> on how
to install and use Nix.</p>
</div>
<div class="step">
<h2><span class="step-number">3</span>Get the code</h2>
<p>Download the <a href="https://git.homefree.host/homefree/sample-config" target="_blank">sample host config</a> to your workstation.</p>
<div class="code-block">
<code>git clone https://git.homefree.host/homefree/sample-config</code>
</div>
</div>
<div class="step">
<h2><span class="step-number">4</span>Prepare the configuration</h2>
<p>Update configuration.nix with your preferred settings. More details TBD.</p>
</div>
<div class="step">
<h2><span class="step-number">5</span>Get the IP address of the target machine</h2>
<p>Create a bootable USB flash drive of the minimal NixOS ISO image. Simple instructions can be found <a href="https://nixos.wiki/wiki/NixOS_Installation_Guide/Unetbootin" target="_blank">here</a>.</p>
<p>Boot the target machine with the USB flash drive</p>
</div>
<div class="step">
<h2><span class="step-number">6</span>Hardware Preparation</h2>
<p>Disable secure boot in the BIOS of the target machine.</p>
<p>Plug the machine into an ethernet cable.</p>
<div class="note">
<strong>Note:</strong> Installation currently does not work over WiFi.
</div>
</div>
<div class="step">
<h2><span class="step-number">7</span>Create NixOS bootable flash drive and boot up machine</h2>
<p>After the machine is has booted the minimal NixOS image and you are logged in, get the IP address with the following:</p>
<div class="code-block">
<code>
ifconfig
</code>
</div>
</div>
<div class="step">
<h2><span class="step-number">8</span>Install HomeFree</h2>
<p>Run the installation script. Again, make sure the target computer is connected to an ethernet cable.</p>
<p>Enter the IP of the target machine as directed.</p>
<div class="code-block">
<code>
./install.sh
</code>
</div>
</div>
<div class="step">
<h2><span class="step-number">9</span>Next Steps</h2>
<p>Now that you have a running instance, you should be able to log in with:</p>
<div class="code-block">
<code>ssh [adminUsername]@10.0.0.1</code>
</div>
<p>You might want to:</p>
<ul style="list-style-position: inside; margin-top: 1rem;">
<li>Browse to https://www.[your domain]</li>
<li>Explore the configuration options</li>
<li>Set up authentication</li>
<li>Verify that DDNS is configured properly and your domain is pointing at your server</li>
</ul>
<div class="note" style="margin-top: 1.5rem;">
<strong>Need help?</strong> Check out the documentation or get in touch for support.
</div>
</div>
</div>