Added fediverse bridge draft

This commit is contained in:
2025-09-04 02:26:27 +02:00
parent 0e72dcbe36
commit d2fa90774b
12 changed files with 265 additions and 0 deletions

View File

@@ -100,6 +100,8 @@ defaults_networks:
subnet: 192.168.103.192/28
web-app-magento:
subnet: 192.168.103.208/28
web-app-bridgy-fed:
subnet: 192.168.103.224/28
# /24 Networks / 254 Usable Clients
web-app-bigbluebutton:

View File

@@ -74,6 +74,7 @@ ports:
web-app-chess: 8050
web-app-bluesky_view: 8051
web-app-magento: 8052
web-app-bridgy-fed: 8053
web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
public:
# The following ports should be changed to 22 on the subdomain via stream mapping

View File

@@ -0,0 +1,25 @@
# Bridgy Fed
## Description
Bridgy Fed bridges ActivityPub (Fediverse), ATProto/Bluesky, and IndieWeb (webmentions/mf2). It mirrors identities and interactions across networks.
## Overview
This role builds and runs Bridgy Fed as a Docker container and (optionally) starts a Datastore-mode Firestore emulator as a sidecar. It exposes HTTP locally for a front proxy.
Upstream docs & dev notes:
- User & developer docs: https://fed.brid.gy and https://bridgy-fed.readthedocs.io/
- Source: https://github.com/snarfed/bridgy-fed
- Local run (reference): `flask run -p 8080` with APPVIEW_HOST/PLC_HOST/BGS_HOST/PDS_HOST set, and Datastore emulator envs
## Features
- Dockerized Flask app (gunicorn)
- Optional Firestore emulator (Datastore mode) sidecar
- Front proxy integration via `sys-stk-front-proxy`
## Quick start
1) Set domains and ports in inventory.
2) Enable/disable the emulator in `config/main.yml`.
3) Run the role; your front proxy will publish the app.
## Notes
- Emulator is **not** for production; its in-memory unless you mount a volume/configure import/export.

View File

@@ -0,0 +1,34 @@
features:
matomo: true
css: true
desktop: true
central_database: false
logout: false
oidc: false
server:
domains:
canonical:
- "bridgyfed.{{ PRIMARY_DOMAIN }}"
csp:
whitelist: {}
flags: {}
docker:
services:
database:
enabled: false
emulator:
enabled: true
image: 'gcr.io/google.com/cloudsdktool/google-cloud-cli:latest'
application:
image: "python"
version: "3.12-bookworm"
name: "web-app-bridgy-fed"
rbac:
roles: {}
source:
repo: "https://github.com/snarfed/bridgy-fed.git"
ref: "main"

View File

@@ -0,0 +1,49 @@
# Runtime image for Bridgy Fed (Flask) with a build step that clones upstream
ARG PY_BASE="python:3.12-bookworm"
FROM ${PY_BASE} AS build
ARG BRIDGY_REPO_URL
ARG BRIDGY_REPO_REF
# System deps: git, build tools, curl for healthchecks, and gunicorn
RUN apt-get update && apt-get install -y --no-install-recommends \
git build-essential curl ca-certificates && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN git clone --depth=1 --branch "${BRIDGY_REPO_REF}" "${BRIDGY_REPO_URL}" ./
# Python deps
RUN pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
# Create oauth_dropins static symlink (upstream expects this)
RUN python - <<'PY'\n\
import oauth_dropins, pathlib, os\n\
target = pathlib.Path(oauth_dropins.__file__).parent / 'static'\n\
link = pathlib.Path('/app/oauth_dropins_static')\n\
try:\n\
if link.exists() or link.is_symlink():\n\
link.unlink()\n\
os.symlink(str(target), str(link))\n\
except FileExistsError:\n\
pass\n\
print('Symlinked oauth_dropins_static ->', target)\n\
PY
# Final stage
FROM ${PY_BASE}
ARG CONTAINER_PORT
ENV PORT=${CONTAINER_PORT:-8080}
WORKDIR /app
COPY --from=build /app /app
# Non-root good practice
RUN useradd -r -m -d /nonroot appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE ${PORT}
# Upstream flask app entry: 'flask_app:app'
CMD ["sh", "-lc", "exec gunicorn -w 2 -k gthread -b 0.0.0.0:${PORT} flask_app:app"]

View File

@@ -0,0 +1,22 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Bridgy Fed: bridge between ActivityPub (Fediverse), ATProto/Bluesky and IndieWeb."
license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
galaxy_tags:
- activitypub
- bluesky
- atproto
- fediverse
- bridge
repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://fed.brid.gy/docs"
logo:
class: "fa-solid fa-bridge"
dependencies: []

View File

@@ -0,0 +1,21 @@
- name: "Load docker and front proxy for {{ application_id }}"
include_role:
name: sys-stk-full-stateless
- name: "Include front proxy for {{ container_hostname }}:{{ ports.localhost.http[application_id] }}"
include_role:
name: sys-stk-front-proxy
vars:
domain: "{{ container_hostname }}"
http_port: "{{ ports.localhost.http[application_id] }}"
- name: "Provide Dockerfile"
copy:
src: "Dockerfile"
dest: "{{ docker_compose.directories.instance }}/Dockerfile"
notify:
- docker compose build
- name: "Run once marker"
set_fact:
run_once_web_app_bridgy_fed: true

View File

@@ -0,0 +1,3 @@
- name: "Include core routines for '{{ application_id }}'"
include_tasks: "01_core.yml"
when: run_once_web_app_bridgy_fed is not defined

View File

@@ -0,0 +1,20 @@
# Administration
## Local dev shell (inside container)
```bash
docker compose exec application bash
```
## Logs
```bash
docker compose logs -f application
docker compose logs -f emulator # if enabled
```
## Notes
- Upstream dev run example:
```bash
export APPVIEW_HOST=api.bsky.app PLC_HOST=plc.directory BGS_HOST=bsky.network PDS_HOST=atproto.brid.gy
flask --debug run -p 8080
```
(We run via gunicorn in this role.)

View File

@@ -0,0 +1,43 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
build:
context: .
dockerfile: Dockerfile
args:
BRIDGY_REPO_URL: "{{ BRIDGY_REPO_URL }}"
BRIDGY_REPO_REF: "{{ BRIDGY_REPO_REF }}"
CONTAINER_PORT: "{{ container_port | string }}"
image: "{{ BRIDGY_IMAGE }}"
container_name: "{{ BRIDGY_CONTAINER }}"
hostname: "{{ container_hostname }}"
env_file:
- "{{ docker_compose.files.env }}"
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
depends_on:
{% if EMULATOR_ENABLED | bool %}
- emulator
{% endif %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% if EMULATOR_ENABLED | bool %}
emulator:
image: "{{ EMULATOR_IMAGE }}"
container_name: "{{ BRIDGY_CONTAINER }}_emulator"
command: >
gcloud emulators firestore start
--host-port=0.0.0.0:{{ EMULATOR_PORT }}
--database-mode=datastore-mode
--quiet
ports:
- "127.0.0.1:{{ EMULATOR_PORT }}:{{ EMULATOR_PORT }}"
environment:
- CLOUDSDK_CORE_DISABLE_PROMPTS=1
restart: unless-stopped
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% endif %}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -0,0 +1,18 @@
# Flask / Gunicorn basics
FLASK_ENV="{{ ENVIRONMENT | default('production') }}"
PORT="{{ container_port }}"
BRIDGY_ADMIN_EMAIL="{{ BRIDGY_ADMIN_EMAIL }}"
# Bridgy Fed upstream knobs (see README @ GitHub)
APPVIEW_HOST="{{ APPVIEW_HOST }}"
PLC_HOST="{{ PLC_HOST }}"
BGS_HOST="{{ BGS_HOST }}"
PDS_HOST="{{ PDS_HOST }}"
# Datastore emulator (Datastore-mode Firestore). If sidecar enabled, point here.
GOOGLE_CLOUD_PROJECT="{{ EMULATOR_PROJECT_ID }}"
DATASTORE_EMULATOR_HOST="{{ EMULATOR_ENABLED | ternary(EMULATOR_HOST_INTERNAL, '') }}"
# DATASTORE_DATASET not needed when GOOGLE_CLOUD_PROJECT is set
# Optional:
# GUNICORN_CMD_ARGS="--log-level info"

View File

@@ -0,0 +1,27 @@
# General
application_id: "web-app-bridgy-fed"
# App container
BRIDGY_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
BRIDGY_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
#BRIDGY_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.application.version')}}"
container_port: 8080
container_hostname: "{{ domains | get_domain(application_id) }}"
BRIDGY_ADMIN_EMAIL: "{{ users.administrator.email }}"
# Source
BRIDGY_REPO_URL: "{{ applications | get_app_conf(application_id, 'source.repo') }}"
BRIDGY_REPO_REF: "{{ applications | get_app_conf(application_id, 'source.ref') }}"
# Emulator sidecar (Datastore-mode Firestore)
EMULATOR_ENABLED: "{{ applications | get_app_conf(application_id, 'docker.services.emulator.enabled') }}"
EMULATOR_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.emulator.image') }}"
EMULATOR_PORT: 8089
EMULATOR_HOST_INTERNAL: "emulator:8089"
EMULATOR_PROJECT_ID: "bridgy-federated-local"
# Runtime env defaults for Bridgy Fed (see upstream README)
APPVIEW_HOST: "api.bsky.app"
PLC_HOST: "plc.directory"
BGS_HOST: "bsky.network"
PDS_HOST: "atproto.brid.gy"