Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 214 additions & 0 deletions docs/howto/dev-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# Using a dev version of the server

This isn't required for most development -- you can use chat.zulip.org,
or another live Zulip community you belong to, for testing the mobile app.
But sometimes when debugging interactions with the server, or developing
server-side changes related to the mobile app, it's helpful to run the
mobile app against a development server which you control.

Setting this up involves a few steps, but it should be straightforward if
our instructions are right and you follow them carefully. If these don't
work for you or you have any trouble, please report it in chat, with details
on exactly what you did and what happened; we'll help you debug, and then
adjust the instructions so they work for the next person with a setup like
yours.

(Also, if these instructions don't discuss your setup, definitely ask in
chat! And PRs very welcome.)


## Summary checklist

This checklist describes a typical setup (with your Zulip dev server
inside Vagrant). It may be helpful for reminders after you've done
this a time or two before.

For details on each step, and for alternative configurations, see the
sections below.

- [ ] Find your computer's IP address on your LAN; perhaps try
`ip route get 8 | perl -lne '/src (\S+)/ && print $1'`.
- [ ] Check your `~/.zulip-vagrant-config` (outside the dev VM).
- [ ] Run the server like `EXTERNAL_HOST=${ip_address}:9991 tools/run-dev`.
- [ ] Log in at `http://${ip_address}:9991`. Type `http://` explicitly.


## 1. Set up a dev server

First, if you haven't already, you'll want to install and provision a
[Zulip Server dev VM](https://zulip.readthedocs.io/en/latest/development/overview.html).

For most people the recommended setup uses Vagrant to manage a VM containing
the Zulip server. If you choose instead to run the Zulip server directly on
your host machine, these instructions will work with some variations.

You'll run the Zulip server in the dev VM with `tools/run-dev`, following
the usual instructions for Zulip server development (linked above). [Step
4](#4-set-external_host) below adds some options to the `run-dev` command
to make it accessible from the mobile app.


## 2. Find the right IP address

For development on the web app, you'd typically access your Zulip dev server
in a browser on your computer, with the URL `http://localhost:9991/`. This
refers to port 9991 on `localhost`, which is a name that works for talking
to a server on your own computer.

That URL won't necessarily work for the mobile app, because on your phone
(either physical or emulated), `localhost` would be a name for the phone
itself, rather than your computer. Instead, we'll find an IP address that we
can use instead of `localhost`, which will reach your computer when used on
the phone.

There are several ways to do this, depending on your platform. See below.

### iOS simulator (macOS only)

The iOS simulator shares its network interface with the computer it's running
on. Happily, this means `http://localhost:9991` will work without further
configuration; you can skip to [the last step](#last-step).

### Android emulator

This works if you're running the app in the Android emulator, on the same
computer where you're running the dev server (either as a Vagrant host, or
directly.)

In this situation, the emulator provides 10.0.2.2 as a special alias for the
`localhost` of your computer. (See [upstream docs][android-emulator-net].)
So you can just use `10.0.2.2` below.

There is one drawback: when using this address (in particular when using it
in Step 4 below), you won't be able to load the dev server in a browser on
your computer. If that makes your testing inconvenient, then move on to the
alternative approach below, which additionally works on all platforms.

[android-emulator-net]: https://developer.android.com/studio/run/emulator-networking

### Any physical or emulated device

This method should work on any physical device, the Android emulator,
or the iOS simulator.

First:
* If you're using a physical device, you'll need it and your computer to be
on the same local network. You can do this by connecting both the mobile device
and the computer to the same wifi network; or by creating a mobile hotspot
on the device and connecting the computer to that.
* For an emulator/simulator, you just need to run it on the same computer
you're running the Zulip server on.

We'll use **the IP address your computer uses on the local network**.
* For a physical device, this should be on the same network the phone is on.
* For the Android emulator, any IP address that belongs to your
computer (and isn't a special "loopback" address like 127.0.0.1)
will do.
* For the iOS simulator, if you are not using the simpler method above,
even a loopback address like 127.0.0.1 will be fine.

To find this, you can use a command-line tool like (on Linux or macOS)
`ip addr` or `ifconfig`; or look in the network pane of macOS's System
Preferences or of Windows's Control Panel. The IP address you want
will often start with `192.168` or `10.10`; the network interface it
belongs to might look like `wlp4s0` or `en1`.

The command `ip route get 8.8.8.8` (on Linux) will show how your
computer would send a packet to the Internet, which is typically the
right direction. You'd use the address shown after `src`, which is
the one that belongs to your computer.

For a detailed example, see our howto on [finding your IP
address](find-ip-address.md).


## 3. Listen on all interfaces

(If you're using the Android emulator and the IP address 10.0.2.2, or if you're
using the iOS simulator and `localhost`, you can skip this step and move on
to step 4.)

By default, the Zulip dev server only listens on the "loopback" network
interface, 127.0.0.1, aka `localhost`. This is a nice secure default,
because it means the only way to connect to the server is from on the
computer itself. But it's less helpful when what we want is to connect from
another device; so we'll configure it to listen on all your computer's
network interfaces.

### If using Vagrant

If you set up your dev server to run inside Vagrant (the recommended and
usual approach), then the process actually listening on `localhost:9991` is
a forwarder, set up by Vagrant, which passes requests on to the Zulip
server inside the VM.

To make the forwarder listen on all network interfaces, just add the
following line to a file `~/.zulip-vagrant-config` on the host computer
(and create the file if it doesn't already exist):
```
HOST_IP_ADDR 0.0.0.0
```

Then restart the Vagrant guest using `vagrant reload`.

### If running server directly on host

If you're running the Zulip server directly on your computer, then you
control this by passing the option `--interface=` to `tools/run-dev`.
For example:
<pre>
$ tools/run-dev <strong>--interface=</strong>
</pre>

(But you'll probably add more to the command too; see step 4.)


## 4. Set EXTERNAL_HOST

(If you're using `localhost` with the iOS simulator, you can skip this
step.)

Like most complex web apps, the Zulip server has an idea internally of what
base URL it's supposed to be accessed at; we call this setting
`EXTERNAL_HOST`. In development, the setting is normally `localhost:9991`,
and corresponds to a base URL of `http://localhost:9991/`.

Set this to `ADDRESS:9991`, where `ADDRESS` is the address you identified in
step 2. In development, we can do this with an environment variable. For
example, if in step 2 you chose 10.0.2.2, then run the server with this
command:

<pre>
$ <strong>EXTERNAL_HOST=10.0.2.2:9991</strong> tools/run-dev
</pre>

or if step 3 called for `--interface=`, then

<pre>
$ <strong>EXTERNAL_HOST=10.0.2.2:9991</strong> tools/run-dev --interface=
</pre>

(Note for Zulip server experts: This also sets `REALM_HOSTS`, via some logic
in `zproject/dev_settings.py`, which is actually the critical part here.)


<a id="last-step"></a>
## 5. Log in!

Now fire up the app on your emulator or device, go to the
"switch account" UI, and enter the URL of the dev server.

This will be `http://ADDRESS:9991`, where `ADDRESS` is the address you
identified in step 2. (Be sure to type the `http://`.)

This should get you the login screen!

To log in, you'll want the password for some user on the dev server.
You can find that with a command like this:
```
./manage.py print_initial_password iago@zulip.com
```

(Ideally the app would support the handy dev-only auth method which
bypasses the need for a password; that's #405.
Consider implementing that feature.)
144 changes: 144 additions & 0 deletions docs/howto/find-ip-address.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Finding your computer's IP address

This doc describes how to find the IP address your computer uses on the
local network. This is often needed as a step in setting up to [use a dev
version of the Zulip server](dev-server.md) with the app.

In brief:
* Look at your network configuration, either with a command line tool like
`ip addr` or `ifconfig` (both available for Linux and macOS) or in the
network pane of macOS's System Preferences or of Windows's Control Panel.
* Look there for the IP address on your wifi interface, or whatever network
interface connects your computer to the Internet. The IP address you want
will often start with `192.168`. The network interface it belongs to
might look like `wlp4s0` or `en1`.

More detail below. (PRs with examples of different configurations would be
very welcome!)

## Example: `ip addr`, wifi, Linux

If you run the command `ip addr` on a Linux machine connected to wifi, the
output might look similar to this:

<pre>
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 54:ee:75:26:2e:d9 brd ff:ff:ff:ff:ff:ff
3: wlp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 90:48:9a:a5:28:ef brd ff:ff:ff:ff:ff:ff
inet <b>192.168.0.23</b>/24 brd 10.0.0.255 scope global dynamic noprefixroute wlp4s0
valid_lft 225643sec preferred_lft 225643sec
inet6 2a00:1028:8386:75de:20a4:2fdf:5373:31c3/64 scope global temporary dynamic
valid_lft 172791sec preferred_lft 52729sec
inet6 2a00:1028:8386:75de:ca5:d3cf:dd83:9b69/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 172791sec preferred_lft 86391sec
inet6 fe80::83a6:19d:16c6:5e0d/64 scope link noprefixroute
valid_lft forever preferred_lft forever
</pre>

Here `lo` is the "loopback" interface accessible only from itself. `wlp4s0`
is this computer's wifi interface. IP (v4) addresses are introduced with
the label `inet`.

The relevant IP address in this example is the `inet` value on the wifi
interface: `192.168.0.23`.

## Example: `ifconfig`, wifi, macOS

If you run the command `ifconfig` on a macOS machine connected to wifi, the
output might look similar to this:

<pre>
$ ifconfig
lo0: flags=8049&lt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 16384
options=1203&lt;RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP&gt;
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=201&lt;PERFORMNUD,DAD&gt;
gif0: flags=8010&lt;POINTOPOINT,MULTICAST&gt; mtu 1280
stf0: flags=0&lt;&gt; mtu 1280
XHC20: flags=0&lt;&gt; mtu 0
en1: flags=8963&lt;UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST&gt; mtu 1500
options=60&lt;TSO4,TSO6&gt;
ether 6a:00:02:98:c3:d0
media: autoselect &lt;full-duplex&gt;
status: inactive
en2: flags=8963&lt;UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST&gt; mtu 1500
options=60&lt;TSO4,TSO6&gt;
ether 6a:00:02:98:c3:d1
media: autoselect &lt;full-duplex&gt;
status: inactive
en0: flags=8863&lt;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
ether c4:b3:01:c1:ce:9f
inet6 fe80::47e:23e4:2dbd:e1fa%en0 prefixlen 64 secured scopeid 0x7
inet <b>192.168.86.89</b> netmask 0xffffff00 broadcast 192.168.86.255
nd6 options=201&lt;PERFORMNUD,DAD&gt;
media: autoselect
status: active
p2p0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 2304
ether 06:b3:01:c1:ce:9f
media: autoselect
status: inactive
awdl0: flags=8943&lt;UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST&gt; mtu 1484
ether 32:d0:80:06:6c:3b
inet6 fe80::30d0:80ff:fe06:6c3b%awdl0 prefixlen 64 scopeid 0x9
nd6 options=201&lt;PERFORMNUD,DAD&gt;
media: autoselect
status: active
bridge0: flags=8863&lt;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
options=63&lt;RXCSUM,TXCSUM,TSO4,TSO6&gt;
ether 6a:00:02:98:c3:d0
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en1 flags=3&lt;LEARNING,DISCOVER&gt;
ifmaxaddr 0 port 5 priority 0 path cost 0
member: en2 flags=3&lt;LEARNING,DISCOVER&gt;
ifmaxaddr 0 port 6 priority 0 path cost 0
nd6 options=201&lt;PERFORMNUD,DAD&gt;
media: &lt;unknown type&gt;
status: inactive
utun0: flags=8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 2000
inet6 fe80::126b:c8e2:bc66:596%utun0 prefixlen 64 scopeid 0xb
nd6 options=201&lt;PERFORMNUD,DAD&gt;
utun1: flags=8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1380
inet6 fe80::25e7:e24c:aadc:4f82%utun1 prefixlen 64 scopeid 0xc
nd6 options=201&lt;PERFORMNUD,DAD&gt;
vboxnet0: flags=8842&lt;BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
ether 0a:00:27:00:00:00
vboxnet1: flags=8943&lt;UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST&gt; mtu 1500
ether 0a:00:27:00:00:01
inet 172.28.128.1 netmask 0xffffff00 broadcast 172.28.128.255
</pre>

There are kind of a lot of different interfaces here. The ones without an
`inet` value aren't likely to matter -- that means an IPv4 address. Of
those, in this example:
* `lo0` is a "loopback" interface accessible only from itself.
* `vboxnet1` (and `vboxnet0`) are interfaces created by VirtualBox (or
perhaps created by Vagrant and used by VirtualBox) for communicating with
VMs managed by VirtualBox.
* `en0` is the wifi interface.

(If your local network is very futuristic, it's possible your wifi interface
will have only an IPv6 address, labeled `inet6`. As of 2018, this is rare.)

The relevant IP address in this example is the `inet` value on the wifi
interface: `192.168.86.89`.

One command to help sort through this output would be
`ifconfig | grep 'inet.*broadcast'`:
<pre>
inet <b>192.168.86.89</b> netmask 0xffffff00 broadcast 192.168.86.255
inet 172.28.128.1 netmask 0xffffff00 broadcast 172.28.128.255
</pre>
6 changes: 3 additions & 3 deletions docs/howto/push-notifications-ios-simulator.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Testing Push Notifications on iOS Simulator

For documentation on testing push notifications on Android or a real
iOS device, see https://github.com/zulip/zulip-mobile/blob/main/docs/howto/push-notifications.md
iOS device, see [push-notifications.md](push-notifications.md).

This doc describes how to test client-side changes on iOS Simulator.
It will demonstrate how to use APNs payloads the server sends to
Expand Down Expand Up @@ -92,7 +92,7 @@ The `user_id` is that of `iago@zulip.com` in the Zulip dev environment.

These canned payloads assume that EXTERNAL_HOST has its default value
for the dev server. If you've
[set EXTERNAL_HOST to use an IP address](https://github.com/zulip/zulip-mobile/blob/main/docs/howto/dev-server.md#4-set-external_host)
[set EXTERNAL_HOST to use an IP address](dev-server.md#4-set-external_host)
in order to enable your device to connect to the dev server, you'll
need to adjust the `realm_url` fields. You can do this by a
find-and-replace for `localhost`; for example,
Expand Down Expand Up @@ -219,7 +219,7 @@ for setting up a dev server.

If you want to run the dev server on a different machine than the Mac
host, you'll need to follow extra steps
[documented here](https://github.com/zulip/zulip-mobile/blob/main/docs/howto/dev-server.md)
[documented here](dev-server.md)
to make it possible for the app running on the iOS Simulator to
connect to the dev server.

Expand Down
Loading