docker compose (архитектура amd64 или arm64), свободный порт 8080, домен и reverse-proxy с TLS, установленные и авторизованные Claude Code и Codex на машинах, которыми вы управляете, доступ к репозиторию wiva-hq/CodeRail за командами установки моста
CodeRail — это self-hosted пульт (панель, развёрнутая на вашем собственном сервере) для Claude Code и Codex: чаты, подтверждения вызовов инструментов, терминалы, файлы, git и браузер на каждой вашей машине. Серверная часть — один контейнер ghcr.io/wiva-hq/coderail, веб-интерфейс на порту 8080 за HTTPS, всё состояние в ./data.
Схема из чего состоит система:
| Компонент | Где работает | Что делает |
|---|---|---|
| Сервер CodeRail | ваш сервер, контейнер `ghcr.io/wiva-hq/coderail` | отдаёт веб-интерфейс на 8080, хранит историю в `./data` |
| Мост (bridge) | каждая управляемая машина | ходит только наружу, к серверу |
| Claude Code и Codex | каждая управляемая машина | ключи остаются локально, на сервер не уезжают |
Ключевое следствие: сервер должен быть доступен с телефона, а машины — только исходящие соединения к серверу. Сквозного шифрования нет — история хранится на вашем сервере, это надо принять до установки.
Проверьте базу списком:
./data — история чатов и файлы будут расти.Что сделать: выполнить диагностику одной пачкой.
Зачем: если Docker не установлен или порт занят, контейнер не поднимется, и вы будете искать причину не там.
Как проверить:
docker --version
docker compose version
uname -m
ss -ltnp | grep ':8080' || echo "порт 8080 свободен"
df -h / | tail -1
Ожидаемый вывод: строка вида Docker version 2x.x.x, Docker Compose version v2.x, x86_64 (это amd64) или aarch64 (это arm64), сообщение порт 8080 свободен и строка с запасом места. Почему это работает: ss -ltnp показывает занятые TCP-порты, поэтому пустой вывод по 8080 означает, что публикация порта не конфликтует.
Что сделать: создать рабочий каталог и подкаталог data рядом с файлом конфигурации.
Зачем: всё состояние CodeRail хранится в ./data; если каталог не смонтировать как том, история исчезнет при пересоздании контейнера.
Как проверить:
mkdir -p ~/coderail/data
cd ~/coderail
pwd && ls -la
Ожидаемый вывод: путь вида /home/<user>/coderail и список с каталогом data. Почему это работает: Docker монтирует каталог хоста внутрь контейнера, и запись переживает docker compose down — при условии, что путь тома совпадает с тем, который ожидает образ.
Пример: если вы работаете под пользователем deploy, команда pwd вернёт /home/deploy/coderail.

Что сделать: создать docker-compose.yml, поднять контейнер, поставить перед ним HTTPS и установить мост на управляемые машины.
Зачем: контейнер даёт веб-интерфейс на 8080, а мост на каждой машине превращает её в управляемую — без него в панели не будет ни чатов, ни терминалов.
Как проверить: см. блок команд ниже и Шаг 3.
Файл ~/coderail/docker-compose.yml:
services:
coderail:
image: ghcr.io/wiva-hq/coderail
container_name: coderail
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./data:/app/data
Внутренний путь тома (/app/data) сверьте с документацией проекта wiva-hq/CodeRail: важен именно он, иначе данные окажутся вне смонтированного каталога.
Запуск:
cd ~/coderail
docker compose pull
docker compose up -d
Ожидаемый вывод: Container coderail Started. Почему это работает: pull забирает образ под вашу архитектуру (amd64 или arm64), up -d запускает его в фоне с автоперезапуском.
Дальше HTTPS. Порт 8080 — единственный опубликованный порт, поэтому TLS ставится перед ним на reverse-proxy. Пример шаблона для Caddy (домен замените на свой):
<ваш-домен> {
reverse_proxy 127.0.0.1:8080
}
<ваш-домен> — это DNS-имя, которое указывает на IP сервера, например coderail.myteam.dev. Как именно CodeRail ожидает TLS и требуется ли ему знание о внешнем адресе — сверьтесь с документацией проекта.
Затем на каждой машине, которой хотите управлять, установите мост. Точную команду установки и список параметров берите из README репозитория wiva-hq/CodeRail — в посте канала она не приводится, выдумывать синтаксис нельзя. Логика та же, что у любого агента за NAT: мост инициирует исходящее соединение к вашему серверу, поэтому проброс портов на машинах не нужен, а ключи Claude и Codex остаются на компьютерах.
Пример: сервер — ARM-VPS (aarch64), образ берётся под arm64 без отдельного тега; телефон открывает https://coderail.myteam.dev, ноутбук с Claude Code держит исходящее соединение к этому же домену.
Если управляете несколькими агентами сразу, схему «пульт на телефоне + агенты на машинах» удобно расширять по гайду Как превратить чёлку MacBook в пульт управления ИИ-агентами: настройка Claude Code, Codex, Cursor и Copilot.

Что сделать: последовательно проверить контейнер, HTTP-ответ локально, HTTPS снаружи и живую сессию с телефона.
Зачем: каждая проверка отсекает свой класс поломок — упавший контейнер, занятый порт, неверный TLS, непривязанный мост.
Как проверить:
docker ps --filter name=coderail --format 'table {{.Status}}\t{{.Ports}}'
docker logs --tail 30 coderail
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080
curl -sS -I https://<ваш-домен> | head -1
ls -la ~/coderail/data
Что должно появиться на экране:
STATUS — Up и время работы, в PORTS — 0.0.0.0:8080->8080/tcp;panic/fatal;curl локально печатает 200 или 302 (редирект на страницу входа — норма);curl по HTTPS печатает HTTP/2 200;ls показывает непустой data — значит, состояние пишется на диск.Финальная проверка глазами: откройте https://<ваш-домен> в браузере телефона, войдите, найдите в списке свою машину, отправьте агенту короткий запрос и подтвердите вызов инструмента прямо из интерфейса.
Чек-лист приёмки:
coderail в состоянии Up, порт 8080 опубликованhttp://127.0.0.1:8080 отвечает 200 или 302https://<ваш-домен> открывается с мобильного браузера~/coderail/data непустой после первого диалогаПроблема. Контейнер не стартует, порт занят
driver failed programming external connectivity on endpoint coderail: Bind for 0.0.0.0:8080 failed: port is already allocatedsudo ss -ltnp | grep ':8080' и остановить, либо перенести публикацию на другой порт: в docker-compose.yml заменить на "8081:8080", выполнить docker compose up -d и поправить reverse_proxy на 127.0.0.1:8081.Проблема. С телефона страница не открывается по HTTPS
ERR_SSL_PROTOCOL_ERROR или ERR_CONNECTION_REFUSEDIP:8080; убедиться, что reverse-proxy запущен и слушает 443 (sudo ss -ltnp | grep ':443'), а curl -I http://127.0.0.1:8080 локально уже отвечает 200/302. Если локально пусто — проблема в контейнере, а не в сертификате.Проблема. Docker не принимает команды от пользователя
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sockdocker.sudo usermod -aG docker $USER && newgrp docker, затем повторить docker compose up -d. Если вместо этого выводится Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? — сам демон не запущен: sudo systemctl enable --now docker.Один контейнер ghcr.io/wiva-hq/coderail с томом ./data, HTTPS перед портом 8080 и мост на каждой машине дают вам пульт управления Claude Code и Codex с телефона. Дальше стоит закрыть доступ по сети (VPN или allowlist на reverse-proxy) и проверить, как встраивать такую схему в командную работу — см. Claude Code для команды: как настроить субагентов и общий ИИ-суперагент.
Нужно ли ставить приложение на телефон?
Нет. CodeRail — веб-интерфейс на порту 8080, поэтому достаточно браузера телефона и адреса https://<ваш-домен>.
Где хранятся ключи Claude и Codex?
На компьютерах, где они установлены, — мост ходит только наружу, ключи на сервер не уезжают. При этом история диалогов хранится на вашем сервере.
Есть ли сквозное шифрование истории?
Нет. Сквозного шифрования нет, история лежит на вашем сервере — учитывайте это при выборе хоста и доступа к нему.
На каком железе пойдёт сервер?
Образ ghcr.io/wiva-hq/coderail собран под amd64 и arm64, то есть подходит и обычный x86-VPS, и ARM-машина. Конкретные требования к памяти сверьтесь с документацией проекта.