Getting Started with Tinode: An Open-Source Messaging Server
Tags: opensource, chat, tinode, docker
Published: 2024-03-15 01:25:07

Do you need to build a chat service and have no time to develop the service from scratch? Calm down! There is an open-source solution to answer your problem.
In this post, we will explore [tinode](https://tinode.co/) to solve our problem

## What is Tinode?

Tinode is an open-source messaging platform written in Go. It can be used to build real-time messaging applications.

From their official site
> Tinode is a free, unlimited, and flexible open source messaging platform that’s been built mobile-first.

>Instant, free, global communication should be a fundamental feature of today's internet. Our aim is to enable everyone to create a high-quality chat experience outside of the walled gardens that exist today.

## Getting Started
In this section, we will only explain running a tinode server with binary and docker using Linux.

### Install from binaries
Before following below step, make sure our database is already running

* Download the Tinode binary on their [release page](https://github.com/tinode/chat/releases/)
. We will use [v0.22.12](https://github.com/tinode/chat/releases/download/v0.22.12/tinode-alldbs.linux-amd64.tar.gz) alldbs for Linux in this example
```bash
wget https://github.com/tinode/chat/releases/download/v0.22.12/tinode-alldbs.linux-amd64.tar.gz
```
* Create a new directory and extract the binary to the new directory
```bash
mkdir tinode-chat
tar -xvf tinode-alldbs.linux-amd64.tar.gz -C tinode-chat
```
* Set the Tinode configuration by editing a configuration file named `tinode.conf` in the same directory as the Tinode binary.
```bash
cd tinode-chat
vim tinode.conf
```
* Change the `use_adapter`, `User`, `Addr`, `Passwd`, and `DBName` values on the DB connection configuration section. In this example, we will use the MySQL database.
```conf
                // Must be one of the adapters from the list below.
                "use_adapter": "mysql",

                // Configurations of individual adapters.
                "adapters": {
                        // MySQL configuration. See https://godoc.org/github.com/go-sql-driver/mysql#Config
                        // for other possible options.
                        "mysql": {
                                // MySQL connection settings.
                                // See https://pkg.go.dev/github.com/go-sql-driver/mysql#Config for more info
                                // and available fields and options.
                                "User": "db_username",
                                "Net": "tcp",
                                "Addr": "db_host",
                                "Passwd": "db_password",
                                "DBName": "db_name",
                                // The 'collation=utf8mb4_unicode_ci' is optional but highly recommended for
                                // emoji and certain CJK characters.
                                "Collation": "utf8mb4_unicode_ci",
                                // Parse time values to time.Time. Required.
                                "ParseTime": true,
```
* Run the database initializer `init-db`
```bash
./init-db
```
Output example
```log
2024/03/14 04:23:49 Database adapter: 'mysql'; version: 113
2024/03/14 04:23:49 Database not found. Creating.
2024/03/14 04:23:59 Database successfully created.
2024/03/14 04:23:59 No data provided, stopping
2024/03/14 04:23:59 All done.
```
If we want to generate user data when initializing the database, we can use json file to generate the data for the database. The json format example from official docs [data.json](https://github.com/tinode/chat/blob/master/tinode-db/data.json). To init the database by generating data from the json file execute the below command
```bash
# This command will initialize the database and generate example users like Bob or Alice
./init-db -data=data.json
```
Output example while init-db with generating data from json file
```log
2024/03/14 04:27:11 Database adapter: 'mysql'; version: 113
2024/03/14 04:27:11 Database not found. Creating.
2024/03/14 04:27:16 Database successfully created.
2024/03/14 04:27:16 Generating users...
usr;alice;usrDUuFy6DahqY;alice123
usr;bob;usr8jmNzPuC2Hk;bob123
2024/03/14 04:27:17 Generating group topics...
grp;*ABC;grpNjtGeGveyEs
grp;*ABCDEF;grp7tR9jTaFl00
grp;*BACDF;grptKswCQFaZdY
2024/03/14 04:27:17 Generating P2P subscriptions...
p2p;alice:bob;p2p8jmNzPuC2HkNS4XLoNqGpg
2024/03/14 04:27:17 Generating group subscriptions...
2024/03/14 04:27:17 Inserting messages...
2024/03/14 04:27:18 Inserting forms as  tino IFHqLxWfylQ
2024/03/14 04:27:19 Sample data processing completed.
2024/03/14 04:27:19 All done.
```
* After the database is initialized, run the tinode server
```bash
./tinode
```
Once the Tinode server is started, you can access the Tinode web interface by opening a web browser and navigating to the following URL: http://localhost:6060
Login Interface
![Tinode login interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c16djjjs3nyb4nvy565p.png)
```
# Example User | user:password
alice:alice123
bob:bob123
eve:eve123
```
Logged in Interface
![Tinode logged-in interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hi367ezk6mgf802f73ep.png)

Congratulations! You have successfully installed the Tinode binary on your system. You can now start using Tinode as a standalone messaging server or integrate it with other applications for real-time communication. For more information on how to use Tinode, you can refer to the [official documentation](https://github.com/tinode/chat/blob/master/INSTALL.md).

### Run with docker
To save time, we will use docker compose to run the tinode server
* Create `tinode-docker` directory and create docker-compose.yml inside it
```bash
mkdir tinode-docker
cd tinode-docker
vim docker-compose.yml
```
Copy the below code to our `docker-compose.yml` file
```yml
services:
  mysql:
    image: "mysql:8"
    container_name: mysql
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes # Not recommended in prod
    restart: always
    volumes:
      - db-data:/var/lib/mysql
      
  tinode:
    image: "tinode/tinode-mysql:0.22.12"
    container_name: tinode
    restart: on-failure
    ports:
      - "6060:6060"
      - "16060:16060"
    depends_on:
      - mysql
    links:
      - mysql

volumes:
  db-data:

```
* Run the tinode server
```bash
docker compose up
``` 
Taraa!! Our messaging server is ready to use

![Tinode running by docker compose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/339a84ix6gnl7oge60lq.png)