How to add a repository that this server will build and publish. Pushing main or beta on a repository owned by agthatch starts a build. app.yaml at the repository root tells the server which targets to run.
agthatch. Pushes for any other owner are ignored.., _, and -. That name is the last segment of agthatch/<name>.rules, placeholder, or caddy-sites. They are reserved. A web deploy for those names is refused.git@github.com:agthatch/<name>.git with the agthatch
main and beta are built. Other branches, tags, and events that are not pushes are ignored.Add a GitHub webhook on the repository:
https://build.brotherlybins.com/. Any path on that host is accepted.application/json.The server answers HTTP 200 when it accepts the push and starts the build. That response does not mean the APK or the web site is ready.
The project is a Flutter app with pubspec.yaml at the repository root. The server runs flutter pub get in the image flutter-builder:latest, then one or both of these commands:
flutter build apk --release
flutter build web --release --target <web.target>
The image's Flutter version is the one every app gets. .fvmrc is not read. The build does not pass --dart-define. A value the app needs at compile time has to already be available to that command, because app.yaml has no field for it.
The checkout on the server is reset to origin/<branch> on every build. Commit the files you want built. Do not commit secrets.
Put app.yaml in the repository root. The server reads a small subset of YAML. It is not a general YAML parser.
android:, web:, or backend:.key: value.# starts a comment.A repository with no app.yaml builds only the Android APK.
android:
kind: flutter
target: lib/main.dart
kind must be flutter. Any other kind stops the build before Android or web runs. When target is set, it must be a relative file path such as lib/main.dart: no leading slash, no .., and no leading dash. The APK command does not receive --target. Flutter builds its default Android target.
The APK is published at:
https://apk.brotherlybins.com/<repository-name>-<branch>.apk
For agthatch/demo-app on main, that is https://apk.brotherlybins.com/demo-app-main.apk.
web:
kind: flutter
target: lib/main.dart
hostname: app.example.com
kind must be flutter. Any other kind stops the build before Android or web runs. target is required and follows the same path rules as the Android target. The web command is flutter build web --release --target <target>.
hostname is the public DNS name for this site. The app repository sets it. app.example.com above is a placeholder; replace it with the name you will serve. The name must contain a dot. An IP address is refused. A name this server already serves is refused, including tv.brotherlybins.com, apk.brotherlybins.com, build.brotherlybins.com, rules.brotherlybins.com, and any hostname already used by another app.
Create the DNS record for that hostname so it reaches this server before the first web deploy. The server does not create DNS records.
If hostname is missing or empty, the web deploy stops before the Flutter web build and before it changes Caddy. The current web release stays in place. When the same file also has an Android target, the APK build still runs, and the web step then fails.
A successful web deploy is served at https://<hostname>/. The server keeps the current release and the previous one. A failed build leaves the current release where it was. Caddy is reloaded only when that app's site file changes. Other sites are not rewritten.
android:
kind: flutter
target: lib/main.dart
web:
kind: flutter
target: lib/main.dart
hostname: app.example.com
Android runs first, then web.
backend:
kind: dart
A backend section is recognized and not deployed. The server does not build an image, publish a port, or start a container from it. The section can stay in the file.
| Field | Required | Meaning |
|---|---|---|
android.kind | When the section exists | flutter |
android.target | No | Relative Dart path. Checked when present. Not passed to the APK build. |
web.kind | When the section exists | flutter |
web.target | For web | Relative Dart path passed to flutter build web --target. |
web.hostname | For web | Public DNS name. You create the DNS record. Omit it and the web deploy publishes nothing. |
backend.* | No | Recorded and not deployed. |
agthatch/<name>, and the name is not reserved.https://build.brotherlybins.com/, the server secret, and push events.main or beta.pubspec.yaml is at the root, and the Flutter release command succeeds in flutter-builder:latest.app.yaml matches the shape on this page.web.hostname is a DNS name you control, and that name reaches this server.