> ## Documentation Index
> Fetch the complete documentation index at: https://rustunnel.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributing

> How to contribute to rustunnel — an open-source, self-hosted tunnel server written in Rust.

Contributions are welcome! rustunnel is open-source under the [AGPLv3 license](https://github.com/joaoh82/rustunnel/blob/main/LICENSE). Whether it's a bug fix, a new feature, or improved documentation, we appreciate your help.

## Before you start

For larger changes or new features, **open an issue first** to discuss the approach. This avoids duplicate effort and ensures the change is aligned with the project direction.

For small fixes (typos, docs, minor bugs) you can go straight to a pull request.

***

## Getting started

<Steps>
  <Step title="Fork and clone">
    Fork the repository on GitHub, then clone your fork:

    ```bash theme={null}
    git clone https://github.com/<your-username>/rustunnel.git
    cd rustunnel
    ```
  </Step>

  <Step title="Install dependencies">
    You need:

    | Tool           | Version | Notes                                      |
    | -------------- | ------- | ------------------------------------------ |
    | Rust toolchain | 1.76+   | Install via [rustup](https://rustup.rs)    |
    | `pkg-config`   | any     | Required by `reqwest` (TLS)                |
    | `libssl-dev`   | any     | On Debian/Ubuntu: `apt install libssl-dev` |
    | Node.js + npm  | 18+     | Only needed to rebuild the dashboard UI    |
    | Docker         | any     | Required to run the test database          |
  </Step>

  <Step title="Install git hooks">
    Run this once after cloning to activate the pre-push quality gate:

    ```bash theme={null}
    make install-hooks
    ```

    Every `git push` will automatically run `cargo fmt` checks and `cargo clippy` before the push is allowed.
  </Step>

  <Step title="Create a feature branch">
    Branch off `main` with a descriptive name:

    ```bash theme={null}
    git checkout -b fix/heartbeat-timeout
    # or
    git checkout -b feat/tcp-region-selection
    ```
  </Step>
</Steps>

***

## Local development

### Build

```bash theme={null}
# Debug build (fast compile)
cargo build --workspace

# Or via Make
make build
```

### Run the server locally

Generate a self-signed certificate for local testing:

```bash theme={null}
mkdir -p /tmp/rustunnel-dev

openssl req -x509 -newkey rsa:2048 \
  -keyout /tmp/rustunnel-dev/key.pem \
  -out    /tmp/rustunnel-dev/cert.pem \
  -days 365 -nodes \
  -subj "/CN=localhost"
```

Start the server with the checked-in local config:

```bash theme={null}
cargo run -p rustunnel-server -- --config deploy/local/server.toml
```

### Run the client locally

With the server running, expose a local service:

```bash theme={null}
# HTTP tunnel
cargo run -p rustunnel-client -- http 3000 \
  --server localhost:4040 \
  --token dev-secret-change-me \
  --insecure

# TCP tunnel
cargo run -p rustunnel-client -- tcp 5432 \
  --server localhost:4040 \
  --token dev-secret-change-me \
  --insecure
```

<Note>`--insecure` skips TLS verification — required when using the self-signed cert. Never use it against a production server.</Note>

***

## Running tests

The integration test suite spins up a real server on random ports and exercises auth, HTTP tunnels, TCP tunnels, and reconnection logic. It requires a running PostgreSQL instance.

```bash theme={null}
# Start the local PostgreSQL container (persists across reboots)
make db-start

# Full suite: unit + integration
make test

# With output visible
TEST_DATABASE_URL=postgres://rustunnel:test@localhost:5432/rustunnel_test \
  cargo test --workspace -- --nocapture

# Run a single test
TEST_DATABASE_URL=postgres://rustunnel:test@localhost:5432/rustunnel_test \
  cargo test <test_name> -p <crate_name>

# Stop PostgreSQL when done
make db-stop
```

***

## Code quality

Before opening a PR, make sure these pass:

```bash theme={null}
# Format check
cargo fmt --all -- --check

# Lint (zero warnings policy)
cargo clippy --workspace --all-targets -- -D warnings

# Both at once
make check
```

CI runs the same checks on every push and pull request.

***

## Opening a pull request

1. Push your branch to your fork and open a PR against `main`.
2. Write a clear description of **what changed and why**.
3. Make sure CI is green — format, Clippy, and all tests.
4. A maintainer will review and merge.

### PR guidelines

* **Keep PRs focused** — one logical change per PR. Avoid bundling unrelated fixes.
* **Add or update tests** for any new behaviour. The integration test suite in `tests/integration/` is the right place for end-to-end scenarios.
* **Follow existing code style** — `cargo fmt` is enforced by CI.
* **Update documentation** if you change user-facing behaviour (flags, config keys, API endpoints).

***

## Project structure

| Path                         | Purpose                                                    |
| ---------------------------- | ---------------------------------------------------------- |
| `crates/rustunnel-protocol/` | Shared `ControlFrame` types and serialization              |
| `crates/rustunnel-server/`   | Server: control plane, HTTP/TCP edges, dashboard, TLS      |
| `crates/rustunnel-client/`   | CLI client with auto-reconnect and local port forwarding   |
| `crates/rustunnel-mcp/`      | MCP server for AI agent integration                        |
| `dashboard-ui/`              | Next.js dashboard frontend                                 |
| `deploy/`                    | Dockerfiles, compose files, systemd unit, config templates |
| `tests/integration/`         | End-to-end tests (real server + real PostgreSQL)           |
| `docs/`                      | Public documentation source                                |

***

## Useful make targets

| Target               | Description                                |
| -------------------- | ------------------------------------------ |
| `make build`         | Debug build of all workspace crates        |
| `make release`       | Optimized release build                    |
| `make check`         | `cargo fmt` check + `cargo clippy`         |
| `make test`          | Full test suite (requires `make db-start`) |
| `make db-start`      | Start the local PostgreSQL container       |
| `make db-stop`       | Stop the local PostgreSQL container        |
| `make install-hooks` | Install the pre-push git hook              |
| `make docker-build`  | Build the server Docker image              |

***

## License

By contributing you agree that your work will be licensed under the [GNU AGPLv3 License](https://github.com/joaoh82/rustunnel/blob/main/LICENSE).

***

## Contact

**João Henrique Machado Silva**

* GitHub: [@joaoh82](https://github.com/joaoh82)
* Issues & feature requests: [GitHub Issues](https://github.com/joaoh82/rustunnel/issues)

***

## Related pages

<CardGroup cols={2}>
  <Card title="Architecture" icon="book-open" href="/docs/guides/architecture">
    Understand the control protocol, yamux data plane, and crate structure before diving into the code.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/docs/quickstart">
    Install the client and open your first tunnel in three steps.
  </Card>

  <Card title="Client guide" icon="terminal" href="/docs/guides/client-guide">
    Every command, flag, and config option for the rustunnel CLI client.
  </Card>

  <Card title="Self-hosting" icon="server" href="/docs/guides/self-hosting">
    Run your own rustunnel server on a VPS with systemd and Let's Encrypt.
  </Card>
</CardGroup>
