A roles/containers/akkoma/README.org => roles/containers/akkoma/README.org +20 -0
@@ 0,0 1,20 @@
+* /roles/containers/akkoma
+
+[[https://akkoma.dev][Akkoma]] module.
+
+Before using this,
+you probably want to set/edit the following variables
+in your ~secret.yml~ (or your unencrypted config):
+#+begin_src yaml
+akkoma_postgres_user: "akkoma"
+akkoma_postgres_pass: "akkoma"
+akkoma_instance_name: "Akkoma"
+akkoma_admin_email: "admin@{{ domain }}"
+akkoma_notify_email: "notify@{{ domain }}"
+akkoma_allow_index: "y"
+akkoma_strip_uploads: "y"
+akkoma_anonymize_uploads: "n"
+akkoma_dedup_uploads: "n"
+akkoma_admin_nickname: "{{ username }}"
+akkoma_admin_password: "changeme"
+#+end_src
A roles/containers/akkoma/defaults/main.yml => roles/containers/akkoma/defaults/main.yml +15 -0
@@ 0,0 1,15 @@
+---
+akkoma_project_dir: social
+akkoma_port: "4880"
+akkoma_domain: "{{ akkoma_project_dir }}.{{ domain }}"
+akkoma_postgres_user: "akkoma"
+akkoma_postgres_pass: "akkoma"
+akkoma_instance_name: "Akkoma"
+akkoma_admin_email: "admin@{{ domain }}"
+akkoma_notify_email: "notify@{{ domain }}"
+akkoma_allow_index: "y"
+akkoma_strip_uploads: "y"
+akkoma_anonymize_uploads: "n"
+akkoma_dedup_uploads: "n"
+akkoma_admin_nickname: "{{ username }}"
+akkoma_admin_password: "changeme"
A roles/containers/akkoma/tasks/caddy.yml => roles/containers/akkoma/tasks/caddy.yml +26 -0
@@ 0,0 1,26 @@
+---
+- name: Make sure akkoma-caddy reverse proxy config exists
+ become: true
+ vars:
+ project_domain: "{{ akkoma_domain }}"
+ project_port: "{{ akkoma_port }}"
+ ansible.builtin.template:
+ src: ../../../network/caddy/templates/reverse-proxy.template
+ mode: "0644"
+ dest: /etc/caddy/akkoma
+ validate: caddy validate --adapter caddyfile --config %s
+
+- name: Make sure caddy links to the akkoma config
+ become: true
+ ansible.builtin.lineinfile:
+ path: /etc/caddy/Caddyfile
+ search_string: ^import /etc/caddy/akkoma
+ mode: "0644"
+ line: import /etc/caddy/akkoma
+ validate: caddy validate --adapter caddyfile --config %s
+
+- name: Restart caddy
+ become: true
+ ansible.builtin.service:
+ name: caddy
+ state: restarted
A roles/containers/akkoma/tasks/main.yml => roles/containers/akkoma/tasks/main.yml +5 -0
@@ 0,0 1,5 @@
+---
+- name: Setup akkoma docker images
+ ansible.builtin.include_tasks: setup.yml
+- name: Setup akkoma reverse proxy
+ ansible.builtin.include_tasks: caddy.yml
A roles/containers/akkoma/tasks/setup.yml => roles/containers/akkoma/tasks/setup.yml +83 -0
@@ 0,0 1,83 @@
+---
+- name: Ensure akkoma-project-dir exists
+ become: true
+ ansible.builtin.file:
+ path: "{{ container_dir }}/{{ akkoma_project_dir }}"
+ state: directory
+ recurse: true
+
+# Setup docker images
+- name: Setup akkoma db
+ community.docker.docker_container:
+ name: akkoma_db
+ restart_policy: unless-stopped
+ image: docker.io/postgres:12.2-alpine
+ volumes:
+ - "{{ container_dir }}/{{ akkoma_project_dir }}/db:\
+ /var/lib/postgresql/data"
+ env:
+ POSTGRES_PASSWORD: "{{ akkoma_postgres_pass }}"
+ POSTGRES_USER: "{{ akkoma_postgres_user }}"
+ POSTGRES_DB: akkoma
+
+- name: Setup akkoma container
+ community.docker.docker_container:
+ name: akkoma
+ restart_policy: unless-stopped
+ image: codeberg.org/comcloudway/akkoma-basic-alpine:v3.10.2-r1
+ ports:
+ - "{{ akkoma_port }}:4000"
+ volumes:
+ - "{{ container_dir }}/{{ akkoma_project_dir }}/config:/akkoma/config"
+ - "{{ container_dir }}/{{ akkoma_project_dir }}/static:/akkoma/static"
+ - "{{ container_dir }}/{{ akkoma_project_dir }}/uploads:/akkoma/uploads"
+ links:
+ - akkoma_db
+ env:
+ DB_HOST: "akkoma_db"
+ DB_USER: "{{ akkoma_postgres_user }}"
+ DB_NAME: "akkoma"
+ DB_PASS: "{{ akkoma_postgres_pass }}"
+ INSTANCE_DOMAIN: "{{ akkoma_domain }}"
+ INSTANCE_NAME: "{{ akkoma_instance_name }}"
+ INSTANCE_ADMIN_EMAIL: "{{ akkoma_admin_email }}"
+ INSTANCE_NOTIFY_EMAIL: "{{ akkoma_notify_email }}"
+ INSTANCE_INDEX: "{{ akkoma_allow_index }}"
+ STRIP_UPLOADS: "{{ akkoma_strip_uploads }}"
+ ANONYMIZE_UPLOADS: "{{ akkoma_anonymize_uploads }}"
+ DEDUPLICATE_UPLOADS: "{{ akkoma_dedup_uploads }}"
+
+- name: Wait for akkoma to be up
+ ansible.builtin.wait_for:
+ host: 0.0.0.0
+ port: "{{ akkoma_port }}"
+ delay: 1
+
+- name: Installing a frontends
+ community.docker.docker_container_exec:
+ container: akkoma
+ chdir: "/akkoma"
+ argv:
+ - "/akkoma/bin/pleroma_ctl"
+ - "frontend"
+ - "install"
+ - "{{ item }}"
+ - "--ref stable"
+ loop:
+ - "pleroma-fe"
+ - "admin-fe"
+
+- name: Creating an admin user
+ community.docker.docker_container_exec:
+ container: akkoma
+ chdir: "/akkoma"
+ argv:
+ - "/akkoma/bin/pleroma_ctl"
+ - "user"
+ - "new"
+ - "{{ akkoma_admin_nickname }}"
+ - "{{ akkoma_admin_email }}"
+ - "--password"
+ - "{{ akkoma_admin_password }}"
+ - "--admin"
+ - "-y"
A roles/containers/akkoma/templates/firefish.conf => roles/containers/akkoma/templates/firefish.conf +254 -0
@@ 0,0 1,254 @@
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+# Firefish configuration
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+# After starting your server, please don't change the URL! Doing so will break federation.
+
+# ┌─────┐
+#───┘ URL └─────────────────────────────────────────────────────
+
+# Final accessible URL seen by a user.
+url: https://{{ firefish_domain }}/
+
+# ┌───────────────────────┐
+#───┘ Port and TLS settings └───────────────────────────────────
+
+#
+# Firefish requires a reverse proxy to support HTTPS connections.
+#
+# +----- https://example.com/ ------------+
+# +------+ |+-------------+ +----------------+|
+# | User | ---> || Proxy (443) | ---> | Firefish (3000) ||
+# +------+ |+-------------+ +----------------+|
+# +---------------------------------------+
+#
+# You need to set up a reverse proxy. (e.g. nginx, caddy)
+# An encrypted connection with HTTPS is highly recommended
+# because tokens may be transferred in GET requests.
+
+# The port that your Firefish server should listen on.
+port: 3000
+
+# ┌──────────────────────────┐
+#───┘ PostgreSQL configuration └────────────────────────────────
+
+db:
+ host: firefish_db
+ port: 5432
+ #ssl: false
+ # Database name
+ db: calckey
+
+ # Auth
+ user: {{ firefish_postgres_user }}
+ pass: {{ firefish_postgres_pass }}
+
+ # Whether disable Caching queries
+ #disableCache: true
+
+ # Extra Connection options
+ #extra:
+ # ssl:
+ # host: localhost
+ # rejectUnauthorized: false
+
+# ┌─────────────────────┐
+#───┘ Redis configuration └─────────────────────────────────────
+
+redis:
+ host: firefish_redis
+ port: 6379
+ #tls:
+ # host: localhost
+ # rejectUnauthorized: false
+ #family: 0 # 0=Both, 4=IPv4, 6=IPv6
+ #pass: example-pass
+ #prefix: example-prefix
+ #db: 1
+ #user: default
+
+# ┌─────────────────────────────┐
+#───┘ Cache server configuration └─────────────────────────────────────
+
+# A Redis-compatible server (DragonflyDB, Keydb, Redis) for caching
+# If left blank, it will use the Redis server from above
+
+#cacheServer:
+ #host: localhost
+ #port: 6379
+ #family: 0 # 0=Both, 4=IPv4, 6=IPv6
+ #pass: example-pass
+ #prefix: example-prefix
+ #db: 1
+
+# Please configure either MeiliSearch *or* Sonic.
+# If both MeiliSearch and Sonic configurations are present, MeiliSearch will take precedence.
+
+# ┌───────────────────────────┐
+#───┘ MeiliSearch configuration └─────────────────────────────────────
+#meilisearch:
+# host: meilisearch
+# port: 7700
+# ssl: false
+# apiKey:
+
+# ┌─────────────────────┐
+#───┘ Sonic configuration └─────────────────────────────────────
+
+sonic:
+ host: firefish_sonic
+ port: 1491
+ auth: {{ firefish_sonic_pass }}
+ collection: notes
+ bucket: default
+
+
+# ┌───────────────┐
+#───┘ ID generation └───────────────────────────────────────────
+
+id: {{ firefish_id }}
+# No need to uncomment in most cases, but you may want to change
+# these settings if you plan to run a large and/or distributed server.
+
+# cuid:
+# # Min 16, Max 24
+# length: 16
+#
+# # Set this to a unique string across workers (e.g., machine's hostname)
+# # if your workers are running in multiple hosts.
+# fingerprint: my-fingerprint
+
+
+# ┌─────────────────────┐
+#───┘ Other configuration └─────────────────────────────────────
+
+# Maximum length of a post (default 3000, max 100000)
+#maxNoteLength: 3000
+
+# Maximum length of an image caption (default 1500, max 8192)
+#maxCaptionLength: 1500
+
+# Reserved usernames that only the administrator can register with
+reservedUsernames: [
+ 'root',
+ 'admin',
+ 'administrator',
+ 'me',
+ 'system'
+]
+
+# Whether disable HSTS
+#disableHsts: true
+
+# Number of worker processes
+#clusterLimit: 1
+
+# Worker only mode
+#onlyQueueProcessor: 1
+
+# Job concurrency per worker
+# deliverJobConcurrency: 128
+# inboxJobConcurrency: 16
+
+# Job rate limiter
+# deliverJobPerSec: 128
+# inboxJobPerSec: 16
+
+# Job attempts
+# deliverJobMaxAttempts: 12
+# inboxJobMaxAttempts: 8
+
+# IP address family used for outgoing request (ipv4, ipv6 or dual)
+#outgoingAddressFamily: ipv4
+
+# Syslog option
+#syslog:
+# host: localhost
+# port: 514
+
+# Proxy for HTTP/HTTPS
+#proxy: http://127.0.0.1:3128
+
+#proxyBypassHosts: [
+# 'web.kaiteki.app',
+# 'example.com',
+# '192.0.2.8'
+#]
+
+# Proxy for SMTP/SMTPS
+#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
+#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
+#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
+
+# Media Proxy
+#mediaProxy: https://example.com/proxy
+
+# Proxy remote files (default: false)
+#proxyRemoteFiles: true
+
+#allowedPrivateNetworks: [
+# '127.0.0.1/32'
+#]
+
+# TWA
+#twa:
+# nameSpace: android_app
+# packageName: tld.domain.twa
+# sha256CertFingerprints: ['AB:CD:EF']
+
+# Upload or download file size limits (bytes)
+#maxFileSize: 262144000
+
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+# Congrats, you've reached the end of the config file needed for most deployments!
+# Enjoy your Firefish server!
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+
+
+
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+# Managed hosting settings
+# >>> NORMAL SELF-HOSTERS, STAY AWAY! <<<
+# >>> YOU DON'T NEED THIS! <<<
+# Each category is optional, but if each item in each category is mandatory!
+# If you mess this up, that's on you, you've been warned...
+#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+#maxUserSignups: 100
+#isManagedHosting: true
+#deepl:
+# managed: true
+# authKey: ''
+# isPro: false
+#
+#email:
+# managed: true
+# address: 'example@email.com'
+# host: 'email.com'
+# port: 587
+# user: 'example@email.com'
+# pass: ''
+# useImplicitSslTls: false
+#
+#objectStorage:
+# managed: true
+# baseUrl: ''
+# bucket: ''
+# prefix: ''
+# endpoint: ''
+# region: ''
+# accessKey: ''
+# secretKey: ''
+# useSsl: true
+# connnectOverProxy: false
+# setPublicReadOnUpload: true
+# s3ForcePathStyle: true
+
+# !!!!!!!!!!
+# >>>>>> AGAIN, NORMAL SELF-HOSTERS, STAY AWAY! <<<<<<
+# >>>>>> YOU DON'T NEED THIS, ABOVE SETTINGS ARE FOR MANAGED HOSTING ONLY! <<<<<<
+# !!!!!!!!!!
+
+# Seriously. Do NOT fill out the above settings if you're self-hosting.
+# They're much better off being set from the control panel.
A roles/containers/akkoma/templates/sonic.conf => roles/containers/akkoma/templates/sonic.conf +69 -0
@@ 0,0 1,69 @@
+# Sonic
+# Fast, lightweight and schema-less search backend
+# Configuration file
+# Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg
+
+
+[server]
+
+log_level = "debug"
+
+
+[channel]
+
+inet = "0.0.0.0:1491"
+tcp_timeout = 300
+
+auth_password = "{{ firefish_sonic_pass }}"
+
+[channel.search]
+
+query_limit_default = 10
+query_limit_maximum = 100
+query_alternates_try = 4
+
+suggest_limit_default = 5
+suggest_limit_maximum = 20
+
+list_limit_default = 100
+list_limit_maximum = 500
+
+
+[store]
+
+[store.kv]
+
+path = "/var/lib/sonic/store/kv/"
+
+retain_word_objects = 1000
+
+[store.kv.pool]
+
+inactive_after = 1800
+
+[store.kv.database]
+
+flush_after = 900
+
+compress = true
+parallelism = 2
+max_files = 100
+max_compactions = 1
+max_flushes = 1
+write_buffer = 16384
+write_ahead_log = true
+
+[store.fst]
+
+path = "/var/lib/sonic/store/fst/"
+
+[store.fst.pool]
+
+inactive_after = 300
+
+[store.fst.graph]
+
+consolidate_after = 180
+
+max_size = 2048
+max_words = 250000