# Using Docker to run Tinode
All images are available at https://hub.docker.com/r/tinode/
1. [Install Docker](https://docs.docker.com/install/) 1.8 or above. The provided dockerfiles are dependent on [Docker networking](https://docs.docker.com/network/) which may not work with the older Docker.
2. Create a bridge network. It's used to connect Tinode container with the database container.
```
$ docker network create tinode-net
```
3. Decide which database backend you want to use: RethinkDB, MySQL or MongoDB. Run the selected database container, attaching it to `tinode-net` network:
1. **RethinkDB**: If you've decided to use RethinkDB backend, run the official RethinkDB Docker container:
```
$ docker run --name rethinkdb --network tinode-net --restart always -d rethinkdb:2.3
```
See [instructions](https://hub.docker.com/_/rethinkdb/) for more options.
2. **MySQL**: If you've decided to use MySQL backend, run the official MySQL Docker container:
```
$ docker run --name mysql --network tinode-net --restart always --env MYSQL_ALLOW_EMPTY_PASSWORD=yes -d mysql:5.7
```
See [instructions](https://hub.docker.com/_/mysql/) for more options. MySQL 5.7 or above is required.
3. **MongoDB**: If you've decided to use MongoDB backend, run the official MongoDB Docker container and initialise it as single node replica set (you can change "rs0" if you wish):
```
$ docker run --name mongodb --network tinode-net --restart always -d mongo:latest --replSet "rs0"
$ docker exec -it mongodb mongo
# And inside mongo shell:
> rs.initiate( {"_id": "rs0", "members": [ {"_id": 0, "host": "mongodb:27017"} ]} )
> quit()
```
See [instructions](https://hub.docker.com/_/mongo/) for more options. MongoDB 4.2 or above is required.
The name `rethinkdb`, `mysql` or `mongodb` in the `--name` assignment is important. It's used by other containers as a database's host name.
4. Run the Tinode container for the appropriate database:
1. **RethinkDB**:
```
$ docker run -p 6060:6060 -d --name tinode-srv --network tinode-net tinode/tinode-rethinkdb:latest
```
2. **MySQL**:
```
$ docker run -p 6060:6060 -d --name tinode-srv --network tinode-net tinode/tinode-mysql:latest
```
3. **MongoDB**:
```
$ docker run -p 6060:6060 -d --name tinode-srv --network tinode-net tinode/tinode-mongodb:latest
```
You can also run Tinode with the `tinode/tinode` image (which has all of the above DB adapters compiled in). You will need to specify the database adapter via `STORE_USE_ADAPTER` environment variable. E.g. for `mysql`, the command line will look like
```
$ docker run -p 6060:6060 -d -e STORE_USE_ADAPTER mysql --name tinode-srv --network tinode-net tinode/tinode:latest
```
See [below](#supported-environment-variables) for more options.
The port mapping `-p 5678:1234` tells Docker to map container's port 1234 to host's port 5678 making server accessible at http://localhost:5678/. The container will initialize the database with test data on the first run.
You may replace `:latest` with a different tag. See all all available tags here:
* [MySQL tags](https://hub.docker.com/r/tinode/tinode-mysql/tags/)
* [RethinkDB tags](https://hub.docker.com/r/tinode/tinode-rethink/tags/)
* [MongoDB tags](https://hub.docker.com/r/tinode/tinode-mongodb/tags/)
* [All bundle tags](https://hub.docker.com/r/tinode/tinode/tags/) (comming soon)
5. Test the installation by pointing your browser to [http://localhost:6060/](http://localhost:6060/).
## Optional
### External config file
The container comes with a built-in config file which can be customized with values from the environment variables (see [Supported environment variables](#supported_environment_variables) below). If changes are extensive it may be more convenient to replace the built-in config file with a custom one. In that case map the config file located on your host (e.g. `/users/jdoe/new_tinode.conf`) to container (e.g. `/tinode.conf`) using [Docker volumes](https://docs.docker.com/storage/volumes/) `--volume /users/jdoe/new_tinode.conf:/tinode.conf` then instruct the container to use the new config `--env EXT_CONFIG=/tinode.conf`:
```
$ docker run -p 6060:6060 -d --name tinode-srv --network tinode-net \
--volume /users/jdoe/new_tinode.conf:/tinode.conf \
--env EXT_CONFIG=/tinode.conf \
tinode/tinode-mysql:latest
```
If you set `EXT_CONFIG` all other environment variables except `RESET_DB`, `FCM_SENDER_ID`, `FCM_VAPID_KEY` are ignored.
### Resetting or upgrading the database
The database schema may change from time to time. An error `Invalid database version 101. Expected 103` means the schema has changed and needs to be updated, in this case from version 101 to version 103. You need to either reset or upgrade the database to continue:
Shut down the Tinode container and remove it:
```
$ docker stop tinode-srv && docker rm tinode-srv
```
then repeat step 4 adding `--env RESET_DB=true` to reset or `--env UPGRADE_DB=true` to upgrade.
Also, the database is automatically created if missing.
### Enable push notifications
Tinode uses Google Firebase Cloud Messaging (FCM) to send pushes.
Follow [instructions](../docs/faq.md#q-how-to-setup-fcm-push-notifications) for obtaining the required FCM credentials.
* Download and save the [FCM service account credentials](https://cloud.google.com/docs/authentication/production) file.
* Obtain values for `apiKey`, `messagingSenderId`, `projectId`, `appId`, `messagingVapidKey`.
Assuming your Firebase credentials file is named `myproject-1234-firebase-adminsdk-abc12-abcdef012345.json`
and it's saved at `/Users/jdoe/`, web API key is `AIRaNdOmX4ULR-X6ranDomzZ2bHdRanDomq2tbQ`, Sender ID `141421356237`,
Project ID `myproject-1234`, App ID `1:141421356237:web:abc7de1234fab56cd78abc`, VAPID key (a.k.a. "Web Push certificates")
is `83_Or_So_Random_Looking_Characters`, start the container with the following parameters (using MySQL container as an example):
```
$ docker run -p 6060:6060 -d --name tinode-srv --network tinode-net \
-v /Users/jdoe:/fcm \
--env FCM_CRED_FILE=/fcm/myproject-1234-firebase-adminsdk-abc12-abcdef012345.json \
--env FCM_API_KEY=AIRaNdOmX4ULR-X6ranDomzZ2bHdRanDomq2tbQ \
--env FCM_APP_ID=1:141421356237:web:abc7de1234fab56cd78abc \
--env FCM_PROJECT_ID=myproject-1234 \
--env FCM_SENDER_ID=141421356237 \
--env FCM_VAPID_KEY=83_Or_So_Random_Looking_Characters \
tinode/tinode-mysql:latest
```
### Run the chatbot
See [instructions](../chatbot/python/).
The chatbot password is generated only when the database is initialized or reset. It's saved to `/botdata` directory in the container. If you want to keep the data available between container changes, such as image upgrades, make sure the `/botdata` is a mounted volume (i.e. you always launch the container with `--volume botdata:/botdata` option).
## Supported environment variables
You can specify the following environment variables when issuing `docker run` command:
| Variable | Type | Default | Function |
| --- | --- | --- | --- |
| `AUTH_TOKEN_KEY` | string | `wfaY2RgF2S1OQI/ZlK+LSârp1KB2jwAdGAIHQ7JZn+Kc=` | base64-encoded 32 random bytes used as salt for authentication tokens. |
| `AWS_ACCESS_KEY_ID` | string | | AWS Access Key ID when using `s3` media handler |
| `AWS_CORS_ORIGINS` | string | `["*"]` | Allowed origins ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)) URL for downloads. Generally use your server URL and its aliases. |
| `AWS_REGION` | string | | AWS Region when using `s3` media handler |
| `AWS_S3_BUCKET` | string | | Name of the AWS S3 bucket when using `s3` media handler |
| `AWS_SECRET_ACCESS_KEY` | string | | AWS [Secret Access Key](https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/) when using `s3` media handler |
| `CLUSTER_SELF` | string | | Node name if the server is running in a Tinode cluster |
| `CLUSTER_NUM_PROXY_EVENT_GOROUTINES` | int | 0 | Number of goroutines used for processing topic master to proxy responses |
| `DEBUG_EMAIL_VERIFICATION_CODE` | string | | Enable dummy email verification code, e.g. `123456`. Disabled by default (empty string). |
| `EXT_CONFIG` | string | | Path to external config file to use instead of the built-in one. If this parameter is used all other variables except `RESET_DB`, `FCM_SENDER_ID`, `FCM_VAPID_KEY` are ignored. |
| `EXT_STATIC_DIR` | string | | Path to external directory containing static data (e.g. Tinode Webapp files) |
| `FCM_CRED_FILE` | string | | Path to json file with FCM server-side service account credentials which will be used to send push notifications. |
| `FCM_API_KEY` | string | | Firebase API key; required for receiving push notifications in the web client |
| `FCM_APP_ID` | string | | Firebase web app ID; required for receiving push notifications in the web client |
| `FCM_PROJECT_ID` | string | | Firebase project ID; required for receiving push notifications in the web client |
| `FCM_SENDER_ID` | string | | Firebase FCM sender ID; required for receiving push notifications in the web client |
| `FCM_VAPID_KEY` | string | | Also called 'Web Client certificate' in the FCM console; required by the web client to receive push notifications. |
| `FCM_INCLUDE_ANDROID_NOTIFICATION` | boolean | true | If true, pushes a data + notification message, otherwise a data-only message. [More info](https://firebase.google.com/docs/cloud-messaging/concept-options). |
| `MEDIA_HANDLER` | string | `fs` | Handler of large files, either `fs` or `s3` |
| `MYSQL_DSN` | string | `'root@tcp(mysql)/tinode'` | MySQL [DSN](https://github.com/go-sql-driver/mysql#dsn-data-source-name). |
| `PLUGIN_PYTHON_CHAT_BOT_ENABLED` | bool | `false` | Enable calling into the plugin provided by Python chatbot |
| `RESET_DB` | bool | `false` | Drop and recreate the database. |
| `SAMPLE_DATA` | string | _see comment â_ | File with sample data to load. Default `data.json` when resetting or generating new DB, none when upgrading. Use `` (empty string) to disable |
| `SMTP_DOMAINS` | string | | White list of email domains; when non-empty, accept registrations with emails from these domains only (email verification). |
| `SMTP_HOST_URL` | string | `'http://localhost:6060/'` | URL of the host where the webapp is running (email verification). |
| `SMTP_LOGIN` | string | | Optional login to use for authentication with the SMTP server (email verification). |
| `SMTP_PASSWORD` | string | | Optional password to use for authentication with the SMTP server (email verification). |
| `SMTP_PORT` | number | | Port number of the SMTP server to use for sending verification emails, e.g. `25` or `587`. |
| `SMTP_SENDER` | string | | [RFC 5322](https://tools.ietf.org/html/rfc5322) email address to use in the `FROM` field of verification emails, e.g. `'"John Doe"