Eternaltwin

Home

Server

The software versions, host name and addresses below describe the production machine and cannot be checked from this repository: they were last confirmed on 2024-12-26, against the eternaltwin/config repository. Everything else on this page was verified against the source tree on 2026-09-16.

Environment

NameVersion
JRE17
Nginx1.22
Node.js>= 20.11.0, LTS recommended
PHP8.3
Postgres17.2
Ruby3.0

The Node.js requirement is the one enforced by this repository: engines.node in the root package.json asks for >=20.11.0. The other rows describe what is installed on the machine.

Running Eternaltwin itself only requires Node.js, for the frontend server, and Postgres, for the data stores: the backend ships as a self-contained executable and needs no toolchain at run time. The JVM, PHP and Ruby code of this repository is made of client libraries and examples (clients/kotlin, clients/ruby, sdk/php, examples/); they are built and tested by the GitLab CI, never by the server. If the JRE, PHP and Ruby rows above are still needed, it is for something outside this repository.

Databases

  • Postgres holds the application data. It is the default store in the Production and Test configuration profiles, and the only one used in production.
  • SQLite backs three stores only (app_store, mailer_store, twinoid_store), and is meant for local development.
  • ClickHouse is not an application store, and nothing in this repository talks to it. Eternaltwin emits OpenTelemetry; whether a ClickHouse-backed collector sits downstream on this host is decided outside this repository.

Network

  • Internal name: pousty.eternaltwin.org
  • IPv4: 162.55.107.242
  • IPv6: 2a01:4f8:2191:302a::2

Services and ports

Eternaltwin runs as two processes.

The backend is the eternaltwin executable, started with eternaltwin backend. It binds the address of [backend] listen, which defaults to [::]:50320; [backend] port, when set, overrides only the port of that address. It serves the REST API under /api/v1, the action handlers under /actions, the OAuth endpoints, and the OTLP endpoints /v1/logs and /v1/traces, all on that single port.

The frontend is the Node server of packages/website, started with node ./dist/eternaltwin/main/main.mjs. It does not read eternaltwin.toml: it takes its own settings from the command line, either as a JSON document passed to --config or through --backend-secret, --backend-secret-url, --backend-port, --port and --url. Its default port is 50321 and it expects the backend on port 50320.

The [frontend] section of eternaltwin.toml configures the backend, not the Node server: [frontend] port sets [frontend] uri, from which the backend derives the OAuth callback endpoints it registers with Discord and GitLab.

Outside production the Node server proxies /api/v1/, /oauth/, /actions/ and /v1/traces/ to the backend itself, so that a developer only has to open the frontend port. This proxy is disabled when the frontend runs in production mode: there, routing those paths to the backend is the job of the reverse proxy in front of both processes.

Deployment

The backend executable is cross-compiled by the GitLab CI, not built on the server. The cargo xtask precompile <target> task runs cross build --bin eternaltwin --release for a target, and writes the executable next to a meta.json recording its version, under dist/<target>/. Four targets are precompiled on a tag: x86_64-apple-darwin, x86_64-pc-windows-gnu, x86_64-unknown-linux-gnu and x86_64-unknown-linux-musl.

The release CI job then runs cargo xtask publish exe, which uploads each executable as a generic package of the eternaltwin/eternaltwin project and attaches it to the release of the v<version> tag, under the name eternaltwin-<target>.

The frontend is built from the repository with yarn run build:production, which produces the Angular application and the Node server under packages/website/dist/.

Configuration

The server is initialized from a custom Arch VM image. The application configuration is then loaded from the repo eternaltwin/config.