@@ -1,41 +1,40 @@
3[](http://www.haskell.org)
3[](http://www.haskell.org)
4−[](https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29)
4+[](https://github.com/obsidiansystems/obelisk/blob/master/LICENSE)
6−Obelisk is an opinionated, batteries-included framework for building production-ready web and mobile applications in [Haskell](https://www.haskell.org/). It's goal is to represent a cohesive, highly-curated set of choices that [Obsidian Systems](https://obsidian.systems/) has made for building these types of applications in a way that is extremely fast but does not compromise on production readiness.
6+<p align="center"><img src="docs/obelisk-logo-640.png" width="50%" alt="Obelisk Logo"></p>
8−- [Overview](#installing-obelisk)
8+Functional reactive web and mobile applications, with batteries included. Obelisk's goal is to represent a cohesive, highly-curated set of choices that [Obsidian Systems](https://obsidian.systems/) has made for building these types of applications in a way that is extremely fast but does not compromise on production readiness.
9− - [Why would I use it?](#why-would-i-use-it)
9+
10+- [Overview](#overview)
10 - [Who should consider using it?](#who-should-consider-using-it)
11 - [Who should consider using it?](#who-should-consider-using-it)
11- [Installing Obelisk](#installing-obelisk)
12- [Installing Obelisk](#installing-obelisk)
12- [Developing an Obelisk project](#developing-an-obelisk-project)
13- [Developing an Obelisk project](#developing-an-obelisk-project)
13− - [Adding Packages](#adding-packages)
14− - [Adding Package Overrides](#adding-package-overrides)
15− - [Running over HTTPS](#running-over-https)
16 - [IDE Support](#ide-support)
14 - [IDE Support](#ide-support)
17− - [Terminal-based feedback](#terminal-based-feedback)
18− - [Experimental `ghcide` support](#experimental-ghcide-support)
19- [Deploying](#deploying)
15- [Deploying](#deploying)
20− - [Locally](#locally)
21 - [Default EC2 Deployment](#default-ec2-deployment)
16 - [Default EC2 Deployment](#default-ec2-deployment)
22 - [Custom Non-EC2 Deployment](#custom-non-ec2-deployment)
17 - [Custom Non-EC2 Deployment](#custom-non-ec2-deployment)
23 - [VirtualBox Deployment](#virtualbox-deployment)
18 - [VirtualBox Deployment](#virtualbox-deployment)
19+ - [Locally](#locally)
24 - [From macOS](#from-macos)
20 - [From macOS](#from-macos)
25 - [Deploying an updated version](#deploying-an-updated-version)
21 - [Deploying an updated version](#deploying-an-updated-version)
26- [Mobile](#mobile)
22- [Mobile](#mobile)
27 - [iOS](#ios)
23 - [iOS](#ios)
28 - [Android](#android)
24 - [Android](#android)
25+- [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
26+- [Contributing](#contributing)
30## Overview
28## Overview
32−### Why would I use it?
30+Obelisk allows you to build high-quality web and mobile applications very quickly using [Reflex](https://reflex-frp.org/). In minutes you can go from an empty directory to an interactive application that works on web, iOS, and Android, all sharing the same Haskell codebase! Obelisk's development environment also enables extremely rapid development and feedback. You can take advantage of Haskell's type system across the frontend and backend boundary. This means changes to your backend that would break your frontend are immediately detected during development and vice versa. Obelisk uses Haskell's compiler to give you a complete "TODO list" of what needs to be updated.
34−Obelisk allows you to build high-quality, high-performance web and mobile applications very quickly using [Reflex](https://reflex-frp.org/). In minutes you can go from an empty directory to a working prototype of an interactive application that works on web, iOS, and Android, all sharing the same Haskell codebase! Obelisk's development environment also enables extremely rapid prototyping and feedback. You can take advantage of Haskell's type system across the frontend and backend boundary. This means changes to your backend that would break your frontend are immediately detected during development and Haskell's compiler is able to give you a complete "TODO" list of what needs to be updated.
32+Obelisk is targeted primarily at Haskell developers who want to build high-quality web and/or mobile applications in Haskell, without the distractions of manually choosing and integrating technology for every piece of the system.
36### Who should consider using it?
34### Who should consider using it?
38−Obelisk is targeted primarily at Haskell developers who want to build high-quality web and/or mobile applications in Haskell without the distractions of manually choosing and integrating technology for every piece of the system.
36+Obelisk assumes basic knowledge of [Haskell](https://www.haskell.org/) and [Reflex/Reflex-DOM](https://reflex-frp.org/), web technologies like [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) and [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS), and a terminal shell like [Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)). Knowledge of [Nix](https://nixos.org/) helps but is not strictly necessary.
40## Installing Obelisk
39## Installing Obelisk
@@ -43,67 +42,34 @@ Obelisk is targeted primarily at Haskell developers who want to build high-quali
43 If you already have Nix installed, make sure you have version 2.0 or higher. To check your current version, run `nix-env --version`.
42 If you already have Nix installed, make sure you have version 2.0 or higher. To check your current version, run `nix-env --version`.
441. Set up nix caches
431. Set up nix caches
45 1. If you are running NixOS, add this to `/etc/nixos/configuration.nix`:
44 1. If you are running NixOS, add this to `/etc/nixos/configuration.nix`:
47 nix.binaryCaches = [ "https://nixcache.reflex-frp.org" ];
46 nix.binaryCaches = [ "https://nixcache.reflex-frp.org" ];
48 nix.binaryCachePublicKeys = [ "ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=" ];
47 nix.binaryCachePublicKeys = [ "ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=" ];
50 and rebuild your NixOS configuration (e.g. `sudo nixos-rebuild switch`).
49 and rebuild your NixOS configuration (e.g. `sudo nixos-rebuild switch`).
51− 1. If you are using another operating system or linux distribution, ensure that these lines are present in your Nix configuration file (`/etc/nix/nix.conf` on most systems; [see full list](https://nixos.org/nix/manual/#sec-conf-file)):
50+ 1. If you are using another operating system or Linux distribution, ensure that these lines are present in your Nix configuration file (`/etc/nix/nix.conf` on most systems; [see full list](https://nixos.org/nix/manual/#sec-conf-file)):
53− binary-caches = https://cache.nixos.org https://nixcache.reflex-frp.org
52+ binary-caches = https://cache.nixos.org https://nixcache.reflex-frp.org
54− binary-cache-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
53+ binary-cache-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
55− binary-caches-parallel-connections = 40
54+ binary-caches-parallel-connections = 40
57− * other Linux: enable sandboxing (see these [issue172](https://github.com/obsidiansystems/obelisk/issues/172#issuecomment-411507818) or [issue6](https://github.com/obsidiansystems/obelisk/issues/6) if you run into build problems)
56+ * If you're on a Linux distribution other than NixOS, enable sandboxing (see these [issue 172](https://github.com/obsidiansystems/obelisk/issues/172#issuecomment-411507818) or [issue 6](https://github.com/obsidiansystems/obelisk/issues/6) if you run into build problems) by adding the following:
59 sandbox = true
58 sandbox = true
61− * MacOS: disable sandboxing (there are still some impure dependencies for now)
60+ * If you're on MacOS, disable sandboxing (there are still some impure dependencies for now) by adding the following:
63 sandbox = false
62 sandbox = false
65 then restart the nix daemon
64 then restart the nix daemon
67 sudo launchctl stop org.nixos.nix-daemon
66 sudo launchctl stop org.nixos.nix-daemon
68 sudo launchctl start org.nixos.nix-daemon
67 sudo launchctl start org.nixos.nix-daemon
70−1. Install obelisk: `nix-env -f https://github.com/obsidiansystems/obelisk/archive/master.tar.gz -iA command`
71+ nix-env -f https://github.com/obsidiansystems/obelisk/archive/master.tar.gz -iA command
72−### Contributing to Obelisk
74−When developing on obelisk itself you may launch `ghcid` for the corresponding project as follows. For example to launch ghcid for `lib/backend` project:
77−nix-shell -A obeliskEnvs.obelisk-backend --run "cd lib/backend && ghcid -c 'cabal new-repl'"
80−Or to launch ghcid for `lib/command` project:
83−nix-shell -A obeliskEnvs.obelisk-command --run "cd lib/command && ghcid -c 'cabal new-repl'"
86−To re-install `ob` from source do
88−nix-env -f /path/to/obelisk -iA command
91−Note that `ob` will defer to the version found in your project's `.obelisk/impl` directory. To update that version specifically:
94−ob thunk unpack ./.obelisk/impl
99−If you want to commit your changes, first push them to your fork of obelisk and then
102−cd /your/project/root
103−ob thunk pack .obelisk/impl
104−git add .obelisk/impl
105−git commit -m "Bump obelisk"
108### Accessing private repositories
74### Accessing private repositories
@@ -133,119 +99,12 @@ Firefox will not be able to properly run the development website due to [issue 4
134Every time you change the Haskell source files in frontend, common or backend, `ob run` will automatically recompile the modified files and reload the server. Furthermore, it will display on screen compilation errors and warnings if any.
100Every time you change the Haskell source files in frontend, common or backend, `ob run` will automatically recompile the modified files and reload the server. Furthermore, it will display on screen compilation errors and warnings if any.
138−In order to add package dependencies, declare them under the build-depends field in the appropriate cabal files (backend, common, and frontend each have their own). The corresponding Nix packages will automatically be selected when building.
140−### Adding package overrides
142−To add a version override to any Haskell package, or to add a Haskell package that doesn't exist in the nixpkgs used by Obelisk, use the `overrides` attribute in your project's `default.nix`. For example, to use a specific version of the `aeson` package fetched from GitHub and a specific version of the `waargonaut` package fetched from Hackage, your `default.nix` will look like:
146−project ./. ({ pkgs, ... }: {
148− overrides = self: super: let
149− aesonSrc = pkgs.fetchFromGitHub {
150− owner = "obsidiansystems";
151− repo = "aeson-gadt-th";
152− rev = "ed573c2cccf54d72aa6279026752a3fecf9c1383";
153− sha256 = "08q6rnz7w9pn76jkrafig6f50yd0f77z48rk2z5iyyl2jbhcbhx3";
157− aeson = self.callCabal2nix "aeson" aesonSrc {};
158− waargonaut = self.callHackageDirect {
161− sha256 = "1zv28np3k3hg378vqm89v802xr0g8cwk7gy3mr77xrzy5jbgpa39";
167−For further information see [the Haskell section](https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure) of nixpkgs Contributors Guide.
169−### Adding extra local packages
171−If the standard packages (`frontend`, `backend`, and `common`) are not
172−enough, to add more local Haskell packages, define them with the
173−`packages` parameter. The sources of these packages will be
174−automatically reloaded by `ob run`.
178−project ./. ({ pkgs, ... }: {
181− another = ./another;
186−### Running over HTTPS
188−To run your app locally over HTTPS, update the protocol in `config/common/route` to `https`, and then use `ob run` as normal.
190−Since Obelisk generates a self-signed certificate for running HTTPS, the browser will issue a warning about using an invalid certificate. On Chrome, you can go to `chrome://flags/#allow-insecure-localhost` to enable invalid certificates for localhost.
192### IDE Support
102### IDE Support
194−#### Terminal-based feedback
196Obelisk officially supports terminal-based feedback (akin to [`ghcid`](https://github.com/ndmitchell/ghcid)) in `ob run` and `ob watch`.
104Obelisk officially supports terminal-based feedback (akin to [`ghcid`](https://github.com/ndmitchell/ghcid)) in `ob run` and `ob watch`.
198−#### **Experimental** `ghcide` support
200−> **NOTE:** `ghcide` support is strictly **experimental** and **not officially supported**. There is no guarantee that it will work for you or that this support will be maintained over time.
202−To try out the **experimental** [`ghcide`](https://github.com/digital-asset/ghcide) support:
204− * Install a `ghcide` plugin for your editor.
205− * Add `__withGhcide = true;` to your Obelisk project's `default.nix` (inside the call to `project`). With this setting, `ob shell` will provide `ghcide` as well.
206− * Add `hie-bios.sh` to the root of your project:
208− cat > hie-bios.sh <<'EOF'
210− source "$HOME/.bash_profile"; # NOTE: Some editors need help finding 'ob' and this assumes that `ob` is made available on your `$PATH` in `.bash_profile`
211− ob internal export-ghci-configuration > "$HIE_BIOS_OUTPUT"
213− chmod +x hie-bios.sh
215− * **Note:** In some projects you need to use `ob internal export-ghci-configuration --use-relative-paths` in this script instead. This is known to happen when your project contains symlinks to other packages.
216− * Add `hie.yaml` to the root of your project:
218− echo 'cradle: { bios: { program: hie-bios.sh } }' > hie.yaml
220− * Test the configuration with `ob shell ghcide`. Assuming your project compiles and works with `ghcide` otherwise, this should succeed.
221− * Start your editor in a way that it can access the appropriate `ghcide`:
222− * This can sometimes be achieved with `ob shell 'start my editor'`.
223− * If you can't easily start your editor in a way that it inherits your shell, you may need to customize how your `ghcide` plugin finds `ghcide` or create a custom `ghcide` replacement script that you install globally. For example, for Visual Studio Code on macOS adding a script called `ghcide` to your `PATH` like the one below will cause `ghcide` from each project's `ob shell` to be used:
226− source "$HOME/.bash_profile" # NOTE: This assumes that `ob` is made available on your `$PATH` in `.bash_profile`
227− ob shell "ghcide $@"
230## Deploying
106## Deploying
237−nix-build -A exe --no-out-link
240−Copy the result to a new directory, add configuration, and run!
244−ln -s $(nix-build -A exe --no-out-link)/* test-app/
245−cp -r config test-app
246−(cd test-app && ./backend)
249### Default EC2 Deployment
108### Default EC2 Deployment
251In this section we will demonstrate how to deploy your Obelisk app to an Amazon EC2 instance. Obelisk deployments are configured for EC2 by default (see [Custom Non-EC2 Deployment](#custom-non-ec2-deployment)).
110In this section we will demonstrate how to deploy your Obelisk app to an Amazon EC2 instance. Obelisk deployments are configured for EC2 by default (see [Custom Non-EC2 Deployment](#custom-non-ec2-deployment)).
@@ -255,14 +114,14 @@ First create a new EC2 instance:
2551. Launch a NixOS 19.09 EC2 instance (we recommend [this AMI](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#LaunchInstanceWizard:ami=ami-00a8eeaf232a74f84))
1141. Launch a NixOS 19.09 EC2 instance (we recommend [this AMI](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#LaunchInstanceWizard:ami=ami-00a8eeaf232a74f84))
2561. In the instance configuration wizard ensure that your instance has at least 1GB RAM and 10GB disk space.
1151. In the instance configuration wizard ensure that your instance has at least 1GB RAM and 10GB disk space.
2571. When prompted save your AWS private key (`~/myaws.pem`) somewhere safe. We'll need it later during deployment.
1161. When prompted save your AWS private key (`~/myaws.pem`) somewhere safe. We'll need it later during deployment.
258−1. Go to "Security Groups", select your instance's security group and under "Inbound" tab add a new rule for HTTP port 80 and 443.
117+1. Go to "Security Groups", select your instance's security group and under "Inbound" tab add a new rule for HTTP port 80 and HTTPS port 443.
260At this stage your instance should be booting and become accessible shortly. Note down the hostname of your EC2 instance.
119At this stage your instance should be booting and become accessible shortly. Note down the hostname of your EC2 instance.
262Now go to your Obelisk project directory (`~/code/myapp`), and initialize a deployment config (`~/code/myapp-deploy`):
121Now go to your Obelisk project directory (`~/code/myapp`), and initialize a deployment config (`~/code/myapp-deploy`):
263Your project directory must be "thunkable", i.e. something on which `ob thunk pack` can be called. Usually it will be a git repository whose current revision has been pushed upstream.
122Your project directory must be "thunkable", i.e. something on which `ob thunk pack` can be called. Usually it will be a git repository whose current revision has been pushed upstream.
266cd ~/code/myapp
125cd ~/code/myapp
267SERVER=ec2-35-183-22-197.ca-central-1.compute.amazonaws.com
126SERVER=ec2-35-183-22-197.ca-central-1.compute.amazonaws.com
268ROUTE=https://myapp.com # Publicly accessible route to your app
127ROUTE=https://myapp.com # Publicly accessible route to your app
@@ -281,7 +140,7 @@ This step will also require that you manually verify the authenticity of the hos
282Next, go to the deployment directory that you just initialized and deploy!
141Next, go to the deployment directory that you just initialized and deploy!
285cd ~/code/myapp-deploy
144cd ~/code/myapp-deploy
286ob deploy push
145ob deploy push
@@ -310,6 +169,25 @@ Here's a `module.nix` that is configured for deployment to a VirtualBox VM (runn
311The `{...}:` and following is the [NixOS module](https://nixos.org/nixos/manual/index.html#sec-writing-modules) definition.
170The `{...}:` and following is the [NixOS module](https://nixos.org/nixos/manual/index.html#sec-writing-modules) definition.
174+If you want deploy your application locally or test a production-oriented build you can build and deploy the app as described below.
176+Build the application:
179+nix-build -A exe --no-out-link
182+Copy the result to a new directory, add configuration, and run!
186+ln -s $(nix-build -A exe --no-out-link)/* test-app/
187+cp -r config test-app
188+(cd test-app && ./backend)
313### From macOS
191### From macOS
315Deploying from macOS requires some extra setup:
193Deploying from macOS requires some extra setup:
@@ -343,7 +221,7 @@ Your account must also belong to an Apple Developer Team, if you want to access
3431. Click accept to authorize on both the computer and the iPhone.
2211. Click accept to authorize on both the computer and the iPhone.
345##### Xcode
223##### Xcode
346−Install Xcode 8.2 (contains iOS SDK 10.2) and open it so that it runs its post install tool setup.
224+Install Xcode 11.2 (contains iOS SDK 13.2) and open it so that it runs its post install tool setup.
348These versions will work out of the box but iOS SDKs prior to 11.3 should also work. You can choose another installed version in `default.nix`
226These versions will work out of the box but iOS SDKs prior to 11.3 should also work. You can choose another installed version in `default.nix`
@@ -436,3 +314,13 @@ This should copy over and install the application on your device (if you see a
436##### Build a release version
314##### Build a release version
438After having configured signing for your app, you may proceed to build a release version of the app. This is no different to how you build the non-release version, so consult the section [Android](#android) further above for exact instructions on building and deploying to your device.
316After having configured signing for your app, you may proceed to build a release version of the app. This is no different to how you build the non-release version, so consult the section [Android](#android) further above for exact instructions on building and deploying to your device.
319+## Frequently Asked Questions (FAQ)
321+Refer to [FAQ](FAQ.md).
326+Contributions and issue reports are encouraged and appreciated! Refer to the [Contributing](CONTRIBUTING.md) guide for information about getting started.