Compare commits

...
2 Commits
Author SHA1 Message Date
Veillax 7994ad492c more stuff
CI / test (push) Successful in 1m16s
Release / image (push) Successful in 3m42s
2026-10-27 03:41:35 -06:00
VeillaxandClaude Sonnet 5.5 b5d52b441a Add a release workflow that pushes the container image on a new tag
Release / image (push) Successful in 3m37s
Also lets CI fetch Reef from this server, as the other sharks repositories do.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 03:20:55 -06:00
3 changed files with 144 additions and 1 deletions

No files matched your search

+7
View File
@@ -8,6 +8,8 @@ on:
jobs:
test:
runs-on: ubuntu-latest
env:
GOPRIVATE: git.veillax.com
steps:
- uses: actions/checkout@v4
@@ -15,6 +17,11 @@ jobs:
with:
go-version-file: go.mod
# Go fetches Reef straight from this server. Harmless for public repositories and
# what makes private ones work.
- name: Let Go fetch modules from this server
run: git config --global url."https://x-access-token:${{ secrets.GITHUB_TOKEN }}@git.veillax.com/".insteadOf "https://git.veillax.com/"
- name: Formatting
run: |
unformatted=$(gofmt -l cmd internal)
+59
View File
@@ -0,0 +1,59 @@
name: Release
# Push a tag such as v0.1.0 to build and publish the container image:
# git tag -a v0.1.0 -m "sandbar v0.1.0" && git push origin v0.1.0
on:
push:
tags: ['v*']
jobs:
image:
runs-on: ubuntu-latest
env:
GOPRIVATE: git.veillax.com
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
# Go fetches Reef straight from this server. Harmless for public repositories and
# what makes private ones work.
- name: Let Go fetch modules from this server
run: git config --global url."https://x-access-token:${{ secrets.GITHUB_TOKEN }}@git.veillax.com/".insteadOf "https://git.veillax.com/"
- name: Test
run: |
go vet ./...
go test ./...
# The Dockerfile packages these binaries, so the arm64 image needs no emulation.
- name: Build the binaries
run: |
for a in amd64 arm64; do
mkdir -p dist/bin/linux_$a
CGO_ENABLED=0 GOOS=linux GOARCH=$a go build -trimpath \
-ldflags "-s -w -X main.version=${GITHUB_REF_NAME}" \
-o dist/bin/linux_$a/sandbar ./cmd/sandbar
done
# Optional secret REGISTRY_TOKEN (and variable REGISTRY_USER): an access token with
# package write permission, for servers where the job token can't push.
- name: Build and push the container image
env:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN || secrets.GITHUB_TOKEN }}
REGISTRY_USER: ${{ vars.REGISTRY_USER || github.actor }}
run: |
host=${GITHUB_SERVER_URL#*://}
owner=$(echo "$GITHUB_REPOSITORY_OWNER" | tr 'A-Z' 'a-z')
image="$host/$owner/sandbar"
echo "$REGISTRY_TOKEN" | docker login "$host" -u "$REGISTRY_USER" --password-stdin
# a container-driver builder can build several architectures in one go
docker buildx create --name release --driver docker-container --use >/dev/null 2>&1 || docker buildx use release
tags="-t $image:$GITHUB_REF_NAME"
case "$GITHUB_REF_NAME" in
*-*) ;; # pre-releases (v1.0.0-rc1) don't move :latest
*) tags="$tags -t $image:latest" ;;
esac
docker buildx build --platform linux/amd64,linux/arm64 $tags --push .
+78 -1
View File
@@ -29,7 +29,84 @@ bin/sandbar -listen :8090 -url https://sandbar.example.com
Open `http://localhost:8090` and create the first administrator. Or set `SANDBAR_ADMIN_EMAIL` and
`SANDBAR_ADMIN_PASSWORD` in `.env` to create it at startup.
Docker: `docker run -p 8090:8090 -v sandbar-data:/data -e SANDBAR_MASTER_KEY=... sandbar`.
## Deploying
### Docker
Pushing a version tag publishes a multi-architecture (amd64 and arm64) image to the registry on the same server as
the repository, as `git.veillax.com/veillax/sandbar:<version>` and `:latest`. Generate a master key once with
`docker run --rm git.veillax.com/veillax/sandbar -genkey`, then keep it in a `.env` file next to this compose file:
```yaml
services:
sandbar:
image: git.veillax.com/veillax/sandbar:latest
restart: unless-stopped
ports:
- "127.0.0.1:8090:8090"
env_file: .env
environment:
SANDBAR_URL: https://sandbar.example.com
volumes:
- sandbar-data:/data
volumes:
sandbar-data:
```
```
docker compose up -d
```
- The container runs as user 65532 and keeps its database in `/data`. Use a named volume as above. If you bind-mount
a folder instead, make it writable by 65532 (`chown 65532:65532 ./data`).
- Set `SANDBAR_MASTER_KEY` yourself. Without it a key is generated inside `/data`, next to the database it protects.
- To build the image locally, see the comment at the top of `Dockerfile`.
- Update with `docker compose pull && docker compose up -d`. Your data stays in the volume. Copy the data folder
before upgrading, since there is no migration tooling yet.
### Binary
Build `sandbar` (`go build -o bin/ ./cmd/sandbar`; releases only publish the container image), copy it to the server with a `.env` file, and run it
under a service manager. A minimal systemd unit:
```ini
[Unit]
Description=Sandbar
After=network-online.target
[Service]
User=sandbar
WorkingDirectory=/var/lib/sandbar
ExecStart=/usr/local/bin/sandbar -listen 127.0.0.1:8090 -env /etc/sandbar/.env
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
Put `SANDBAR_DATA=/var/lib/sandbar` in the env file and make `/etc/sandbar/.env` readable only by the `sandbar` user.
### HTTPS and a reverse proxy
Sandbar serves plain HTTP, so put a reverse proxy in front of it and set `SANDBAR_URL` to the public address, since
links in notifications use it. Caddy needs one line:
```
sandbar.example.com {
reverse_proxy 127.0.0.1:8090
}
```
With nginx, turn off response buffering for the live topic feeds (`/<topic>/sse` and `/<topic>/json`), or
subscribers see messages late: `proxy_buffering off; proxy_read_timeout 1h;`.
### After the first start
1. Open the address and create the administrator, or set `SANDBAR_ADMIN_EMAIL` and `SANDBAR_ADMIN_PASSWORD` first.
2. Add an email or webhook channel and use its test button, so you know alerts will reach you.
3. Create an API key on the Account page for scripts and monitoring agents.
4. Set up backups (see Database below), including the master key, which must be stored apart from the data.
## How the pieces fit