---
title: Charmhub | Deploy Tmate-ssh-server using Charmhub - The Open Operator Collection
description: Deploy the latest version of Tmate-ssh-server on any cloud.
url: https://charmhub.io/tmate-ssh-server/docs/explanation-charm-architecture
---

# Tmate-ssh-server

[Canonical IS DevOps](https://charmhub.io/publisher/canonical-is-devops "View all packages from Canonical IS DevOps")

* [Canonical IS DevOps](https://charmhub.io/publisher/canonical-is-devops "View all packages from Canonical IS DevOps")

Platform:

24.04

22.04

stable 76324872

```
juju deploy tmate-ssh-server
```

[Learn to deploy on juju >](https://juju.is/docs/juju/manage-applications)

---

#### Contacts

##### Maintainers

+ [Launchpad Team](https://launchpad.net/~canonical-is-devops)

* [Submit a bug](https://github.com/canonical/tmate-ssh-server-operator/issues)

---

Share your thoughts on this charm with the community on discourse.

[Join the discussion](https://discourse.charmhub.io/)

# Charm architecture

The tmate SSH server operator operates [tmate SSH server](https://github.com/tmate-io/tmate-ssh-server),
which is the server side of [tmate](https://github.com/tmate-io/tmate), an open-source terminal multiplexer
that provides instant terminal sharing capabilities.
The tmate SSH server application is built from source as an OCI image and runs as a systemd service on the machine.

The charm provides the necessary connection details for a tmate client to connect to the tmate SSH server service
via integration data.

```
C4Container
title Container diagram for tmate SSH Server

 Container_Boundary(c1, "tmate SSH Server") {
    Container(tmatessh, "tmate SSH Server", "", "Provides sharing a remote session")
 }
Container_Boundary(c2, "tmate Client Charm") {
    Container(clientcharm, "tmate Client Charm", "", "Charm managing tmate client workload.")
 }

    System_Ext(tmateclient, "tmate Client", "Client that shares their terminal session")
    System_Ext(collaborator, "Collaborator", "Another client who wants access to the terminal")

    Rel(tmatessh, clientcharm, "provides connection details")
    Rel(clientcharm, tmateclient, "init client with connection details")

    Rel(tmateclient, tmatessh, "init session via SSH")
    Rel(collaborator, tmatessh, "join session via SSH")

    UpdateRelStyle(tmatessh, clientcharm, $offsetY="30", $offsetX="-70")
    UpdateRelStyle(clientcharm, tmateclient, $offsetY="80", $offsetX="150")
    UpdateRelStyle(tmateclient, tmatessh, $offsetY="-30", $offsetX="10")
    UpdateRelStyle(collaborator, tmatessh, $offsetY="-30", $offsetX="80")
```

### [Why is this a machine charm?](https://charmhub.io/tmate-ssh-server/docs/explanation-charm-architecture#p-36866-why-is-this-a-machine-charm)

The OCI image for tmate SSH server requires certain kernel capabilities to run ([SYS\_ADMIN](https://github.com/tmate-io/tmate-ssh-server/issues/73#issuecomment-762756632)).
At design time, due to the limitations of a Juju Kubernetes charm, the container was unable to receive the capability.
Furthermore, providing SSH ingress for machine charms is easier to achieve than for K8s charms. Hence, it was decided to make tmate SSH server a machine charm.

See [[specification] ISD099 tmate charm for Github Runners](https://discourse.charmhub.io/t/specification-isd099-tmate-charm-for-github-runners/16837)
for more information.

## [OCI images](https://charmhub.io/tmate-ssh-server/docs/explanation-charm-architecture#p-36866-oci-images)

We use [Rockcraft](https://canonical-rockcraft.readthedocs-hosted.com/en/latest/) to build OCI images for tmate SSH server.
The images are defined in [tmate-ssh-server\_rock](https://github.com/canonical/tmate-ssh-server-operator/tree/main/tmate-ssh-server_rock).
They are published to the [Github Container registry](https://github.com/canonical/tmate-ssh-server-operator/pkgs/container/tmate-ssh-server).

## [Juju events](https://charmhub.io/tmate-ssh-server/docs/explanation-charm-architecture#p-36866-juju-events)

The following Juju [events](https://juju.is/docs/sdk/event) are observed and handled by the charm as follows:

1. [install](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/hook/#install): The charm is installed on the machine. The charm tests if a unit IP is assigned, otherwise the event is deferred. Afterwards,
   the charm installs the necessary tmate SSH server’s dependencies, setups ssh keys and installs a `systemd` service that runs the tmate SSH server OCI image. The integration data is updated with the relevant server connection details (equivalent of `tmate.conf` configuration file),
   which can be used by a tmate client to connect to the server.
2. [update-status](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/hook/#update-status): This is a regular status check. The charm
   checks if the tmate SSH server is still running and restarts it if it is not.
3. `get-server-config-action`: This is an [action event](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/hook/#action-actiont) triggered by the user
   to get the current server connection configuration (`tmate.conf`), which can be used by a tmate client to connect to the server.
4. `ssh-debug-relation-joined`: This is a [relation joined event](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/hook/#endpoint-relation-joined) that fires when
   a unit joins an integration. It inserts the relevant server connection details into the integration data, which can be used by a tmate client to connect to the server.

> See more about events in the Juju docs: [Hook](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/hook)

## [Charm code overview](https://charmhub.io/tmate-ssh-server/docs/explanation-charm-architecture#p-36866-charm-code-overview)

The `src/charm.py` is the default entry point for a charm and has the `TmateSSHServerOperatorCharm` Python class which inherits from CharmBase. CharmBase is the base class
from which all charms are formed, defined by [Ops](https://juju.is/docs/sdk/ops) (Python framework for developing charms).

> See more in the Juju docs: [Charm](https://canonical-juju.readthedocs-hosted.com/en/latest/user/reference/charm/)

The `__init__` method guarantees that the charm observes all events relevant to its operation and handles them.

Take, for example, when the charm gets deployed.

1. User runs the command:

```
juju deploy tmate-ssh-server
```

1. An `install` event is emitted.
2. In the `__init__` method is defined how to handle this event like this:

```
self.framework.observe(self.on.install, self._on_install)
```

1. The method `_on_install`, for its turn, will take the necessary actions such as installing the tmate SSH server software.

The code is structured according to the best practices described in [Managing charm complexity](https://discourse.charmhub.io/t/specification-isd014-managing-charm-complexity/11619).
Therefore, in addition to `src/charm.py`, there are other modules in the charm that are responsible for specific tasks:

* observe changes to the ssh-debug integration
* manage the state of the charm
* abstracting interactions with the tmate SSH server application

---
