Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ on:
push:
branches: [master]
tags: ['*']
paths-ignore:
- '**.md'
- 'deploy/**'
- 'LICENSE'
- '.gitignore'
pull_request:
paths-ignore:
- '**.md'
- 'deploy/**'
- 'LICENSE'
- '.gitignore'
workflow_dispatch:

# This build is heavy (TDLib + tgcalls + WebRTC from source); cancel runs
Expand Down
86 changes: 86 additions & 0 deletions deploy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Deploying with podman + Quadlet (rootless)

Runs the call service as a rootless systemd service via [Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
Requires **podman ≥ 4.4** on the server. The image is public on GHCR, so no
registry login is needed to pull.

## 1. Install the unit and config

```sh
mkdir -p ~/.config/containers/systemd ~/.config/tg-call-service
cp deploy/tg-call-service.container ~/.config/containers/systemd/
cp deploy/tg-call-service.env.example ~/.config/tg-call-service/tg-call-service.env
```

Edit `~/.config/tg-call-service/tg-call-service.env` and set `API_ID` / `API_HASH`
(from <https://my.telegram.org/apps>).

## 2. Create data dirs and a prompt

```sh
mkdir -p ~/.local/share/tg-call-service/{tdlib_db,recordings}
```

Provide the audio prompt (48 kHz stereo MP3) played to callers — copy your own to
`~/.local/share/tg-call-service/prompt.mp3`, or generate one with the tools image:

```sh
# simple beep prompt
podman run --rm -v ~/.local/share/tg-call-service:/out \
ghcr.io/nikicat/tg-echo-service-tools:latest prompt

# or a GLaDOS TTS prompt
podman run --rm -v ~/.local/share/tg-call-service:/out \
ghcr.io/nikicat/tg-echo-service-tools:latest \
glados-prompt GLADOS_TEXT="Please leave a message after the beep."
```

## 3. One-time Telegram login

Authenticate once to create the TDLib session in `tdlib_db` (interactive — enter
your phone number and the login code Telegram sends):

```sh
podman run --rm -it \
--env-file ~/.config/tg-call-service/tg-call-service.env \
-v ~/.local/share/tg-call-service/tdlib_db:/app/tdlib_db:Z \
ghcr.io/nikicat/tg-echo-service:latest auth
```

## 4. Start it

```sh
loginctl enable-linger "$USER" # keep the service running with no login session
systemctl --user daemon-reload # generate the service from the .container unit
systemctl --user start tg-call-service # [Install] handles auto-start at boot
```

Check status / logs:

```sh
systemctl --user status tg-call-service
journalctl --user -u tg-call-service -f
```

## 5. Updates (optional)

The unit sets `AutoUpdate=registry`; enable the timer to pull a newer `:latest` and
restart automatically:

```sh
systemctl --user enable --now podman-auto-update.timer
```

To pin a release instead, set `Image=ghcr.io/nikicat/tg-echo-service:v1.2.3` in the
unit and drop the `AutoUpdate=registry` line.

## Notes

- **`Network=pasta`** needs the `passt` package (default on recent distros; it's the
rootless default on podman ≥ 5). If unavailable, remove that line to fall back to
the default rootless network.
- `%h` expands to the user's home. If your systemd doesn't expand it in a value,
replace `%h/...` with absolute paths.
- **Rootful variant:** put the `.container` in `/etc/containers/systemd/`, replace
`%h/...` with absolute paths (e.g. `/var/lib/tg-call-service/...`), then
`sudo systemctl daemon-reload && sudo systemctl start tg-call-service`.
40 changes: 40 additions & 0 deletions deploy/tg-call-service.container
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Quadlet unit for the Telegram echo call service (rootless podman + systemd).
#
# Install to: ~/.config/containers/systemd/tg-call-service.container
# Then: systemctl --user daemon-reload && systemctl --user start tg-call-service
#
# See deploy/README.md for full setup (credentials, prompt, one-time auth, linger).
# Requires podman >= 4.4 (Quadlet).

[Unit]
Description=Telegram echo call service
After=network-online.target
Wants=network-online.target

[Container]
Image=ghcr.io/nikicat/tg-echo-service:latest
# Pull a newer :latest on `podman auto-update` (enable the timer; see README).
AutoUpdate=registry

# API_ID, API_HASH and optional ECHO_DELAY.
EnvironmentFile=%h/.config/tg-call-service/tg-call-service.env

# Persistent TDLib session DB — created by the one-time `auth` run (see README).
Volume=%h/.local/share/tg-call-service/tdlib_db:/app/tdlib_db:Z
# Recorded voice messages, written after each call.
Volume=%h/.local/share/tg-call-service/recordings:/app/recordings:Z
# Audio prompt played to callers (provide your own 48 kHz stereo MP3).
Volume=%h/.local/share/tg-call-service/prompt.mp3:/app/prompt.mp3:ro,Z

# Rootless networking; the service only makes outbound connections (no ports).
Network=pasta

[Service]
Restart=always
RestartSec=5
# First start pulls the image (a few hundred MB); allow time.
TimeoutStartSec=900

[Install]
# Auto-start at boot (after `systemctl --user daemon-reload`); no `enable` needed.
WantedBy=default.target
7 changes: 7 additions & 0 deletions deploy/tg-call-service.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copy to ~/.config/tg-call-service/tg-call-service.env and fill in.
# Telegram API credentials — create an app at https://my.telegram.org/apps
API_ID=
API_HASH=

# Optional: seconds to delay before echoing the caller's audio back.
#ECHO_DELAY=2