From ddd2e5f9cbc7f11955404e3c6d7574313d2b4055 Mon Sep 17 00:00:00 2001 From: Ellis Rahhal Date: Sun, 24 Nov 2024 11:38:11 -0800 Subject: [PATCH] * Updated landing page * Added caching policy to landing page Caddy config * Added radicale * Added cryptpad * Added jellyfin --- default.nix | 4 +- hosts/homefree/configuration.nix | 3 + module.nix | 34 ++++ profiles/acme.nix | 11 ++ profiles/hosting.nix | 71 ++++++- services/cryptpad.nix | 28 +++ services/jellyfin.nix | 71 +++++++ services/radicale.nix | 2 +- site/default.nix | 2 +- site/package-lock.json | 4 +- site/package.json | 2 +- site/src/comparison.html | 83 ++++++++ site/src/css/main-blue.css | 192 ------------------- site/src/css/main-old.css | 145 -------------- site/src/css/main.css | 172 +++++++++++++++-- site/src/faq.html | 250 +++++++++++++++++++++++++ site/src/includes/elements/header.html | 1 + site/src/layouts/base.html | 15 +- site/src/quick-start.html | 18 +- 19 files changed, 731 insertions(+), 377 deletions(-) create mode 100644 profiles/acme.nix create mode 100644 services/cryptpad.nix create mode 100644 services/jellyfin.nix create mode 100644 site/src/comparison.html delete mode 100644 site/src/css/main-blue.css delete mode 100644 site/src/css/main-old.css create mode 100644 site/src/faq.html diff --git a/default.nix b/default.nix index 5a5ea2a..5bba16c 100644 --- a/default.nix +++ b/default.nix @@ -6,10 +6,10 @@ homefree-inputs.nixos-generators.nixosModules.all-formats homefree-inputs.nixos-hardware.nixosModules.common-cpu-intel homefree-inputs.nixos-hardware.nixosModules.common-pc-laptop - homefree-inputs.disko.nixosModules.disko - homefree-inputs.sops-nix.nixosModules.sops homefree-inputs.authentik-nix.nixosModules.default + homefree-inputs.disko.nixosModules.disko homefree-inputs.nixvim.nixosModules.nixvim + homefree-inputs.sops-nix.nixosModules.sops ./modules/ddclient-multi.nix ./module.nix ./hosts/homefree/configuration.nix diff --git a/hosts/homefree/configuration.nix b/hosts/homefree/configuration.nix index fae111f..58ead98 100644 --- a/hosts/homefree/configuration.nix +++ b/hosts/homefree/configuration.nix @@ -1,6 +1,7 @@ { config, lib, ... }: { imports = [ + ../../profiles/acme.nix ../../profiles/common.nix ../../profiles/config-editor.nix ../../profiles/git.nix @@ -13,10 +14,12 @@ ../../services/adguardhome.nix ../../services/authentik.nix + ../../services/cryptpad.nix ../../services/ddclient.nix ../../services/dnsmasq.nix ../../services/home-assistant ../../services/gitea.nix + ../../services/jellyfin.nix ../../services/postgres.nix ../../services/radicale.nix ../../services/unbound.nix diff --git a/module.nix b/module.nix index 1f51f6f..d6cfb1a 100644 --- a/module.nix +++ b/module.nix @@ -318,6 +318,26 @@ }; }; + cryptpad = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "enable Cryptpad Document service"; + }; + + public = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open to public on WAN port"; + }; + + adminKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "Public keys that have access to admin panel"; + }; + }; + homeassistant = { enable = lib.mkOption { type = lib.types.bool; @@ -346,6 +366,20 @@ }; }; + jellyfin = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "enable Jellyfin media server"; + }; + + public = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open to public on WAN port"; + }; + }; + radicale = { enable = lib.mkOption { type = lib.types.bool; diff --git a/profiles/acme.nix b/profiles/acme.nix new file mode 100644 index 0000000..dff690d --- /dev/null +++ b/profiles/acme.nix @@ -0,0 +1,11 @@ +{ config, ... }: +{ + ## Required by Cryptpad and potentially other services + security.acme = { + defaults = { + ## @TODO: Replace with a real email from config + email = "${config.homefree.system.adminUsername}@${config.homefree.system.domain}"; + }; + acceptTerms = true; + }; +} diff --git a/profiles/hosting.nix b/profiles/hosting.nix index d11b9b3..4d9dceb 100644 --- a/profiles/hosting.nix +++ b/profiles/hosting.nix @@ -45,11 +45,12 @@ in ## @TODO: Remove headers and check if still works extraConfig = '' header { + # Add general security headers Strict-Transport-Security "max-age=31536000; includeSubdomains" - X-XSS-Protection "1; mode=block" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" - Referrer-Policy "same-origin" + Referrer-Policy "strict-origin-when-cross-origin" + X-XSS-Protection "1; mode=block" } '' + (if entry.public == false then '' bind 10.0.0.1 192.168.2.1 @@ -76,17 +77,67 @@ in output file ${config.services.caddy.logDir}/access-landing-page.log ''; extraConfig = '' - header { - Cache-Control: no-cache, no-store, must-revalidate - Strict-Transport-Security "max-age=31536000; includeSubdomains" - X-XSS-Protection "1; mode=block" - X-Content-Type-Options "nosniff" - X-Frame-Options "SAMEORIGIN" - Referrer-Policy "same-origin" - } bind 10.0.0.1 192.168.2.1 ${config.homefree.system.domain} root * ${config.homefree.landing-page.path} file_server + + # Enable Gzip compression + encode gzip + + # HTML files - No caching to ensure fresh content + @html { + file + path *.html + } + header @html { + # Disable caching for HTML + Cache-Control "no-cache, must-revalidate" + # Add ETag for conditional requests + ETag + # Add Last-Modified header + +Last-Modified + } + + # CSS files - Aggressive caching with revalidation + @css { + file + path *.css + } + header @css { + # Cache for 1 year, but allow revalidation + Cache-Control "public, max-age=31536000, stale-while-revalidate=86400" + ETag + +Last-Modified + Vary Accept-Encoding + } + + # Assets (CSS, JS, images) + @assets { + file + path *.js *.png *.jpg *.jpeg *.gif *.svg *.woff *.woff2 + } + header @assets { + # Cache for 1 hour, but allow revalidation + Cache-Control "public, max-age=3600, must-revalidate" + # Add ETag for conditional requests + ETag + # Add Last-Modified header + +Last-Modified + # Add Vary header to handle different client capabilities + Vary Accept-Encoding + } + + # General headers + header { + # Remove Server header for security + -Server + # Add general security headers + Strict-Transport-Security "max-age=31536000; includeSubdomains" + X-Content-Type-Options "nosniff" + X-Frame-Options "SAMEORIGIN" + Referrer-Policy "strict-origin-when-cross-origin" + X-XSS-Protection "1; mode=block" + } ''; }; } diff --git a/services/cryptpad.nix b/services/cryptpad.nix new file mode 100644 index 0000000..e7420c3 --- /dev/null +++ b/services/cryptpad.nix @@ -0,0 +1,28 @@ +{ config, ... }: +{ + services.cryptpad = { + enable = config.homefree.services.cryptpad.enable; + configureNginx = false; + settings = { + httpPort = 3004; + httpAddress = "10.0.0.1"; + blockDailyCheck = true; + httpUnsafeOrigin = "https://cryptpad.${config.homefree.system.domain}"; + httpSafeOrigin = "https://cryptpad-ui.${config.homefree.system.domain}"; + + # Add this after you've signed up in your Cryptpad instance and copy your public key: + # adminKeys = [ "[user@cryptpad.example.com/Jil1apEPZ40j5M8nsjO1-deadbeefHkt+QExscMzKhs=]" ]; + }; + }; + + homefree.proxied-hosts = if config.homefree.services.cryptpad.enable == true then [ + { + label = "cryptpad"; + subdomains = [ "cryptpad" "cryptpad-sandbox" "cryptpad-ui" ]; + http-domains = [ "homefree.${config.homefree.system.localDomain}" ]; + https-domains = [ config.homefree.system.domain ]; + port = 3004; + public = config.homefree.services.cryptpad.public; + } + ] else []; +} diff --git a/services/jellyfin.nix b/services/jellyfin.nix new file mode 100644 index 0000000..4905771 --- /dev/null +++ b/services/jellyfin.nix @@ -0,0 +1,71 @@ +{ config, pkgs, ... }: +{ + services.jellyfin = { + enable = config.homefree.services.jellyfin.enable; + openFirewall = true; + user = config.homefree.system.adminUsername; + }; + + environment.systemPackages = [ + pkgs.jellyfin + pkgs.jellyfin-web + pkgs.jellyfin-ffmpeg + ]; + + ## Support Intro Skipper plugin + nixpkgs.overlays = with pkgs; [ + ( + final: prev: + { + jellyfin-web = prev.jellyfin-web.overrideAttrs (finalAttrs: previousAttrs: { + installPhase = '' + runHook preInstall + + # this is the important line + sed -i "s###" dist/index.html + + mkdir -p $out/share + cp -a dist $out/share/jellyfin-web + + runHook postInstall + ''; + }); + } + ) + ]; + + homefree.proxied-hosts = if config.homefree.services.jellyfin.enable == true then [ + { + label = "jellyfin"; + subdomains = [ "jellyfin" ]; + http-domains = [ "homefree.${config.homefree.system.localDomain}" ]; + https-domains = [ config.homefree.system.domain ]; + port = 8096; + public = config.homefree.services.jellyfin.public; + } + ] else []; + + ##-------------------------------------------------------------------------------- + ## Enable hardware transcoding + ## Only works on Intel + ## @TODO: Move to hardware config + ## @TODO: Add flags for which capabilities are needed by each service + ##-------------------------------------------------------------------------------- + + ## enable vaapi on OS-level + nixpkgs.config.packageOverrides = pkgs: { + vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; + }; + + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver + intel-vaapi-driver # previously vaapiIntel + vaapiVdpau + intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in) + vpl-gpu-rt # QSV on 11th gen or newer + intel-media-sdk # QSV up to 11th gen + ]; + }; +} diff --git a/services/radicale.nix b/services/radicale.nix index d4e91a6..2a9db5d 100644 --- a/services/radicale.nix +++ b/services/radicale.nix @@ -16,7 +16,7 @@ homefree.proxied-hosts = if config.homefree.services.radicale.enable == true then [ { label = "radicale"; - subdomains = [ "radicale" "webdav" "caldav" "carddav" ]; + subdomains = [ "radicale" "dav" "webdav" "caldav" "carddav" ]; http-domains = [ "homefree.${config.homefree.system.localDomain}" ]; https-domains = [ config.homefree.system.domain ]; port = 5232; diff --git a/site/default.nix b/site/default.nix index 7e29e2f..20cdbe8 100644 --- a/site/default.nix +++ b/site/default.nix @@ -4,5 +4,5 @@ buildNpmPackage { name = "site"; src = ./.; # npmDepsHash = lib.fakeHash; - npmDepsHash = "sha256-+laHFZIwVqx9A8lim6amX5HdfCFkgFiU5QHHScV5lSY="; + npmDepsHash = "sha256-uOLu/MrHS+Et9yUyZO66ANRCzG15hki+7oSTqw4eyT0="; } diff --git a/site/package-lock.json b/site/package-lock.json index b448ab9..ab9b741 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1,12 +1,12 @@ { "name": "homefree-site", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "homefree-site", - "version": "0.0.1", + "version": "0.0.2", "dependencies": { "@11ty/eleventy": "^3.0.0", "@11ty/eleventy-plugin-rss": "^2.0.2", diff --git a/site/package.json b/site/package.json index f199c4a..68d9682 100644 --- a/site/package.json +++ b/site/package.json @@ -1,6 +1,6 @@ { "name": "homefree-site", - "version": "0.0.1", + "version": "0.0.2", "private": true, "type": "module", "dependencies": { diff --git a/site/src/comparison.html b/site/src/comparison.html new file mode 100644 index 0000000..95e4de2 --- /dev/null +++ b/site/src/comparison.html @@ -0,0 +1,83 @@ +--- +title: HomeFree Product Comparison +layout: base.html +--- +
+
+

Product Comparison

+
+ +
+ There are similar systems out there but they are all missing important pieces of the puzzles to make a self-hosted + system simple and turnkey. A goal is to be able to provide a elegant Apple-like design experience in a small box with + built-in battery backup and redundant storage that you plug into your modem instead of a router, and go through a + short installation process and be up and running in minutes. There is currently no other product that does all of + the following out of the box without heavy technical lifting. +
    +
  • Router/Gateway
  • +
  • Firewall
  • +
  • Wireless Access Point
  • +
  • Ad Blocking
  • +
  • Dynamic DNS
  • +
  • Reverse Proxy with automatic certificate management
  • +
  • Full Application Suite
  • +
  • Single Sign-On
  • +
  • NAS
  • +
+
+ +
+

OPNSense/PFSense

+

+ OPNSense and PFSense + are popular Open Source router products that can replace a typical router/access point provided + by an ISP, with a lot of additional functionality like firewall functionality, ad blocking, intrusion detection, + etc. These products can be used at home, but are rather technical and complicated, requiring a lot of configuration. + They are also not very suitable for serving general applications. +

+
+
+

Ubiquiti Dream Machine Pro

+

+ The Ubiquiti Dream Machine Pro is a + similar product to OPNSense, but with a highly polished front-end. It is a corporate product, and as such is + not free, nor is it open source. It also does not work well with other network hardware that is not part of the + Ubiquiti ecosystem. It is also a relatively complex product that requires a level of technical understanding. +

+
+
+

Synology

+

+ Synology offers a wide range of products that began with + NAS (Network-Attached Storage) but has extended into offering the ability to run applications in docker containers. + Since they are first and formost network storage devices, they often don't come with much memory and CPU power, + so are not well suited to heavy application usage. Thye also are expensive and not open source, and not purpose + built as routers for WAN facing applications. +

+
+
+

TrueNAS

+

+ TrueNAS TrueNAS covers a similar NAS space to Synology, + but with an open source offering. Being open source, it can be run on better hardware and can more suitably serve + applications, but is not purpose built as a router, and would require heavy configuration to work as one. +

+
+
+

CasaOS and Umbrel

+

+ CasaOS and Umbrel + are focused on serving applications as a first class concern, but less capable in routing + and gateway capability, which would need to be configured separately. From a user experience perspective though, + they are closer to what HomeFree is trying to achieve. +

+
+
+

NextCloud and YunoHost

+

+ NextCloud and YunoHost + are heavy multi-purpose web platforms with a built-in suite of applications. They serve a more narrow niche than CasaOS + and Umbrel as they cannot run arbitrary applications, but rather those built specifically for the NextCloud ecosystem. +

+
+
diff --git a/site/src/css/main-blue.css b/site/src/css/main-blue.css deleted file mode 100644 index 6e7c3f7..0000000 --- a/site/src/css/main-blue.css +++ /dev/null @@ -1,192 +0,0 @@ -: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; - } -} diff --git a/site/src/css/main-old.css b/site/src/css/main-old.css deleted file mode 100644 index 40f9e51..0000000 --- a/site/src/css/main-old.css +++ /dev/null @@ -1,145 +0,0 @@ -: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; - } -} - diff --git a/site/src/css/main.css b/site/src/css/main.css index 60adef2..0029a6e 100644 --- a/site/src/css/main.css +++ b/site/src/css/main.css @@ -226,7 +226,7 @@ nav a:hover { width: 100%; max-width: var(--max-width); margin: 0 auto; - padding: 4rem 0; + padding: 2rem 0; display: flex; flex-direction: column; align-items: center; @@ -269,7 +269,7 @@ nav a:hover { align-items: center; } -.step { +.section { margin-bottom: 2rem; max-width: 800px; width: 100%; @@ -277,11 +277,7 @@ nav a:hover { margin-right: auto; } -.step:last-child { - margin-bottom: 0; -} - -.step h2 { +.section h2 { font-size: 1.75rem; font-weight: 500; color: var(--accent); @@ -304,15 +300,15 @@ nav a:hover { font-weight: 500; } -.step p, -.step .code-block, -.step .note, -.step ul { +.sectionp p, +.sectionp .code-block, +.sectionp .note, +.sectionp ul { width: 100%; text-align: left; } -.step p { +.section p { margin-top: 1rem; } @@ -362,6 +358,147 @@ nav a:hover { color: #666; } +.section-header { + text-align: center; + padding: 2rem 0 0 0; +} + +.section-header h1 { + font-size: 3rem; + font-weight: 500; + letter-spacing: -0.05em; + margin-bottom: 1.5rem; + background: linear-gradient(90deg, var(--accent), #34d399); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + text-shadow: 0 2px 10px rgba(16, 185, 129, 0.1); +} + +.section-header p { + color: var(--text-secondary); + font-size: 1.25rem; + max-width: 800px; + margin: 0 auto 2rem; +} + +.faq-categories { + display: flex; + justify-content: center; + gap: 1rem; + margin-bottom: 3rem; + flex-wrap: wrap; +} + +.category-button { + background-color: var(--bg-secondary); + color: var(--text-primary); + border: none; + padding: 0.5rem 1.5rem; + border-radius: 2rem; + cursor: pointer; + transition: all 0.2s ease; + font-size: 0.9rem; +} + +.category-button:hover, +.category-button.active { + background-color: var(--accent); + color: white; +} + +.faq-section { + max-width: 800px; + margin: 0 auto; + padding: 2rem 0; +} + +.faq-item { + margin-bottom: 2rem; + background-color: var(--bg-secondary); + border-radius: 0.5rem; + overflow: hidden; +} + +.faq-question { + padding: 1.5rem; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + font-weight: 500; + color: var(--accent); + transition: background-color 0.2s ease; +} + +.faq-question:hover { + background-color: rgba(16, 185, 129, 0.1); +} + +.faq-question::after { + content: '+'; + font-size: 1.5rem; + color: var(--accent); +} + +.faq-answer { + padding: 1.5rem 1.5rem 1.5rem; + color: var(--text-secondary); +} + +.faq-answer p { + margin-top: 1rem; +} + +.comparison-table { + width: 100%; + max-width: 1000px; + margin: 2rem auto; + border-collapse: collapse; + font-family: system-ui, -apple-system, sans-serif; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: hidden; +} + +.comparison-table th { + background-color: #f8fafc; + padding: 1rem; + text-align: left; + font-weight: 600; + color: #1e293b; + border-bottom: 2px solid #e2e8f0; +} + +.comparison-table td { + padding: 1rem; + border-bottom: 1px solid #e2e8f0; + color: #475569; +} + +.comparison-table tr:last-child td { + border-bottom: none; +} + +.comparison-table tr:hover td { + background-color: #f1f5f9; +} + +.feature-available { + color: #16a34a; + font-weight: 500; +} + +.feature-unavailable { + color: #dc2626; +} + +.price { + font-size: 1.25rem; + font-weight: 600; + color: #0f172a; +} + .note { background-color: var(--bg-secondary); padding: 1rem 1.5rem; @@ -398,8 +535,17 @@ footer { font-size: 2.5rem; } - .step h2 { + .section h2 { font-size: 1.5rem; } + + .section-header h1 { + font-size: 2.5rem; + } + + .faq-question, + .faq-answer { + padding: 1rem; + } } diff --git a/site/src/faq.html b/site/src/faq.html new file mode 100644 index 0000000..7cfed02 --- /dev/null +++ b/site/src/faq.html @@ -0,0 +1,250 @@ +--- +title: HomeFree FAQs +layout: base.html +--- +
+
+

Frequently Asked Questions

+ +
+ +
+
+
+ What exactly is HomeFree? +
+
+

+ HomeFree is a project with a singular goal: to allow you to control your own data by drastically reducing your + dependence on big centralized corporate services. The way this is accomplished to to own your own device and host + your own services. This has been possible for a long time but required a lot of experience and months or years of + effort to get anywhere close to making this work in a reliable and usable way. +

+

+ In the process of building a self-hosted setup at home, the realiztion dawned that all the pieces are now + available and commoditized, but there is no easy way to stitch them together and no easy way to configure them. + HomeFree aims to solve this by being very specific about choosing the right configuration and curating a + set of applications to cut through the endless choice and inconsistency of currently available systems, and + adding a single UI with a standard design language and single login to access them all. +

+
+ +
+
+ How does it differ from other available solutions? +
+
+

+ There are similar systems out there but they are all missing important pieces of the puzzles to make a self-hosted + system simple and turnkey. A goal is to be able to provide a elegant Apple-like design experience in a small box with + built-in battery backup and redundant storage that you plug directly into your modem and replaces your + router, NAS, home server, and WiFi access point, all through a short installation process to be up and running in minutes. +

+

+ For a detailed comparison with other products, check out the product comparison page. +

+
+
+ +
+
+ What types of things can I do with HomeFree? +
+
+ Almost everything that is provided by Google and other large tech companies could be a target for inclusion + in HomeFree. Services that are already included or are in work: +
    +
  • Photo hosting
  • +
  • Calendar
  • +
  • Contacts
  • +
  • Office Suite
  • +
  • File Storage
  • +
  • Video and Audio Serving
  • +
  • Home Automation
  • +
  • Video surveilance
  • +
  • Website/Blog
  • +
  • Ad Blocking
  • +
  • Password Managemenet
  • +
  • Browser Bookmark Sync
  • +
+
+
+ +
+
+ Can I access my server away from home? +
+
+ Yes! That's one of the core goals of HomeFree - to provide public facing services and access so that + you don't have to rely on large centralized services. You can configure various services to be private + to your home or open to the internet. For services that are private, you can access them remotely by + connecting to HomeFree through a built-in VPN. +
+
+ +
+
+ What are more cutting edge ideas that could be implemented? +
+
+ Anything that could run on a computer or be run as a service could be hosted by HomeFree. The goal is to make + adding modules standard and plug-and-play. AI, privacy, and decentralization are themes that could be explored. +
    +
  • External GPU plugin for AI services. Could cluster GPUs with friends, family, or even strangers
  • +
  • Decentralized social media nodes such as Bluesky and Mastadon
  • +
  • Decentralized CDNs for high traffic sites and services
  • +
  • Shared back-up services between friends and family
  • +
  • Cryptocurrency (though nothing about HomeFree is currently related to or dependency on a blockchain)
  • +
  • Pluggable DNA sequencing module for those who don't want to use a public DNA sequencing service
  • +
+
+
+ +
+
+ Is HomeFree FREE? +
+
+ Yes, it is free in both major senses of the word - it is open source, so you can install and modify it + as you please. It is also free to use, without payment. +
+
+ +
+
+ A stated goal of HomeFree is to be easy to set up. How can this be with the complexities around domain registration, + dynamically allocated IPs, and the complexities of various ISP deployments? +
+
+ Making these easy are core goals of the project, and the vision is to make them as automatic as possible. The easiest route + would be a web-gui or phone app based configuration that does the following: +
    +
  • Detect the ISP and automatically configure appropriately
  • +
  • Provide simple insructions on any changes required to the modem configuration, if necessary
  • +
  • Longer term, look at spearheading a movement for zero-config ISP/modem setup for self hosting
  • +
  • Provide a dynamic DNS service with subdomains at homefree.host for zero-effort setup
  • +
  • If a personal domain is desired, provide a simple step-by-tep UI-based config
  • +
  • For personal domains, detect the registrar, and offer custom instructions for setting up dynamic dns
  • +
  • Longer term, look at protocols/APIs for automatically configuring registrars
  • +
+
+
+ +
+
+ What about email? Isn't that very hard to self-host? +
+
+ It's well know among the self-hosting community that email can be fragile and difficult to self-host for various reasons. The + great thing about HomeFree is that it's not all or nothing. You can progressively decide which services you want to host and + which you want to continue to use elsewhere. But there are still plans to offer the ability to host an email server if you + so wish. For an example of a simple US for setting up a custom domain for secure and reliable email, look at Proton Mail's + domain configuration UI. +
+
+ +
+
+ What is preventing me from losing all my data if the hardware fails or my house burns down? +
+
+ The system is designed to store all data in a way that is easy to bundle and back-up to another machine + in your location and off-site as well. +
+
+ +
+
+ What if I am in the process of moving or don't want to host a server at my location anymore? +
+
+ The backup data bundle is in a standard format and can easily be moved to another HomeFree server or + an online HomeFree-compatible service if you do not want to continue hosting yourself. +
+
+ +
+
+ How do I ensure that access to my services is reliable when I am using it away from home? +
+
+ This problem is still under consideration. One potential solution is to share load across multiple HomeFree + servers, either through friends and family, or a more open anonymous distributed CDN of some sort. Also, + paid-for services could be offered that provide a back-up in case your server goes down or is otherwise + out of service. +
+
+ +
+
+ How can I contribute to the project? +
+
+ We welcome contributions of all kinds! You can: +
    +
  • Submit bug reports and feature requests on our git instance
  • +
  • Improve documentation
  • +
  • Submit pull requests
  • +
  • Help others in our community forums
  • +
+ Check our contribution guidelines [TBD] to get started. +
+
+ +
+
+ What's the license and usage policy? +
+
+ HomeFree is currently built and copyrighted by Ellis Rahhal. I am currently in the process of evaluating which open source license + to release the project under. Most likely it will be a BSD-based license with limited restrictions to encourage wide adoption. +
+
+
+
+ diff --git a/site/src/includes/elements/header.html b/site/src/includes/elements/header.html index 17007a0..4b548f9 100644 --- a/site/src/includes/elements/header.html +++ b/site/src/includes/elements/header.html @@ -9,6 +9,7 @@ diff --git a/site/src/layouts/base.html b/site/src/layouts/base.html index 86ba88f..a004b5b 100644 --- a/site/src/layouts/base.html +++ b/site/src/layouts/base.html @@ -1,6 +1,8 @@ + + @@ -12,11 +14,22 @@ {{ title }} - + {% include "elements/header.html" %}
{{ content | safe }}
{% include "elements/footer.html" %} + diff --git a/site/src/quick-start.html b/site/src/quick-start.html index 6008b4f..8d701c5 100644 --- a/site/src/quick-start.html +++ b/site/src/quick-start.html @@ -9,7 +9,7 @@ layout: base.html for users and developers comfortable installing and configuring software on Linux.

-
+

1Acquire Hardware

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 @@ -19,14 +19,14 @@ layout: base.html but it surely will run on less expensive hardware.

-
+

2Get a Nix environment set up on your host machine.

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 instructions on how to install and use Nix.

-
+

3Get the code

Download the sample host config to your workstation.

@@ -34,18 +34,18 @@ layout: base.html
-
+

4Prepare the configuration

Update configuration.nix with your preferred settings. More details TBD.

-
+

5Get the IP address of the target machine

Create a bootable USB flash drive of the minimal NixOS ISO image. Simple instructions can be found here.

Boot the target machine with the USB flash drive

-
+

6Hardware Preparation

Disable secure boot in the BIOS of the target machine.

Plug the machine into an ethernet cable.

@@ -54,7 +54,7 @@ layout: base.html
-
+

7Create NixOS bootable flash drive and boot up machine

After the machine is has booted the minimal NixOS image and you are logged in, get the IP address with the following:

@@ -64,7 +64,7 @@ layout: base.html
-
+

8Install HomeFree

Run the installation script. Again, make sure the target computer is connected to an ethernet cable.

Enter the IP of the target machine as directed.

@@ -75,7 +75,7 @@ layout: base.html
-
+

9Next Steps

Now that you have a running instance, you should be able to log in with: