From 32f53350a3a3d701e9a1474e670a8454342adc40 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Mon, 19 Oct 2020 16:57:32 -0400 Subject: Devalloc informational website This includes deployment and implementation. As part of sprint-49, here are the startup progress questions: - Are you on track? - Yes? I'm making progress toward a proper launch. - Are you launched? - No - How many weeks to launch? - I would say 4 but it's probably more like 8 - How many (prospective) users have you talked to in the last week? - 2, Kyle and his manager, see below - What have you learned from them? - Kyle thought the metrics were interesting. - His manager thought the metrics were kinda useful but didn't think they really helped people ship higher quality code faster. So that's the rub: I have to show how this can make devs ship higher quality code faster; or, develop a set of features that improve those things. - Kyle pointed out that the clustering feature of devalloc will find optimal pairings *and* identify team silos that could be improved, so that's important to remember and might be a good angle in the future. - On a scale of 1-10, what is your morale? - 6 maybe - What most improved your primary metric? - Well I was able to deploy something within in the week, whereas before I had zero deploys per week. So that's an improvement. - What is your biggest obstacle? - Finding customers to talk to. - Also the thing isn't really built yet, I just have a python script. I need to build the real SaaS product - What are your top 1-3 goals for next week? - Find a single customer I can work with on an ongoing basis - I should ask around my network to see if I have any second-order connections that would be willing to work with me (Asher, Chad, previous bosses, etc) - Build out the front-end of the website (it's very simple, would just need a basic miso module and deployment) - Figure out how to connect/auth to the Github API so I can start building the SaaS version of the product Some user feedback from my friend Kyle. This comes from his engineering manager: > "Looks neat. If it were priced low enough I could see using it to run reports > as part of an overall package. A lot of those metrics don't matter too much to > me as a manager though A lot of these code quality tools are handy info but I > don't feel like they make people ship code any faster or any higher quality > Things like CodeClimate work well for Jrs though to avoid obvious static type > mistakes" Kyle provided some additional comments: > he might have been an unusual case. Jared's not big into metrics, Pivotal > Tracker point estimates, or things like that... He's far more into qualitative > feedback, like retrospectives and 1:1s > > I think it's definitely neat data! I certainly like the collaboration analysis > > It's interesting, we recently had a pair where two devs didn't work well > together, that could be represented here. Though, we didn't want to avoid > having them work together, we wanted them to find a work style that worked for > both of them And that's a good point: devalloc will find optimal pairings *and* points where you could improve team cohesiveness. --- Biz/App.hs | 18 +++++++++-- Biz/Bild/ShellHook.sh | 8 ++--- Biz/Cloud.nix | 2 ++ Biz/Cloud/Chat.nix | 10 +++--- Biz/Cloud/Web.nix | 82 ++++++++++++++++++++++++++++++++++++----------- Biz/Dev.nix | 6 ++++ Biz/Dev/Configuration.nix | 4 ++- Biz/Look.hs | 75 ++++++++++++++++++++++++++++++++++++------- 8 files changed, 162 insertions(+), 43 deletions(-) (limited to 'Biz') diff --git a/Biz/App.hs b/Biz/App.hs index d16bba9..5759499 100644 --- a/Biz/App.hs +++ b/Biz/App.hs @@ -4,7 +4,12 @@ {-# LANGUAGE NoImplicitPrelude #-} -- | General utils for apps -module Biz.App (CSS (..), Manifest (..)) where +module Biz.App + ( CSS (..), + Manifest (..), + HtmlApp (..), + ) +where import Alpha import Data.Aeson (ToJSON) @@ -14,7 +19,7 @@ import Network.HTTP.Media ( (//), (/:), ) -import Servant +import Servant.API (Accept (..), MimeRender (..)) newtype CSS = CSS { unCSS :: Text @@ -38,3 +43,12 @@ data Manifest = Manifest deriving (Show, Eq, Generic) instance ToJSON Manifest + +-- | A wrapper for an HTML page. You need to provide an orphan +-- 'Lucid.Base.ToHtml' instance in the Host module of your app. +-- +-- Ideally this would be captured in a Biz.App type, with overrides for head +-- elements, and we would wouldn't have to make the same basic orphan instance +-- for each app. +newtype HtmlApp a = HtmlApp a + deriving (Show, Eq) diff --git a/Biz/Bild/ShellHook.sh b/Biz/Bild/ShellHook.sh index 4e78acc..b79f1a6 100644 --- a/Biz/Bild/ShellHook.sh +++ b/Biz/Bild/ShellHook.sh @@ -56,9 +56,11 @@ function pie() { runghc Biz.Pie $@ } -# TODO: convert to haskell +# TODO: convert to haskell, see: +# - https://github.com/awakesecurity/nix-deploy/blob/master/src/Main.hs +# - http://www.haskellforall.com/2018/08/nixos-in-production.html function push() { - prefix=$(echo $PWD | sed -e "s|^$BIZ_ROOT/*||g" -e "s|/|.|g") + prefix=$(echo $PWD | sed -e "s|^$BIZ_ROOT/*||g") if [[ "$prefix" == "" ]] then target="$1" @@ -76,7 +78,6 @@ function push() { # TODO: convert to haskell function ship() { - set -ex $BIZ_ROOT/Biz/Lint.py stuff=(${1}) if [[ ${#stuff[@]} -eq 0 ]] @@ -100,7 +101,6 @@ function ship() { # Poor man's ci function ci() { - set -e lint stuff=( Biz/Pie.hs diff --git a/Biz/Cloud.nix b/Biz/Cloud.nix index edf8a85..c70c0ad 100644 --- a/Biz/Cloud.nix +++ b/Biz/Cloud.nix @@ -24,4 +24,6 @@ bild.os { ]; networking.hostName = "simatime"; networking.domain = "simatime.com"; + # the datacenter for this VM is in SF + time.timeZone = "America/Los_Angeles"; } diff --git a/Biz/Cloud/Chat.nix b/Biz/Cloud/Chat.nix index bc97973..6f8ac3a 100644 --- a/Biz/Cloud/Chat.nix +++ b/Biz/Cloud/Chat.nix @@ -2,6 +2,9 @@ # # a homeserver for matrix.org. # +# this uses the config.networking.domain as the ACME host. be sure to add the +# fqdn and element subdomains to security.acme.certs..extraDomainNames +# # - nixos manual: https://nixos.org/nixos/manual/index.html#module-services-matrix # # to create new users: @@ -72,8 +75,8 @@ in { }; # reverse proxy for matrix client-server and server-server communication "${fqdn}" = { - enableACME = true; forceSSL = true; + useACMEHost = config.networking.domain; locations."/".extraConfig = '' return 404; ''; @@ -90,11 +93,8 @@ in { # https://github.com/vector-im/element-web#important-security-note # services.nginx.virtualHosts."${element}" = { - enableACME = true; + useACMEHost = config.networking.domain; forceSSL = true; - serverAliases = [ - "chat.${config.networking.domain}" - ]; root = pkgs.element-web; }; } diff --git a/Biz/Cloud/Web.nix b/Biz/Cloud/Web.nix index acd5c2f..56eeb2d 100644 --- a/Biz/Cloud/Web.nix +++ b/Biz/Cloud/Web.nix @@ -1,6 +1,7 @@ -{ ... }: +{ config, ... }: let + rootDomain = config.networking.domain; bensIp = "24.140.84.23"; in { @@ -11,31 +12,74 @@ in recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; + + group = "users"; + virtualHosts = { - "bsima.me".root = "/home/ben/public_html/"; - "www.bsima.me".root = "/home/ben/public_html/"; - "simatime.com".locations."/".root = "/srv/www/"; - "firefoxsync.simatime.com".locations."/".proxyPass = "http://localhost:5001"; - "hero.simatime.com".locations."/".proxyPass = "http://${bensIp}:3001"; - "tv.simatime.com".locations."/".proxyPass = "http://${bensIp}:8096"; # emby runs on port 8096 - "deluge.simatime.com".locations."/".proxyPass = "http://${bensIp}:8112"; - - "notebook.simatime.com".locations = { - "/" = { - proxyPass = "http://${bensIp}:3099"; - proxyWebsockets = true; - extraConfig = '' - proxy_buffering off; - proxy_read_timeout 86400; + ${rootDomain} = { + locations."/".root = "/srv/www/"; + # serve /~$USER paths + locations."~ ^/~(.+?)(/.*)?$" = { + alias = "/home/$1/public_html$2"; + index = "index.html index.htm"; + extraConfig = '' + autoindex on; ''; }; - "/(api/kernels/[^/]+/channels|terminals/websocket)/" = { - proxyPass = "http://${bensIp}:3099"; - proxyWebsockets = true; + forceSSL = true; + enableACME = true; + }; + + "bsima.me" = { + locations."/" = { + root = "/home/ben/public_html/"; + index = "index.html index.htm"; + extraConfig = '' + autoindex on; + ''; }; + serverAliases = [ "www.bsima.me" ]; + forceSSL = true; + useACMEHost = rootDomain; + }; + + "tv.${rootDomain}" = { + locations."/".proxyPass = "http://${bensIp}:8096"; # emby runs on port 8096 + forceSSL = true; + useACMEHost = rootDomain; }; + + "devalloc.io" = { + locations."/".proxyPass = "http://${bensIp}:8095"; + forceSSL = true; + useACMEHost = rootDomain; + }; + + # Jupyter is currently disabled on Biz.Dev + #"notebook.simatime.com".locations = { + # "/" = { + # proxyPass = "http://${bensIp}:3099"; + # proxyWebsockets = true; + # extraConfig = '' + # proxy_buffering off; + # proxy_read_timeout 86400; + # ''; + # }; + # "/(api/kernels/[^/]+/channels|terminals/websocket)/" = { + # proxyPass = "http://${bensIp}:3099"; + # proxyWebsockets = true; + # }; + #}; }; }; }; + + # This must contain all of the other domains we host + security.acme.certs.${rootDomain}.extraDomainNames = [ + "bsima.me" "www.bsima.me" "tv.${rootDomain}" + "devalloc.io" + "matrix.${rootDomain}" + "chat.${rootDomain}" + ];# } diff --git a/Biz/Dev.nix b/Biz/Dev.nix index a08a8f7..cdb3036 100644 --- a/Biz/Dev.nix +++ b/Biz/Dev.nix @@ -9,8 +9,14 @@ bild.os { ./Users.nix ./Dev/Configuration.nix ./Dev/Hardware.nix + ../Devalloc/Host.nix ]; networking.hostName = "lithium"; networking.domain = "dev.simatime.com"; + services.devalloc-host = { + enable = true; + port = 8095; + package = bild.ghc ../Devalloc/Host.hs; + }; } diff --git a/Biz/Dev/Configuration.nix b/Biz/Dev/Configuration.nix index 7fa0e37..24293cf 100644 --- a/Biz/Dev/Configuration.nix +++ b/Biz/Dev/Configuration.nix @@ -6,6 +6,8 @@ let torrents = { from = 3000; to = 3099; }; delugeWeb = 8112; jellyfin = 8096; + httpdev = { from = 8000; to = 8099; }; + devallocHost = 8095; }; in { networking = { @@ -17,7 +19,6 @@ in { firewall = { allowedTCPPorts = [ 22 8000 8443 443 # standard ports - 8080 8081 8082 # mostly for urbit 500 10000 # no idea ports.jellyfin ports.delugeWeb @@ -25,6 +26,7 @@ in { ]; allowedTCPPortRanges = [ ports.torrents + ports.httpdev ]; allowedUDPPorts = [ ports.murmur ]; allowedUDPPortRanges = [ diff --git a/Biz/Look.hs b/Biz/Look.hs index 4315994..51224a9 100644 --- a/Biz/Look.hs +++ b/Biz/Look.hs @@ -5,36 +5,87 @@ -- -- https://leerob.io/blog/how-stripe-designs-beautiful-websites module Biz.Look - ( fontstack, + ( -- | Base stylesheets + fuckingStyle, + -- | Clay.Media extensions + prefersLight, + prefersDark, + noColorPreference, + -- | Font + fontStack, + -- | Elements hoverButton, ) where +import Alpha import Clay +import qualified Clay.Stylesheet as Clay -fontstack :: Css -fontstack = do +fontStack :: Css +fontStack = do -- i like adobe source pro, maybe use that instead of camphor fontFamily ["Camphor", "Open Sans", "Segoe UI"] [sansSerif] textRendering optimizeLegibility --- TODO: fontSmoothing is not yet implemented in clay --- -webkit-font-smoothing: antialiased --- -moz-osx-font-smoothing: grayscale - hoverButton :: Css -hoverButton = do +hoverButton = button # hover ? do color "#7795f8" - transform $ translateY $ px (-1) + transform <| translateY <| px (-1) boxShadow - [ bsColor (rgba 50 50 93 0.1) $ - shadow + [ bsColor (rgba 50 50 93 0.1) + <| shadow (px 7) (px 14), bsColor (rgba 0 0 0 0.08) - $ shadow + <| shadow (px 3) (px 6) ] + +prefersDark :: Clay.Feature +prefersDark = + Clay.Feature "prefers-color-scheme" (Just (Clay.value ("dark" :: Text))) + +prefersLight :: Clay.Feature +prefersLight = + Clay.Feature "prefers-color-scheme" (Just (Clay.value ("light" :: Text))) + +noColorPreference :: Clay.Feature +noColorPreference = + Clay.Feature + "prefers-color-scheme" + (Just (Clay.value ("no-preference" :: Text))) + +-- | The stylesheet from ported to +-- Clay. +fuckingStyle :: Css +fuckingStyle = do + "body" ? do + maxWidth (px 650) + margin (px 40) auto (px 40) auto + padding 0 (px 10) 0 (px 10) + color "#444" + fontSize (px 18) + lineHeight (em 1.5) + fontFamily + [ "Segoe UI", + "Roboto", + "Helvetica Neue", + "Arial", + "Noto Sans", + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji" + ] + [sansSerif] + "h1" <> "h2" <> "h3" ? lineHeight (em 1.2) + query Clay.all [prefersDark] <| do + "body" ? do + color white + background ("#444" :: Color) + "a:link" ? color ("#5bf" :: Color) + "a:visited" ? color ("#ccf" :: Color) -- cgit v1.2.3