diff options
Diffstat (limited to 'Biz')
-rw-r--r-- | Biz/Cloud.nix | 1 | ||||
-rw-r--r-- | Biz/Cloud/Web.nix | 13 | ||||
-rw-r--r-- | Biz/Nixpert.md | 78 | ||||
-rw-r--r-- | Biz/Nixpert/Chat.md | 123 | ||||
-rw-r--r-- | Biz/Nixpert/Chat.nix | 191 |
5 files changed, 400 insertions, 6 deletions
diff --git a/Biz/Cloud.nix b/Biz/Cloud.nix index 95d0150..f45cd20 100644 --- a/Biz/Cloud.nix +++ b/Biz/Cloud.nix @@ -15,6 +15,7 @@ bild.os { ./Cloud/Web.nix ./Cloud/Znc.nix "${bild.sources.nixos-mailserver}" + ./Nixpert/Chat.nix ]; networking.hostName = "simatime"; networking.domain = "simatime.com"; diff --git a/Biz/Cloud/Web.nix b/Biz/Cloud/Web.nix index fbe4e03..442024e 100644 --- a/Biz/Cloud/Web.nix +++ b/Biz/Cloud/Web.nix @@ -69,12 +69,13 @@ in # the nginx/cgit module puts a '/' at the end of 'location', so we need to # redirect '/git' to '/git/' "/git".return = "301 https://$host/git/"; - "/" = { - root = "/var/web/simatime.com"; - extraConfig = '' - autoindex on; - ''; - }; + # disabled for nixpert test + #"/" = { + # root = "/var/web/simatime.com"; + # extraConfig = '' + # autoindex on; + # ''; + #}; # serve /~$USER paths "~ ^/~(.+?)(/.*)?$" = { alias = "/var/web/$1$2"; diff --git a/Biz/Nixpert.md b/Biz/Nixpert.md new file mode 100644 index 0000000..d97b504 --- /dev/null +++ b/Biz/Nixpert.md @@ -0,0 +1,78 @@ +--- +title: Nixpert.chat biz plan +--- + +# Problem + +Nix is hard to use, especially hard to get started with. But the benefits are +compounding for companies that do adopt it. + +The major pain point is getting help: devs often can't go to IRC because it's +hard to use or they are prevented from doing so by confidential company +information. + +# Solution + +We create a paid chat service where devs can quickly get answers to +questions. We'll have a hosted chat client that is easy to use, maybe just use +slack or something. + +# Key Metrics + +- Number of customers +- Questions answered per shift +- Hours of availability (24/7) + +# Unique Value Proposition + +## High-Level Concept + +Direct-line support for your infrastructure and build code. Like monadfix.com for Nix stuff. + +# Unfair Advantage + +- first mover + +# Channels + +- write articles on: + - common solutions + - benefits of nix + - highlight nix tool + - highlight nix function or technique + +# Customer Segments + +- crypto companies +- ml companies + +## Early Adopters + +- startups, nix companies I know? + +# Cost Structure + +- hourly wages for staff +- infrastructure costs + - chat server via prosody + - errbot for common questions? + - jitsi video chat + - hosted chat room via conversejs.org or JSXC + - chat clients (Dino, iOS: Trillian) + +# Revenue Streams + +- $500 - $1500 monthly subscription for companies +- pair-programming sessions for added $150/hr + +# Growth plan + +## Unicorn Requirements + +### Sales Penetration + +## Support requirements + +### Tech Infra + +### Customer Support diff --git a/Biz/Nixpert/Chat.md b/Biz/Nixpert/Chat.md new file mode 100644 index 0000000..2f229af --- /dev/null +++ b/Biz/Nixpert/Chat.md @@ -0,0 +1,123 @@ +--- +title: Professional Nix Chat Support +header-includes: | + <link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/9.0.0/dist/converse.min.css"> + <script src="https://cdn.conversejs.org/9.0.0/dist/converse.min.js" charset="utf-8"></script> + <style> + </style> +--- + +[Nix](https://nixos.org) is a hermetic, deterministic, and declarative build system, package manager, and operating system. It will save you time and money by making sure: + +- your development environment is the same as your production environment +- every build you do is definitive and reproducible +- all your dependencies and environment variables are accounted for +- developers never have to compile something twice - just download it from the cache + +But, you have to use it right. You can't go half-way in. + +Do you find Nix hard to use? Is the documentation confusing, the language obtuse and difficult? Have you had trouble training new devs? + +If so, you need this service. + +I'm offering dedicated Nix support for a limited number of clients. Here's how it works: + +- If you have a problem or question with Nix, NixOS, or Nixpkgs, send me a message +- I will respond within an hour during business hours +- I'll stay online with you until your problem is resolved +- If we can't solve it via chat, we'll start a video call to work through it + +To sign up, say hello in the chat box in the corner to get started, or [register][] an account. + +<!-- +# What problems does Nix solve? + +<TODO/> + +# What benefits will I get by using Nix? + +<TODO/> + +- largest package repository in the world + +--> + +# Why buy as a team? + +Get a dedicated help room just for your team. Speed up your Nix development time for everyone. Accellerate your product development by getting the infrastructure questions out of the way. + +- $3000/month +- ∞ Nix language questions +- ∞ NixOS questions +- ∞ Nixpkgs ecosystem questions +- ∞ tooling support +- 10h code review +- + architecture review +- + security review +- + best practices + +# Why buy as an individual? + +Is Nix part of your job, but you don't feel 100% comfortable? Get fast dedicated help from an expert. Perform better at your job. Get your Nix questions answered before anyone else and get back to being productive. + +- $300/month +- ∞ Nix language questions +- ∞ NixOS questions +- ∞ Nixpkgs ecosystem questions +- ∞ tooling support +- 2h code review +u- + architecture review +- + security review +- + best practices + +# About this service + +This is just a private XMPP server, you can register an account [here][register] or use your own. Join the public [nix-lobby][] room to get started. When you sign up for the dedicated, paid support you'll be added to a private chat room that you can use for future help requests. We also have 1-on-1 and encrypted messaging for any sensitive information. + +# Who runs this? + +I'm [Ben Sima](https://bsima.me) and I've been working with Nix for 5+ years. All of my personal infrastructure runs on NixOS: email, IRC, XMPP, hardware, websites including this one. I've contributed open source packages and modules to nixpkgs. In my day job, I've managed a Nix-based build system and infrastructure for 150+ developers, handling dozens of custom packages, hundreds of builds per day, and a private cache of terabytes of Nix packages. I've probably managed the largest Nix deployment in the world besides the public NixOS.org infrastructure. + +# Why make this service? + +My career mission is to make reliable software, and Nix is one of the best tools for that job. But people often complain that Nix is hard to use. So my goal with this project is to make Nix easy to use and understand. First I will help you with your day-to-day problems. Along the way I will work out better ways to explain the concepts, benefits and usage of Nix. Then I will take these lessons back to the Nix manual and tooling to make the product better. So in buying this service your money actually buys twice the value: you get direct suport of your daily problems, and you get indirect support by improving Nix over time. + +The business manta I operate by is "win and help win." By offering this service I will help your organization win by improving your infrastructure and delivering reliable software products, and the Nix community wins by having more dedicated improvements contributed upstream. + +<!-- + +# FAQ + +## Do you offer development or training? + +For special projects I offer Nix development work and training on a contract basis. Message me at [bsima@simatime.com](xmpp://bsima@simatime.com) and we'll see if your project is a good fit. If not, I can recommend other contractors that I trust will get the job done. + +## How do I manage my payment and account? + +It's all manual right now. I'll invoice you for payment at the beginning of every month. If you want to cancel, just message me, no hard feelings. Or just don't pay your invoice I guess. + +If you want your XMPP account deleted, you can usually do that from an XMPP client, or message me directly and I'll do it from the admin console. + +## Do you log our chats? + +Yeah I save the logs for 30 days. If you need them deleted for some reason, message me an I'll delete any logs. If you have sensitive data, use OMEMO or PGP encryption. + +--> + +[register]: https://simatime.com/chat +[nix-lobby]: TODO + +<script> + // https://conversejs.org/demo/anonymous.html + converse.initialize({ + allow_logout: false, + authentication: "anonymous", + auto_login: true, + auto_join_rooms: [ "nix-lobby@conference.simatime.com" ], + notify_all_room_messages: [ "nix-lobby@conference.simatime.com" ], + jid: "anon.simatime.com", + keepalive: true, + hide_muc_server: true, + bosh_service_url: "https://anon.simatime.com/http-bind" + }); +</script> diff --git a/Biz/Nixpert/Chat.nix b/Biz/Nixpert/Chat.nix new file mode 100644 index 0000000..2eae9d6 --- /dev/null +++ b/Biz/Nixpert/Chat.nix @@ -0,0 +1,191 @@ +{ config, pkgs, ... }: +# +# xmpp chat service +# +let + salespage = pkgs.runCommand "salespage" {} '' + mkdir -p $out + ${pkgs.pandoc}/bin/pandoc \ + --standalone \ + -f commonmark_x \ + -t html ${./Chat.md} \ + > $out/index.html + ''; + ports = import ../Cloud/Ports.nix; + ssl = { + cert = "/var/lib/acme/simatime.com/fullchain.pem"; + key = "/var/lib/acme/simatime.com/key.pem"; + }; +in { + networking.firewall.allowedTCPPorts = [ + # https://prosody.im/doc/ports + 5000 # file transfer + 5222 # client connections + 5269 # server-to-server + 5280 # http + 5281 # https + 5347 # external components + 5582 # telnet console + ]; + + services.prosody = { + enable = true; + package = pkgs.prosody.override { + withCommunityModules = [ + "conversejs" + ]; + }; + # when i learn how to use security.acme better, and use separate certs, then i + # can fix this group + group = "nginx"; + admins = [ "bsima@simatime.com" ]; + allowRegistration = true; + inherit ssl; + uploadHttp = { + domain = "upload.simatime.com"; + uploadExpireAfter = toString (60*60*24*30); # 30 days, as seconds + }; + modules = { + announce = true; + bosh = true; + groups = true; + motd = true; + register = true; + server_contact_info = true; + vcard = true; + watchregistrations = true; + websocket = true; + welcome = true; + }; + extraConfig = '' + conversejs_options = { + allow_registration = true; + --- authentication = "internal_plain"; + bosh_service_url = "https://simatime.com/http-bind"; + debug = true; + loglevel = "debug"; + -- default_domain = "simatime.com"; + -- domain_placeholder = "simatime.com"; + -- jid = "simatime.com"; + -- keepalive = true; + -- registration_domain = "simatime.com"; + websocket_url = "wss://simatime.com/xmpp-websocket"; + } + + cross_domain_websocket = { "https://simatime.com", "https://anon.simatime.com" } + cross_domain_bosh = false; -- handle this with nginx + consider_bosh_secure = true; + + -- this is a virtualhost that allows anonymous authentication. use this + -- for the sales lobby. the nix module doesn't support 'authentication' + -- so i have to do this here. + VirtualHost "anon.simatime.com" + authentication = "anonymous" + ssl = { + cafile = "/etc/ssl/certs/ca-bundle.crt"; + key = "/var/lib/acme/simatime.com/key.pem"; + certificate = "/var/lib/acme/simatime.com/fullchain.pem"; + }; + ''; + muc = [ + { + domain = "conference.simatime.com"; + maxHistoryMessages = 10000; + name = "Chat Rooms"; + restrictRoomCreation = "admin"; + roomDefaultHistoryLength = 20; + roomDefaultMembersOnly = true; + roomDefaultModerated = true; + roomDefaultPublic = false; + } + ]; + virtualHosts = { + "simatime.com" = { + domain = "simatime.com"; + enabled = true; + inherit ssl; + }; + }; + }; + + services.nginx.virtualHosts."simatime.com".locations."/http-bind" = { + proxyPass = "https://simatime.com:5281/http-bind"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + services.nginx.virtualHosts."simatime.com".locations."/" = { + root = "${salespage}"; + extraConfig = '' + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + services.nginx.virtualHosts."simatime.com".locations."/xmpp-websocket" = { + proxyPass = "https://simatime.com:5281/xmpp-websocket"; + extraConfig = '' + proxy_http_version 1.1; + proxy_buffering off; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 86400; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + services.nginx.virtualHosts."simatime.com".locations."/chat" = { + proxyPass = "https://simatime.com:5281/conversejs"; + extraConfig = '' + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + services.nginx.virtualHosts."anon.simatime.com" = { + useACMEHost = "simatime.com"; + forceSSL = true; + locations = { + "/http-bind" = { + proxyPass = "https://anon.simatime.com:5281/http-bind"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + if ($request_method ~* "(GET|POST)") { + add_header Access-Control-Allow-Origin "*"; + } + if ($request_method = OPTIONS) { + add_header Access-Control-Allow-Origin "*"; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD"; + add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept"; + return 200; + } + ''; + }; + }; + }; + + users.users.nginx.extraGroups = [ "prosody" ]; + + security.acme.certs.${config.networking.domain}.extraDomainNames = [ + "upload.simatime.com" "conference.simatime.com" "simatime.com" "anon.simatime.com" + ]; + + #security.acme.certs.prosody = { + # domain = "${domain}"; + # group = "prosody"; + # dnsProvider = "rfc2136"; + # #credentialsFile = config.secrets.files.dns_creds.path; + # postRun = "systemctl restart prosody"; + # extraDomainNames = [ + # domain + # "upload.${domain}" + # ]; + #}; +} |