@@ -0,0 +1,311 @@
1+# Obelisk Application Deployment Guide
2+This document serves two purposes, the first one is to guide new users that want to deploy Obelisk/Reflex apps and the second one to provide a walk-through for test driving Obelisk releases.
4+> **Note:** To complete this *entire* guide you need access to a macOS machine running the latest OSX release, a Linux machine (can be a VM on that mac) with Nix installed, an iPhone or iPad, and a recent Android device. It also assumes that you have Nix correctly set up and that your system is set up to fetch from binary caches instead of building everything on your machine. If you notice any of the commands below takes more than 5 minutes, then caches are not likely enabled.
6+> Refer to the [Obelisk Installation Documentation](https://github.com/obsidiansystems/obelisk#installing-obelisk) for instructions on configuring the binary caches for any Nix-compatible setup.
10+There are several ways to install Obelisk, but the one we are going to use here allows us to test a single version of Obelisk in different ways. The approach is to clone Obelisk from it's GitHub repository and start a project that uses that local check out.
12+Open a terminal and run the following:
15+export WORKDIR=~/obelisk-guide
19+Then let's get Obelisk from GitHub using a specific branch:
22+export OBELISK_BRANCH=develop
23+git clone https://github.com/obsidiansystems/obelisk.git -b "$OBELISK_BRANCH" "$WORKDIR/obelisk"
26+Once you have an Obelisk check out, you can build it using Nix and make a shortcut (alias) for the rest of the terminal session. With this you will be able to type `ob` anywhere as long as you do not close the terminal.
29+alias ob=$(nix-build "$WORKDIR/obelisk" -A command --no-out-link)/bin/ob
32+In order to start an Obelisk project, we need initialize it in a new directory. Let's call it `myapp`:
35+mkdir -p "$WORKDIR/myapp"
37+ob init --branch "$OBELISK_BRANCH"
40+> **Note:** If the `--branch` parameter is not used, then Obelisk sets your project up to look at the `master` branch from GitHub. This is quite handy for real life projects but distracting for our test drive since we want to make sure any changes we do to the Obelisk codebase (like testing a pull request) are immediately picked up.
42+## b) Run the Obelisk app on localhost
44+Let's test that we can run a server on localhost. This is quite easy:
51+Now open a browser and point it to http://localhost:8000 (or just click on this link). You should see the following:
53+
55+## c) Deploy the web app on a remote machine
57+### Import the NixOS VirtualBox appliance
58+Install [VirtualBox](https://www.virtualbox.org/) on your machine.
60+On NixOS, do this by adding the following line to your `/etc/nixos/configuration.nix` before the last line containing `}`:
63+ virtualisation.virtualbox.host.enable = true;
66+then `sudo nixos-rebuild switch`.
68+The NixOS [download page](https://nixos.org/nixos/download.html) has a section called "VirtualBox appliances". Download that as the target system. The author used the 19.09 `.ova` file.
70+With the downloaded file, open VirtualBox and import the `.ova` file:
72+
74+Leave the default settings and finish the import. That will take a few minutes:
76+
78+You should now see a NixOS machine in the dashboard:
80+
82+If you are on a network with DHCP on your wireless or network card then select right-click on the "NixOS" image and click "Settings". Go to the "Network" section and make "Attached to:" set to "Bridged Adapter".
84+
86+Finally, double-click on the "NixOS" machine and wait for it boot up. If it asks for a password, use `demo`.
88+
90+### Configure the virtual machine for SSH
92+Inside the virtual machine open up "Konsole" by clicking on the start menu in the bottom left corner and typing in "Konsole" until you see it as an option in the menu. Then click on it to open it.
94+Change the system configuration using `sudo` to enable SSH access:
97+sudo nano /etc/nixos/configuration.nix
100+This will ask you to enter your password. Enter `demo`.
102+
104+You need to add the following snippet right before the final line containing `}`.
107+ services.openssh.enable = true;
108+ services.openssh.permitRootLogin = "yes";
111+Save and close the editor by typing <kbd>Ctrl</kbd>+<kbd>O</kbd>, <kbd>Enter</kbd>, and then <kbd>Ctrl</kbd>+<kbd>X</kbd>.
113+Now run `sudo nixos-rebuild switch` (if it asks for a password, again use `demo`) and then set the root password using `sudo passwd root`. Pick a simple password like `root`. You'll need to use it again.
115+To get the virtual machine's IP address go back to the terminal on your *host* machine (not the virtual machine) and run:
118+export VM_ID=$(VBoxManage list runningvms | grep "NixOS" | awk -F'[{}]' '{print $2}')
122+You should see a single identifier that looks like `388bbbe5-e0a2-4b20-9c76-bbaa5746682e`. If you see anything else then you likely you have multiple NixOS machines running. Stop any other machines and run this command again. (Of course, if you're a power user, just change the `grep` to pick out right VM.)
124+Now get the IP address for that machine:
127+export VM_IP=$(VBoxManage guestproperty enumerate "$VM_ID" | grep /V4/IP | awk '{print $4}' | sed 's/,//')
131+You should see an IP like `192.168.7.86`.
133+With that you will be able to SSH into that machine from a terminal, using the username `root`.
136+ssh root@$VM_IP echo "Access granted"
139+This may ask if you want to trust the fingerprint for this server. Answer `yes`. It will ask you for a password. Enter the one you specified above. You should see `Access granted` printed after you type your password and hit <kbd>Enter</kbd>.
141+> **Note:** If instead you see an error like this
144+> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
145+> @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
146+> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
147+> IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
148+> Someone could be eavesdropping on you right now (man-in-the-middle attack)!
149+> It is also possible that a host key has just been changed.
152+> you need to remove the old fingerprint for this IP. Run the following:
155+> sed -i "/^$VM_IP /d" ~/.ssh/known_hosts
158+> and then try the previous `ssh` command again.
160+Now we'll allow access with an SSH key instead of a password. Create a new SSH key with `ssh-keygen`:
163+ssh-keygen -t ed25519 -f "$WORKDIR/obkey" -P ""
166+Now copy your local SSH key to the server:
169+ssh-copy-id -i "$WORKDIR/obkey.pub" root@$VM_IP
172+This will ask you for your password again.
174+Now test login with your key instead:
177+ssh -i "$WORKDIR/obkey" root@$VM_IP echo "Access granted"
180+This should print `Access granted` *without* asking for a password.
182+### Configure the git remote
184+Before the project can be deployed, it needs to be a valid `git` repository.
186+> **Note:** You need `git` installed and configured. You can do that with:
190+> git config --global user.name "John Doe"
191+> git config --global user.email johndoe@example.com
195+git init --bare "$WORKDIR/myapp-git-remote"
199+git commit -m "initial commit"
200+git remote add origin "$WORKDIR/myapp-git-remote"
201+git push -u origin master
206+With that, we can come back to the Obelisk app and initialize the deployment:
210+ob deploy init --ssh-key "$WORKDIR/obkey" --admin-email a@a.a --hostname $VM_IP --route https://$VM_IP "$WORKDIR/myappdeploy" --disable-https
213+Then configure the deployment for VirtualBox:
216+echo '{nixosPkgs, ...}: {...}: { imports = [ (nixosPkgs.path + /nixos/modules/virtualisation/virtualbox-image.nix) ]; }' > "$WORKDIR/myappdeploy/module.nix"
222+cd "$WORKDIR/myappdeploy"
226+Once that is complete, open the webpage with
229+xdg-open http://$VM_IP
232+If that fails, just get the URL by running
238+and copy/paste that URL into your browser navigation input.
240+It should look like this:
242+
244+Congratulations! You have deployed an Obelisk application to a remote server via SSH.
246+## d) Deploy an Android app (Linux host only)
248+> **Note:** This section requires that you be running a Linux *host*.
250+Modify `$WORKDIR/myapp/default.nix` to set `config.android_sdk.accept_license = true;` and then update your app.
254+sed -i 's/# config.android_sdk.accept_license = false;/config.android_sdk.accept_license = true;/g' default.nix
256+git commit -m"Accept license"
260+Make sure *USB debugging* is enabled in your Android device ([instructions here](https://developer.android.com/studio/debug/dev-options) and connect the device using USB. Be sure to confirm any security prompts on the device.
262+Now update your deployment and deploy to Android:
265+cd "$WORKDIR/myappdeploy"
267+ob deploy test android -v
270+This deployment will ask you to create a password (at least 6 characters long) and then ask you a series of questions. You can pick arbitrary answers. If the deployment fails, try using different USB ports on your computer and running `ob deploy test android -v` again. The USB cable you use can also make a difference.
272+When connecting your Android device you may be asked to "Allow USB debugging". You need to allow it.
273+
276+When the deployment is complete opening the app should look something like
278+
280+Congratulations! You have deployed an Obelisk Android app via USB.
282+## e) Deploy an iOS app (macOS host only)
284+> **Note:** This section requires that you be running a macOS *host*.
286+Verify that you can see the device from XCode and you have installed a Provisioning profile that links your Apple Developer Id and the Device identifier. The workflow depends on whether or not you are an independent developer or part of an organization and is out of scope for this manual.
288+
290+Find your `Team ID` at the following URL (Apple Developer Membership details): https://developer.apple.com/account/#/membership/
292+It will be something like `5B445B3WY1`. With that, you can start the deployment workflow after plugging in an iPhone or iPad via USB and setting it to trust the computer:
295+cd "$WORKDIR/myappdeploy"
296+ob deploy test ios <TEAM-ID> # Use your Team ID here
299+
301+
303+If there are no errors and the last line says `100% Installed Package` you can open the device and look for the Obelisk app:
305+
307+
309+Congratulations, you have deployed an Obelisk app on an iOS device.
311+You are now ready to create your own multi-platform application using Obelisk!