# Account-Isolated Installation

- Link: https://ubient.dscloud.biz/docs/ubient-software/rtmn/account-isolated-installation/
- Published: 2026-10-13T01:26:42+09:00
- Author: Ubient

Use this model when one Linux server needs multiple `rtmn` instances separated by
Linux account.

Each instance must have its own:

 * Linux account
 * systemd service name
 * Binary path
 * Environment file
 * Audit log path
 * Telegram bot token

## Example Layout

    ```ubient-docs-code
    rtmn-ops.service   -> User=<account-a> -> /etc/rtmn/env-ops   -> /home/<account-a>/.rtmn-ops/rtmn-ops
    rtmn-app.service   -> User=<account-b> -> /etc/rtmn/env-app   -> /home/<account-b>/.rtmn-app/rtmn-app
    rtmn-admin.service -> User=<account-c> -> /etc/rtmn/env-admin -> /home/<account-c>/.rtmn-admin/rtmn-admin
    ```

## Why Manual Installation Is Needed

The built-in `rtmn install` command is designed for a single default service. The
default service name is `rtmn.service`.

In account-isolated operation, each service name, environment file, log file, and
binary path must be unique. For that reason, this model creates systemd unit files
manually.

## Naming Rules

| Item | Pattern | Example | 
| Linux account | `<account>` | `<service-account>` | 
| Instance name | `<instance>` | `ops` | 
| Binary directory | `/home/<account>/.rtmn-<instance>` | `/home/<service-account>/.rtmn-ops` | 
| Binary path | `/home/<account>/.rtmn-<instance>/rtmn-<instance>` | `/home/<service-account>/.rtmn-ops/rtmn-ops` | 
| Environment file | `/etc/rtmn/env-<instance>` | `/etc/rtmn/env-ops` | 
| Audit log | `/var/log/rtmn/<instance>/audit.log` | `/var/log/rtmn/ops/audit.log` | 
| systemd service | `rtmn-<instance>.service` | `rtmn-ops.service` |

Use only lowercase letters, numbers, and hyphens for `<instance>`.

## 1. Set Variables

    ```ubient-docs-code
    BashACCOUNT=<service-account>
    INSTANCE=ops
    BINARY_SOURCE=/path/to/rtmn
    GROUP="$(id -gn "$ACCOUNT")"
    ```

Verify that the account exists:

    ```ubient-docs-code
    Bashid "$ACCOUNT"
    ```

If the account does not exist, create it using the appropriate method for your distribution:

    ```ubient-docs-code
    Bashsudo useradd -m -s /bin/bash "$ACCOUNT"
    GROUP="$(id -gn "$ACCOUNT")"
    ```

## 2. Install the Account-Specific Binary

    ```ubient-docs-code
    Bashsudo install -d -o "$ACCOUNT" -g "$GROUP" -m 0750 "/home/$ACCOUNT/.rtmn-$INSTANCE"
    sudo install -o "$ACCOUNT" -g "$GROUP" -m 0755 "$BINARY_SOURCE" "/home/$ACCOUNT/.rtmn-$INSTANCE/rtmn-$INSTANCE"
    ```

Verify it:

    ```ubient-docs-code
    Bashsudo -u "$ACCOUNT" "/home/$ACCOUNT/.rtmn-$INSTANCE/rtmn-$INSTANCE" --help
    ```

## 3. Create Environment and Log Directories

    ```ubient-docs-code
    Bashsudo install -d -o root -g root -m 0750 /etc/rtmn
    sudo install -d -o "$ACCOUNT" -g "$GROUP" -m 0750 "/var/log/rtmn/$INSTANCE"
    sudo install -o root -g root -m 0600 /dev/null "/etc/rtmn/env-$INSTANCE"
    ```

The environment file contains the Telegram bot token, so only root should be able
to read it. The audit log directory must be writable by the service account.

## 4. Write the Environment File

    ```ubient-docs-code
    Bashsudoedit "/etc/rtmn/env-$INSTANCE"
    ```

Content:

    ```ubient-docs-code
    RTMN_TELEGRAM_TOKEN=<BOT_TOKEN>
    RTMN_ALLOWED_CHAT_IDS=<CHAT_ID_1>,<CHAT_ID_2>
    RTMN_SHELL_PATH=/bin/bash
    RTMN_SHELL_ARGS=
    RTMN_AUDIT_LOG_PATH=/var/log/rtmn/<INSTANCE>/audit.log
    RTMN_AUDIT_MAX_BYTES=10485760
    RTMN_AUDIT_MAX_BACKUPS=5
    RTMN_DEBOUNCE_MS=200
    RTMN_MAX_CHUNK_SIZE=3500
    RTMN_POLL_TIMEOUT_SEC=30
    RTMN_INCOMING_RATE_PER_MIN=30
    RTMN_OUTGOING_RATE_PER_SEC=25
    RTMN_OUTPUT_OVERFLOW_BYTES=262144
    ```

Verify permissions:

    ```ubient-docs-code
    Bashsudo stat -c '%n %U %G %a' "/etc/rtmn/env-$INSTANCE"
    ```

Expected values are owner `root`, group `root`, and mode `600`.

## 5. Create the systemd Service

    ```ubient-docs-code
    Bashsudo tee "/etc/systemd/system/rtmn-$INSTANCE.service" >/dev/null <<EOF
    [Unit]
    Description=rtmn-$INSTANCE - Telegram-to-Terminal gateway for $ACCOUNT
    After=network-online.target
    Wants=network-online.target
    StartLimitBurst=10
    StartLimitIntervalSec=60

    [Service]
    Type=simple
    User=$ACCOUNT
    Group=$GROUP
    WorkingDirectory=/home/$ACCOUNT
    Environment=HOME=/home/$ACCOUNT
    Environment=USER=$ACCOUNT
    Environment=LOGNAME=$ACCOUNT
    Environment=SHELL=/bin/bash
    ExecStart=/home/$ACCOUNT/.rtmn-$INSTANCE/rtmn-$INSTANCE run
    EnvironmentFile=/etc/rtmn/env-$INSTANCE
    Restart=always
    RestartSec=5
    RestartPreventExitStatus=78
    StandardOutput=journal
    StandardError=journal

    [Install]
    WantedBy=multi-user.target
    EOF
    ```

Verify the unit syntax:

    ```ubient-docs-code
    Bashsudo systemd-analyze verify "/etc/systemd/system/rtmn-$INSTANCE.service"
    ```

## 6. Start the Service

    ```ubient-docs-code
    Bashsudo systemctl daemon-reload
    sudo systemctl enable --now "rtmn-$INSTANCE.service"
    sudo systemctl status "rtmn-$INSTANCE.service" --no-pager
    ```

Check logs:

    ```ubient-docs-code
    Bashsudo journalctl -u "rtmn-$INSTANCE.service" -n 100 --no-pager
    ```

## 7. Repeat for Another Account

Each additional instance must have a unique:

 * `ACCOUNT`
 * `INSTANCE`
 * Telegram bot token
 * Environment file
 * systemd service name
 * Audit log path

Example:

    ```ubient-docs-code
    ACCOUNT=<another-service-account>
    INSTANCE=app
    BINARY_SOURCE=/path/to/rtmn
    GROUP="$(id -gn "$ACCOUNT")"
    ```

Generated layout:

    ```ubient-docs-code
    /home/<another-service-account>/.rtmn-app/rtmn-app
    /etc/rtmn/env-app
    /var/log/rtmn/app/audit.log
    rtmn-app.service
    ```
