mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-09-08 11:17:17 +02:00
Compare commits
3 Commits
4f8ce598a9
...
0a588023a7
Author | SHA1 | Date | |
---|---|---|---|
0a588023a7 | |||
d2fa90774b | |||
0e72dcbe36 |
@@ -100,6 +100,8 @@ defaults_networks:
|
|||||||
subnet: 192.168.103.192/28
|
subnet: 192.168.103.192/28
|
||||||
web-app-magento:
|
web-app-magento:
|
||||||
subnet: 192.168.103.208/28
|
subnet: 192.168.103.208/28
|
||||||
|
web-app-bridgy-fed:
|
||||||
|
subnet: 192.168.103.224/28
|
||||||
|
|
||||||
# /24 Networks / 254 Usable Clients
|
# /24 Networks / 254 Usable Clients
|
||||||
web-app-bigbluebutton:
|
web-app-bigbluebutton:
|
||||||
|
@@ -74,6 +74,7 @@ ports:
|
|||||||
web-app-chess: 8050
|
web-app-chess: 8050
|
||||||
web-app-bluesky_view: 8051
|
web-app-bluesky_view: 8051
|
||||||
web-app-magento: 8052
|
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
|
web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
|
||||||
public:
|
public:
|
||||||
# The following ports should be changed to 22 on the subdomain via stream mapping
|
# The following ports should be changed to 22 on the subdomain via stream mapping
|
||||||
|
@@ -5,6 +5,7 @@ features:
|
|||||||
central_database: false
|
central_database: false
|
||||||
logout: true
|
logout: true
|
||||||
server:
|
server:
|
||||||
|
config_upstream_url: "https://ip.bsky.app/config"
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
web: "bskyweb.{{ PRIMARY_DOMAIN }}"
|
web: "bskyweb.{{ PRIMARY_DOMAIN }}"
|
||||||
@@ -33,7 +34,7 @@ docker:
|
|||||||
database:
|
database:
|
||||||
enabled: false
|
enabled: false
|
||||||
web:
|
web:
|
||||||
enabled: true # @see https://github.com/bluesky-social/social-app
|
enabled: true # @see https://github.com/bluesky-social/social-app
|
||||||
view:
|
view:
|
||||||
enabled: false
|
enabled: false
|
||||||
pds:
|
pds:
|
||||||
|
@@ -3,6 +3,16 @@
|
|||||||
repo: "https://github.com/bluesky-social/social-app.git"
|
repo: "https://github.com/bluesky-social/social-app.git"
|
||||||
dest: "{{ BLUESKY_SOCIAL_APP_DIR }}"
|
dest: "{{ BLUESKY_SOCIAL_APP_DIR }}"
|
||||||
version: "main"
|
version: "main"
|
||||||
|
force: true
|
||||||
notify:
|
notify:
|
||||||
- docker compose up
|
- docker compose up
|
||||||
- docker compose build
|
- docker compose build
|
||||||
|
|
||||||
|
- name: Force BAPP_CONFIG_URL to same-origin /config
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: "{{ BLUESKY_SOCIAL_APP_DIR }}/src/state/geolocation.tsx"
|
||||||
|
regexp: '^\s*const\s+BAPP_CONFIG_URL\s*=\s*.*$'
|
||||||
|
replace: "const BAPP_CONFIG_URL = '/config'"
|
||||||
|
notify:
|
||||||
|
- docker compose build
|
||||||
|
- docker compose up
|
||||||
|
@@ -15,8 +15,9 @@
|
|||||||
include_role:
|
include_role:
|
||||||
name: sys-stk-front-proxy
|
name: sys-stk-front-proxy
|
||||||
vars:
|
vars:
|
||||||
domain: "{{ BLUESKY_WEB_DOMAIN }}"
|
domain: "{{ BLUESKY_WEB_DOMAIN }}"
|
||||||
http_port: "{{ BLUESKY_WEB_PORT }}"
|
http_port: "{{ BLUESKY_WEB_PORT }}"
|
||||||
|
proxy_extra_configuration: "{{ BLUESKY_FRONT_PROXY_CONTENT }}"
|
||||||
when: BLUESKY_WEB_ENABLED | bool
|
when: BLUESKY_WEB_ENABLED | bool
|
||||||
|
|
||||||
- name: "Include front proxy for {{ BLUESKY_VIEW_DOMAIN }}:{{ BLUESKY_VIEW_PORT }}"
|
- name: "Include front proxy for {{ BLUESKY_VIEW_DOMAIN }}:{{ BLUESKY_VIEW_PORT }}"
|
||||||
|
@@ -1,21 +1,30 @@
|
|||||||
|
# General
|
||||||
PDS_HOSTNAME="{{ BLUESKY_API_DOMAIN }}"
|
PDS_HOSTNAME="{{ BLUESKY_API_DOMAIN }}"
|
||||||
PDS_ADMIN_EMAIL="{{ BLUESKY_ADMIN_EMAIL }}"
|
|
||||||
PDS_SERVICE_DID="did:web:{{ BLUESKY_API_DOMAIN }}"
|
|
||||||
|
|
||||||
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
|
|
||||||
PDS_SERVICE_HANDLE_DOMAINS=".{{ PRIMARY_DOMAIN }}"
|
|
||||||
PDS_JWT_SECRET="{{ BLUESKY_JWT_SECRET }}"
|
|
||||||
PDS_ADMIN_PASSWORD="{{ BLUESKY_ADMIN_PASSWORD }}"
|
|
||||||
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{ BLUESKY_ROTATION_KEY }}"
|
|
||||||
PDS_CRAWLERS=https://bsky.network
|
PDS_CRAWLERS=https://bsky.network
|
||||||
PDS_EMAIL_SMTP_URL=smtps://{{ users['no-reply'].email }}:{{ users['no-reply'].mailu_token }}@{{ SYSTEM_EMAIL.HOST }}:{{ SYSTEM_EMAIL.PORT }}/
|
|
||||||
PDS_EMAIL_FROM_ADDRESS={{ users['no-reply'].email }}
|
|
||||||
LOG_ENABLED={{ MODE_DEBUG | string | lower }}
|
LOG_ENABLED={{ MODE_DEBUG | string | lower }}
|
||||||
PDS_BLOBSTORE_DISK_LOCATION={{ BLUESKY_PDS_BLOBSTORE_LOCATION }}
|
PDS_BLOBSTORE_DISK_LOCATION={{ BLUESKY_PDS_BLOBSTORE_LOCATION }}
|
||||||
PDS_DATA_DIRECTORY={{ BLUESKY_PDS_DATA_DIR }}
|
PDS_DATA_DIRECTORY={{ BLUESKY_PDS_DATA_DIR }}
|
||||||
PDS_BLOB_UPLOAD_LIMIT=52428800
|
PDS_BLOB_UPLOAD_LIMIT=52428800
|
||||||
PDS_DID_PLC_URL=https://plc.directory
|
PDS_DID_PLC_URL=https://plc.directory
|
||||||
|
|
||||||
|
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
|
||||||
|
PDS_SERVICE_HANDLE_DOMAINS=".{{ PRIMARY_DOMAIN }}"
|
||||||
|
PDS_SERVICE_DID="did:web:{{ BLUESKY_API_DOMAIN }}"
|
||||||
|
|
||||||
|
# Email
|
||||||
|
PDS_ADMIN_EMAIL="{{ BLUESKY_ADMIN_EMAIL }}"
|
||||||
|
PDS_EMAIL_SMTP_URL=smtps://{{ users['no-reply'].email }}:{{ users['no-reply'].mailu_token }}@{{ SYSTEM_EMAIL.HOST }}:{{ SYSTEM_EMAIL.PORT }}/
|
||||||
|
PDS_EMAIL_FROM_ADDRESS={{ users['no-reply'].email }}
|
||||||
|
|
||||||
|
# Credentials
|
||||||
|
PDS_JWT_SECRET="{{ BLUESKY_JWT_SECRET }}"
|
||||||
|
PDS_ADMIN_PASSWORD="{{ BLUESKY_ADMIN_PASSWORD }}"
|
||||||
|
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{ BLUESKY_ROTATION_KEY }}"
|
||||||
|
|
||||||
|
# View
|
||||||
PDS_BSKY_APP_VIEW_URL={{ BLUESKY_VIEW_URL }}
|
PDS_BSKY_APP_VIEW_URL={{ BLUESKY_VIEW_URL }}
|
||||||
PDS_BSKY_APP_VIEW_DID={{ BLUESKY_VIEW_DID }}
|
PDS_BSKY_APP_VIEW_DID={{ BLUESKY_VIEW_DID }}
|
||||||
|
|
||||||
|
# Report
|
||||||
PDS_REPORT_SERVICE_URL=https://mod.bsky.app
|
PDS_REPORT_SERVICE_URL=https://mod.bsky.app
|
||||||
PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac
|
PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac
|
||||||
|
16
roles/web-app-bluesky/templates/extra_locations.conf.j2
Normal file
16
roles/web-app-bluesky/templates/extra_locations.conf.j2
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Injected by web-app-bluesky (same pattern as web-app-yourls)
|
||||||
|
# Exposes a same-origin /config to avoid CORS when the social-app fetches config.
|
||||||
|
location = /config {
|
||||||
|
proxy_pass {{ BLUESKY_CONFIG_UPSTREAM_URL }};
|
||||||
|
# Nur Hostname extrahieren:
|
||||||
|
set $up_host "{{ BLUESKY_CONFIG_UPSTREAM_URL | regex_replace('^https?://', '') | regex_replace('/.*$', '') }}";
|
||||||
|
proxy_set_header Host $up_host;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
|
||||||
|
# Make response clearly same-origin for browsers
|
||||||
|
proxy_hide_header Access-Control-Allow-Origin;
|
||||||
|
add_header Access-Control-Allow-Origin $scheme://$host always;
|
||||||
|
add_header Vary Origin always;
|
||||||
|
}
|
@@ -43,3 +43,6 @@ BLUESKY_ROTATION_KEY: "{{ applications | get_app_conf(application_id,
|
|||||||
BLUESKY_ADMIN_EMAIL: "{{ users.administrator.email }}"
|
BLUESKY_ADMIN_EMAIL: "{{ users.administrator.email }}"
|
||||||
BLUESKY_ADMIN_PASSWORD: "{{ users.administrator.password }}"
|
BLUESKY_ADMIN_PASSWORD: "{{ users.administrator.password }}"
|
||||||
|
|
||||||
|
# Front proxy
|
||||||
|
BLUESKY_FRONT_PROXY_CONTENT: "{{ lookup('template', 'extra_locations.conf.j2') }}"
|
||||||
|
BLUESKY_CONFIG_UPSTREAM_URL: "{{ applications | get_app_conf(application_id, 'server.config_upstream_url') }}"
|
||||||
|
25
roles/web-app-bridgy-fed/README.md
Normal file
25
roles/web-app-bridgy-fed/README.md
Normal 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; it’s in-memory unless you mount a volume/configure import/export.
|
34
roles/web-app-bridgy-fed/config/main.yml
Normal file
34
roles/web-app-bridgy-fed/config/main.yml
Normal 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"
|
49
roles/web-app-bridgy-fed/files/Dockerfile
Normal file
49
roles/web-app-bridgy-fed/files/Dockerfile
Normal 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"]
|
22
roles/web-app-bridgy-fed/meta/main.yml
Normal file
22
roles/web-app-bridgy-fed/meta/main.yml
Normal 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: []
|
21
roles/web-app-bridgy-fed/tasks/01_core.yml
Normal file
21
roles/web-app-bridgy-fed/tasks/01_core.yml
Normal 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
|
3
roles/web-app-bridgy-fed/tasks/main.yml
Normal file
3
roles/web-app-bridgy-fed/tasks/main.yml
Normal 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
|
20
roles/web-app-bridgy-fed/templates/Administration.md.j2
Normal file
20
roles/web-app-bridgy-fed/templates/Administration.md.j2
Normal 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.)
|
43
roles/web-app-bridgy-fed/templates/docker-compose.yml.j2
Normal file
43
roles/web-app-bridgy-fed/templates/docker-compose.yml.j2
Normal 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' %}
|
18
roles/web-app-bridgy-fed/templates/env.j2
Normal file
18
roles/web-app-bridgy-fed/templates/env.j2
Normal 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"
|
27
roles/web-app-bridgy-fed/vars/main.yml
Normal file
27
roles/web-app-bridgy-fed/vars/main.yml
Normal 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"
|
@@ -4,7 +4,7 @@
|
|||||||
```bash
|
```bash
|
||||||
cd {{ PATH_DOCKER_COMPOSE_INSTANCES }}magento/
|
cd {{ PATH_DOCKER_COMPOSE_INSTANCES }}magento/
|
||||||
docker compose down
|
docker compose down
|
||||||
docker volume rm magento_data
|
docker volume rm MAGENTO_VOLUME
|
||||||
cd {{ PATH_DOCKER_COMPOSE_INSTANCES }} && rm -vR {{ PATH_DOCKER_COMPOSE_INSTANCES }}magento
|
cd {{ PATH_DOCKER_COMPOSE_INSTANCES }} && rm -vR {{ PATH_DOCKER_COMPOSE_INSTANCES }}magento
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
# ⚙️ Installation & First Run
|
|
||||||
|
|
||||||
## 1) Prepare DNS & Ports
|
|
||||||
Ensure a canonical domain is mapped (e.g. `shop.{{ PRIMARY_DOMAIN }}`) and a free localhost port in `group_vars/all/10_ports.yml`:
|
|
||||||
```
|
|
||||||
web-app-magento: 80xx
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2) Seed Credentials
|
|
||||||
Provide (at minimum) an admin password in your inventory (vault recommended):
|
|
||||||
```yaml
|
|
||||||
applications:
|
|
||||||
web-app-magento:
|
|
||||||
credentials:
|
|
||||||
admin_password: "use-a-strong-secret"
|
|
||||||
```
|
|
||||||
The admin username/email are taken from `users.administrator.*`.
|
|
||||||
|
|
||||||
## 3) Deploy
|
|
||||||
Run the Infinito.Nexus playbook for your host(s). The role will:
|
|
||||||
- Start OpenSearch (single node)
|
|
||||||
- Start MariaDB (if `central_database` is disabled, the app-local DB is used instead)
|
|
||||||
- Start Magento application container
|
|
||||||
- Wire environment via `templates/env.j2`
|
|
||||||
|
|
||||||
## 4) Verify
|
|
||||||
Open your domain (e.g. `https://shop.{{ PRIMARY_DOMAIN }}`) and complete any remaining onboarding steps in the admin panel.
|
|
||||||
|
|
||||||
**Admin Panel:** `{{ domains | get_url('web-app-magento', WEB_PROTOCOL) }}/admin`
|
|
||||||
(Default path can vary; set a custom `ADMINURI` later via `bin/magento setup:config:set` if desired.)
|
|
@@ -1,6 +1,6 @@
|
|||||||
# 🔼 Upgrade
|
# 🔼 Upgrade
|
||||||
|
|
||||||
> Always back up the database and the `magento_data` volume before upgrades.
|
> Always back up the database and the `MAGENTO_VOLUME` volume before upgrades.
|
||||||
|
|
||||||
1. Update images/versions in the application config (`roles/web-app-magento/config/main.yml` or inventory overrides).
|
1. Update images/versions in the application config (`roles/web-app-magento/config/main.yml` or inventory overrides).
|
||||||
2. Recreate containers:
|
2. Recreate containers:
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
# 👤 User Administration
|
|
||||||
|
|
||||||
- Access the admin panel at:
|
|
||||||
`{{ domains | get_url('web-app-magento', WEB_PROTOCOL) }}/admin`
|
|
||||||
*(or your custom admin path if configured)*
|
|
||||||
|
|
||||||
- New admin accounts can be created via the web UI or CLI:
|
|
||||||
```bash
|
|
||||||
docker compose exec -it application bin/magento admin:user:create \
|
|
||||||
--admin-user="john" \
|
|
||||||
--admin-password="SuperSecret_12345" \
|
|
||||||
--admin-email="john@example.com" \
|
|
||||||
--admin-firstname="John" \
|
|
||||||
--admin-lastname="Doe"
|
|
||||||
```
|
|
@@ -19,19 +19,19 @@ server:
|
|||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
application:
|
application:
|
||||||
image: "bitnami/magento"
|
image: "ghcr.io/alexcheng1982/docker-magento2"
|
||||||
version: "latest"
|
version: "2.4.6-p3"
|
||||||
name: "magento"
|
name: "magento"
|
||||||
backup:
|
backup:
|
||||||
no_stop_required: true
|
no_stop_required: true
|
||||||
database:
|
database:
|
||||||
enabled: true # Central DB recommended; if disabled, app-local DB is created
|
enabled: true # Central DB recommended; if disabled, app-local DB is created
|
||||||
redis:
|
redis:
|
||||||
enabled: true
|
enabled: true
|
||||||
search:
|
search:
|
||||||
enabled: true
|
enabled: true
|
||||||
image: "opensearchproject/opensearch"
|
image: "opensearchproject/opensearch"
|
||||||
version: "latest"
|
version: "latest"
|
||||||
name: "magento-opensearch"
|
name: "magento-opensearch"
|
||||||
volumes:
|
volumes:
|
||||||
data: "magento_data"
|
data: "magento_data"
|
||||||
|
@@ -1,6 +1 @@
|
|||||||
credentials:
|
|
||||||
admin_password:
|
|
||||||
description: "Password for the initial Magento admin account"
|
|
||||||
algorithm: "alphanumeric"
|
|
||||||
validation:
|
|
||||||
min_length: 12
|
|
||||||
|
@@ -1,6 +1,32 @@
|
|||||||
- name: "load docker, db/redis/proxy for {{ application_id }}"
|
- name: "load docker, db/redis/proxy for {{ application_id }}"
|
||||||
include_role:
|
include_role:
|
||||||
name: sys-stk-full-stateful
|
name: sys-stk-full-stateful
|
||||||
|
vars:
|
||||||
|
docker_compose_flush_handlers: true
|
||||||
|
|
||||||
- name: flush docker service
|
- name: "Run Magento setup:install (in container)"
|
||||||
meta: flush_handlers
|
command: >
|
||||||
|
docker compose exec -T application bash -lc "
|
||||||
|
cd /var/www/html && bin/magento setup:install \
|
||||||
|
--base-url='{{ MAGENTO_URL }}/' \
|
||||||
|
--db-host=\"$MYSQL_HOST\" \
|
||||||
|
--db-name=\"$MYSQL_DATABASE\" \
|
||||||
|
--db-user=\"$MYSQL_USER\" \
|
||||||
|
--db-password=\"$MYSQL_PASSWORD\" \
|
||||||
|
--search-engine='opensearch' \
|
||||||
|
--opensearch-host=\"$OPENSEARCH_HOST\" \
|
||||||
|
--opensearch-port=\"$OPENSEARCH_PORT_NUMBER\" \
|
||||||
|
--admin-firstname=\"$MAGENTO_ADMIN_FIRSTNAME\" \
|
||||||
|
--admin-lastname=\"$MAGENTO_ADMIN_LASTNAME\" \
|
||||||
|
--admin-email=\"$MAGENTO_ADMIN_EMAIL\" \
|
||||||
|
--admin-user=\"$MAGENTO_ADMIN_USERNAME\" \
|
||||||
|
--admin-password=\"$MAGENTO_ADMIN_PASSWORD\""
|
||||||
|
args:
|
||||||
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
|
register: magento_install
|
||||||
|
changed_when: >
|
||||||
|
(magento_install.stdout is defined and
|
||||||
|
('Magento installation complete' in magento_install.stdout
|
||||||
|
or 'successfully installed' in magento_install.stdout))
|
||||||
|
|
||||||
|
- include_tasks: utils/run_once.yml
|
@@ -2,8 +2,3 @@
|
|||||||
- name: "construct {{ role_name }}"
|
- name: "construct {{ role_name }}"
|
||||||
include_tasks: 01_core.yml
|
include_tasks: 01_core.yml
|
||||||
when: run_once_web_app_magento is not defined
|
when: run_once_web_app_magento is not defined
|
||||||
|
|
||||||
- name: run the docker magento tasks once
|
|
||||||
set_fact:
|
|
||||||
run_once_web_app_magento: true
|
|
||||||
when: run_once_web_app_magento is not defined
|
|
||||||
|
@@ -1,34 +1,33 @@
|
|||||||
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
||||||
|
|
||||||
application:
|
application:
|
||||||
{% set container_port = 8080 %}
|
{% set container_port = 80 %}
|
||||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||||
image: "{{ magento_image }}:{{ magento_version }}"
|
image: "{{ MAGENTO_IMAGE }}:{{ MAGENTO_VERSION }}"
|
||||||
container_name: "{{ magento_name }}"
|
container_name: "{{ MAGENTO_CONTAINER }}"
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
|
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
|
||||||
volumes:
|
volumes:
|
||||||
- "data:/bitnami/magento"
|
- "data:/var/www/html"
|
||||||
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
|
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
|
||||||
depends_on:
|
# search:
|
||||||
- search
|
# condition: service_healthy
|
||||||
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
search:
|
search:
|
||||||
{% set container_port = 9200 %}
|
{% set container_port = 9200 %}
|
||||||
image: "{{ magento_search_image }}:{{ magento_search_version }}"
|
image: "{{ MAGENTO_SEARCH_IMAGE }}:{{ MAGENTO_SEARCH_VERSION }}"
|
||||||
container_name: "{{ magento_search_name }}"
|
container_name: "{{ MAGENTO_SEARCH_NAME }}"
|
||||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||||
environment:
|
environment:
|
||||||
- discovery.type=single-node
|
- discovery.type=single-node
|
||||||
- plugins.security.disabled=true
|
|
||||||
- OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
|
- OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
|
||||||
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
|
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
|
||||||
data:
|
data:
|
||||||
name: {{ magento_data }}
|
name: {{ MAGENTO_VOLUME }}
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
||||||
|
@@ -3,30 +3,32 @@
|
|||||||
# - https://github.com/bitnami/containers/tree/main/bitnami/magento
|
# - https://github.com/bitnami/containers/tree/main/bitnami/magento
|
||||||
|
|
||||||
# Host & URLs
|
# Host & URLs
|
||||||
MAGENTO_HOST="{{ domains | get_domain(application_id) }}"
|
MAGENTO_URL="{{ MAGENTO_URL }}"
|
||||||
MAGENTO_BASE_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}/"
|
MAGENTO_BACKEND_FRONTNAME="admin"
|
||||||
MAGENTO_ENABLE_HTTPS={{ (WEB_PORT == 443) | string | lower }}
|
MAGENTO_USE_SECURE={{ (WEB_PORT == 443) | ternary('1','0') }}
|
||||||
|
MAGENTO_BASE_URL_SECURE={{ (WEB_PORT == 443) | ternary('1','0') }}
|
||||||
|
MAGENTO_USE_SECURE_ADMIN={{ (WEB_PORT == 443) | ternary('1','0') }}
|
||||||
|
|
||||||
# Admin (seed from global administrator)
|
# Admin (seed from global administrator)
|
||||||
MAGENTO_USERNAME="{{ users.administrator.username }}"
|
MAGENTO_ADMIN_USERNAME="{{ users.administrator.username }}"
|
||||||
MAGENTO_PASSWORD="{{ applications | get_app_conf(application_id, 'credentials.admin_password') }}"
|
MAGENTO_ADMIN_PASSWORD="{{ users.administrator.password }}"
|
||||||
MAGENTO_EMAIL="{{ users.administrator.email }}"
|
MAGENTO_ADMIN_EMAIL="{{ users.administrator.email }}"
|
||||||
MAGENTO_FIRST_NAME="{{ users.administrator.firstname | default('Admin') }}"
|
MAGENTO_ADMIN_FIRSTNAME="{{ users.administrator.firstname | default('Admin') }}"
|
||||||
MAGENTO_LAST_NAME="{{ users.administrator.lastname | default('User') }}"
|
MAGENTO_ADMIN_LASTNAME="{{ users.administrator.lastname | default('User') }}"
|
||||||
|
|
||||||
# Database (central DB preferred)
|
# Database (central DB preferred)
|
||||||
MARIADB_HOST="{{ database_host }}"
|
MYSQL_HOST="{{ database_host }}"
|
||||||
MARIADB_PORT_NUMBER="{{ database_port }}"
|
MYSQL_PORT="{{ database_port }}"
|
||||||
MAGENTO_DATABASE_USER="{{ database_username }}"
|
MYSQL_USER="{{ database_username }}"
|
||||||
MAGENTO_DATABASE_PASSWORD="{{ database_password }}"
|
MYSQL_PASSWORD="{{ database_password }}"
|
||||||
MAGENTO_DATABASE_NAME="{{ database_name }}"
|
MYSQL_DATABASE="{{ database_name }}"
|
||||||
|
|
||||||
# Search (Magento 2.4+)
|
# Search (Magento 2.4+)
|
||||||
MAGENTO_SEARCH_ENGINE="opensearch"
|
|
||||||
OPENSEARCH_HOST="search"
|
OPENSEARCH_HOST="search"
|
||||||
OPENSEARCH_PORT_NUMBER="9200"
|
OPENSEARCH_PORT_NUMBER="9200"
|
||||||
|
OPENSEARCH_INITIAL_ADMIN_PASSWORD="{{ users.administrator.password }}"
|
||||||
|
|
||||||
# SMTP
|
# SMTP (post-install you’ll wire these in Magento admin or env.php)
|
||||||
SMTP_HOST="{{ SYSTEM_EMAIL.HOST }}"
|
SMTP_HOST="{{ SYSTEM_EMAIL.HOST }}"
|
||||||
SMTP_PORT="{{ SYSTEM_EMAIL.PORT }}"
|
SMTP_PORT="{{ SYSTEM_EMAIL.PORT }}"
|
||||||
SMTP_USER="{{ users['no-reply'].email }}"
|
SMTP_USER="{{ users['no-reply'].email }}"
|
||||||
@@ -34,6 +36,6 @@ SMTP_PASSWORD="{{ users['no-reply'].mailu_token }}"
|
|||||||
SMTP_PROTOCOL={{ SYSTEM_EMAIL.TLS | ternary('tls','ssl') }}
|
SMTP_PROTOCOL={{ SYSTEM_EMAIL.TLS | ternary('tls','ssl') }}
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
ALLOW_EMPTY_PASSWORD="no"
|
PHP_MEMORY_LIMIT="768M"
|
||||||
BITNAMI_DEBUG="false"
|
|
||||||
PHP_MEMORY_LIMIT="1024M"
|
APACHE_SERVERNAME={{ MAGENTO_DOMAIN }}
|
@@ -3,15 +3,14 @@ application_id: "web-app-magento"
|
|||||||
database_type: "mariadb"
|
database_type: "mariadb"
|
||||||
|
|
||||||
# Magento (application container)
|
# Magento (application container)
|
||||||
magento_version: "{{ applications | get_app_conf(application_id, 'docker.services.application.version', True) | default('latest') }}"
|
MAGENTO_DOMAIN: "{{ domains | get_domain(application_id) }}"
|
||||||
magento_image: "{{ applications | get_app_conf(application_id, 'docker.services.application.image', True) | default('bitnami/magento') }}"
|
MAGENTO_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||||
magento_name: "{{ applications | get_app_conf(application_id, 'docker.services.application.name', True) | default('magento') }}"
|
MAGENTO_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.application.version') }}"
|
||||||
magento_data: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) | default('magento_data') }}"
|
MAGENTO_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
|
||||||
|
MAGENTO_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
|
||||||
|
MAGENTO_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
|
||||||
|
|
||||||
# Search (OpenSearch)
|
# Search (OpenSearch)
|
||||||
magento_search_version: "{{ applications | get_app_conf(application_id, 'docker.services.search.version', True) | default('latest') }}"
|
MAGENTO_SEARCH_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.search.version') }}"
|
||||||
magento_search_image: "{{ applications | get_app_conf(application_id, 'docker.services.search.image', True) | default('opensearchproject/opensearch') }}"
|
MAGENTO_SEARCH_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.search.image') }}"
|
||||||
magento_search_name: "{{ applications | get_app_conf(application_id, 'docker.services.search.name', True) | default('magento-opensearch') }}"
|
MAGENTO_SEARCH_NAME: "{{ applications | get_app_conf(application_id, 'docker.services.search.name') }}"
|
||||||
|
|
||||||
# Docker helpers
|
|
||||||
docker_compose_flush_handlers: true
|
|
||||||
|
Reference in New Issue
Block a user