A Federated Multi-Party Chat System in Golang, using Matrix Protocol.
This project is in the scope of a Distribuited Systems Introduction Course. Dragonite is a multi-party federated chat, using the Matrix Protocol. The server is written in Go and implements the Matrix client-server API, so it can be used with Element or any other standard Matrix client — as the banner suggests, the whole thing is inspired by the Dragonite mailer from the Pokémon© franchise.
Dragonite explores how a federated chat system can be built on top of the Matrix protocol instead of a centralized architecture. The goal is to understand, in practice, the trade-offs of federation, event synchronization, and multi-server communication — concepts covered in a Distributed Systems course.
The backend acts as a Matrix homeserver/bridge written in Go, implementing the Matrix client-server API so any standard Matrix client — such as Element — can connect to it directly, without a custom frontend. Key backend dependencies include pgx and lib/pq for PostgreSQL, minio-go for media storage, and godotenv for environment configuration (see go.mod for the full list).
- Go 1.26.1 or later
- Docker (used to run PostgreSQL, Redis, and MinIO locally)
- migrate CLI (used by
migrate.sh) - Element (or any other Matrix client) to connect to the running server
Clone the repository:
git clone https://github.com/caio-bernardo/dragonite.git
cd dragoniteDownload the Go module dependencies:
go mod downloadConsidering you have cloned this project. Make a copy of the .env.example file and rename to .env. Fill the environmet variables.
cp .env.example .env| Variable | Description |
|---|---|
BACKEND_PORT |
Port the Go server listens on |
SERVER_NAME |
Public host/port used to build URLs (e.g. media links) |
VERSION |
App version reported by the server |
DRAGONITE_DB_* |
PostgreSQL connection settings (username, password, database, port, schema, host) |
JWT_TOKEN |
Secret used to sign/verify JWT auth tokens |
REDIS_HOST / REDIS_PORT / REDIS_PASSWORD |
Redis connection settings |
MINIO_ENDPOINT / MINIO_ACCESS_KEY / MINIO_SECRET_KEY / MINIO_USE_SSL |
MinIO connection settings for media storage |
MAX_UPLOAD_BYTES |
Maximum allowed upload size, in bytes (default: 50 MB) |
See .env.example for the full file with default values.
- Open Element Web or your installed Element app.
- On the sign-in screen, choose "Edit" next to the homeserver field (or "Sign in with a different account", depending on the version).
- Enter your server's address — e.g.
http://localhost:8080for a local run, or the value you set inSERVER_NAMEfor a deployed instance. - Sign in or register using the credentials created through Dragonite's own registration flow.
Element expects the homeserver to expose the standard Matrix client-server API endpoints (
/_matrix/client/...). If Element can't discover the server automatically, make sureSERVER_NAMEandBACKEND_PORTare reachable from wherever Element is running, and that any required.well-knowndelegation is set up for non-local deployments.
- (Optional) Start a local database container:
make docker-run- After running the container for the first time you need to create the tables inside the database do that using the
migrate.shscript as follows:
export DB_URL=postgres://user:pass@localhost:5432/dbname?sslmode=disable
./migrate.sh upUse the same values as in .env file.
- Run the server (see more commands at Makefile).
make run- Use
Ctrl-Cto stop the server andmake docker-downto disable the container.
.
├── air.toml
├── cmd
│ └── api
├── docker-compose.yml
├── go.mod
├── go.sum
├── internal
│ ├── delivery
│ ├── domain
│ ├── infrastructure
│ ├── usecase
│ └── util
├── LICENSE
├── Makefile
├── migrate.sh
├── migrations
│ ├── 000001_usuario_table.down.sql
│ ├── 000001_usuario_table.up.sql
│ ├── 000002_evento_table.down.sql
│ ├── 000002_evento_table.up.sql
│ ├── 000004_canal_table.down.sql
│ ├── 000004_canal_table.up.sql
│ ├── 000005_filter_receipt_table.down.sql
│ ├── 000005_filter_receipt_table.up.sql
│ ├── 000006_midia_table.down.sql
│ ├── 000006_midia_table.up.sql
│ ├── 000007_matrix_sync_client_func.down.sql
│ ├── 000007_matrix_sync_client_func.up.sql
│ ├── 000008_add_evento_unsigned_filed.down.sql
│ ├── 000008_add_evento_unsigned_filed.up.sql
│ ├── 000009_presence_table.down.sql
│ ├── 000009_presence_table.up.sql
│ ├── 000010_typing_state.up.sql
│ ├── 000011_backup_version_table.down.sql
│ └── 000011_backup_version_table.up.sql
├── README.md
├── static
└── TASKS.md
Following Clean/Hexagonal Architecture conventions, business rules live in internal/domain and internal/usecase, while internal/delivery and internal/infrastructure handle HTTP/Matrix I/O and external dependencies respectively.
Feel free to open a new issue or submit a pull request. See our CONTRIBUTING guide for details on how to report bugs, suggest enhancements, and submit your first pull request.
This project is under the MIT license. For more info see LICENSE.
This file was made with Make Your Reads.
