# Run the binary or build from source

> Run a Frame server release binary yourself, build frame-server from source with Go, install your own build as the service, or try Frame locally in dev mode.

Source: https://crow.sg/apps/frame/docs/install-binary/

`frame-server` is one static Go binary with SQLite built in. With no configuration at all it runs a working server on plain HTTP port 8080, with its data in `./frame-data`. The [Linux installer](https://crow.sg/apps/frame/docs/install-systemd/) and [Docker](https://crow.sg/apps/frame/docs/install-docker/) wrap the same binary; use this page when you want to run it your own way.

## Run a release binary

Every [release](https://github.com/Crow-Tech-Pte-Ltd/frame/releases/latest) has `frame-server-linux-amd64`, `frame-server-linux-arm64` and `frame-server-linux-armv7`, plus a `SHA256SUMS` file. Download the one for your CPU and check it before you run it:

```sh
curl -fsSLO https://github.com/Crow-Tech-Pte-Ltd/frame/releases/latest/download/frame-server-linux-amd64
curl -fsSLO https://github.com/Crow-Tech-Pte-Ltd/frame/releases/latest/download/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS     # must say OK
chmod +x frame-server-linux-amd64
./frame-server-linux-amd64 version
```

Settings come from environment variables, optionally loaded from a `KEY=value` file passed with `--config`; real environment variables override the file. Start from the annotated [`frame.conf.example`](https://github.com/Crow-Tech-Pte-Ltd/frame/blob/main/deploy/frame.conf.example) and the [configuration reference](https://crow.sg/apps/frame/docs/configuration/):

```sh
./frame-server-linux-amd64 --config frame.conf     # same as: frame-server serve --config frame.conf
```

Set at least `FRAME_PUBLIC_URL`, and `FRAME_DATA_DIR` if the data shouldn't live in `./frame-data`. Run it as an unprivileged user that owns the data directory, and keep it running across reboots yourself, or let the installer do that for you with `--binary` (below). The admin commands are subcommands of the same binary, such as `frame-server admin setup-link`; run them as the user that owns the data.

> [!NOTE] The checksum isn't a signature
> `SHA256SUMS` comes from the same GitHub release, so it catches corrupted or altered downloads, not a compromised release.

## Build from source

You need Go 1.26 (see `server/go.mod`; with the default `GOTOOLCHAIN=auto`, an older Go downloads the pinned toolchain). The web admin panel is prebuilt into the source tree, so `go build` needs neither Node nor Bun.

```sh
git clone https://github.com/Crow-Tech-Pte-Ltd/frame.git
cd frame/server
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "-s -w -X main.version=0.1.0" -o bin/frame-server-linux-arm64 ./cmd/frame-server
```

Change `GOARCH` (and the output name) for your machine. To run your build as the hardened systemd service, install it with the installer from the same checkout, which takes the unit, the admin helper and the example config from `deploy/`:

```sh
sudo sh ../deploy/install.sh --binary bin/frame-server-linux-arm64
```

With Docker, build the image from the checkout instead: see [Build the image yourself](https://crow.sg/apps/frame/docs/install-docker/#build-yourself).

## Try it locally

From a source checkout, dev mode starts a throwaway server with demo data:

```sh
cd frame/server
go run ./cmd/frame-server dev
```

It listens on `0.0.0.0:8787`, stores its data in `server/.devdata/`, opens registration, turns push off and seeds three users who are all friends: `alice`, `bob` and `carol`, password `password123`. `alice` is an admin of the web panel at `http://localhost:8787/admin/`. Delete `.devdata` to start over. Don't use dev mode for a real server.

Pointing an app at a test server:

- **Android emulator:** `http://10.0.2.2:8787` (or `:8080` for a normal server). Inside the emulator, `10.0.2.2` is the computer running it.
- **iOS simulator:** `http://localhost:8787` works.
- **A real phone on the same Wi-Fi:** your computer's LAN address, such as `http://192.168.1.20:8080`. The firewall must allow the port, and `FRAME_LISTEN` must not be `127.0.0.1`.

The apps accept plain `http://` only for localhost and private LAN addresses. Anything on the internet needs HTTPS.
