8 Commits

20 changed files with 411 additions and 2 deletions

View File

@ -18,6 +18,9 @@ available.
- [`mastodon`](roles/mastodon/README.md): deployment using a container based - [`mastodon`](roles/mastodon/README.md): deployment using a container based
setup, able to use webfinger delegation. setup, able to use webfinger delegation.
- [`sharkey`](roles/sharkey/README.md): deployment of sharkey, a misskey-
fork with full mastodon API compatability.
## License ## License
[CNPLv7+](LICENSE.md): Cooperative Nonviolent Public License [CNPLv7+](LICENSE.md): Cooperative Nonviolent Public License

View File

@ -1,17 +1,22 @@
namespace: finallycoffee namespace: finallycoffee
name: fediverse name: fediverse
version: 0.1.2 version: 0.2.0
readme: README.md readme: README.md
authors: authors:
- transcaffeine <transcaffeine@finally.coffee> - transcaffeine <transcaffeine@finally.coffee>
description: Deploying fediverse software, mostly ActivityPub based description: Deploying fediverse software, mostly ActivityPub based
dependencies: dependencies:
"community.docker": "^4.0.0" "community.docker": "^4.0.0"
"community.general": "^10.6.0"
license_file: LICENSE.md license_file: LICENSE.md
build_ignore: build_ignore:
- '*.tar.gz' - '*.tar.gz'
repository: https://git.finally.coffee/finallycoffee/fediverse repository: https://git.finally.coffee/finallycoffee/fediverse
issues: https://codeberg.org/finallycoffee/ansible-collection-fediverse/issues issues: https://codeberg.org/finallycoffee/ansible-collection-fediverse/issues
tags: tags:
- activitypub
- fediverse
- fediwall - fediwall
- sharkey
- gotosocial - gotosocial
- mastodon

6
playbooks/sharkey.yml Normal file
View File

@ -0,0 +1,6 @@
---
- name: Deploy sharkey
hosts: "{{ sharkey_hosts | default('sharkey') }}"
become: "{{ sharkey_become | default(false) }}"
roles:
- role: finallycoffee.fediverse.sharkey

View File

@ -0,0 +1,14 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: gotosocial
description: >-2
Deploy GoToSocial, a lightweight, customizable and safety-focused
activitypub server written in golang.
galaxy_tags:
- gotosocial
- gts
- docker
- activitypub
- fediverse

View File

@ -3,7 +3,7 @@ mastodon_user: mastodon
mastodon_base_path: /opt/mastodon mastodon_base_path: /opt/mastodon
mastodon_domain: ~ mastodon_domain: ~
mastodon_web_domain: ~ mastodon_web_domain: ~
mastodon_version: "4.3.2" mastodon_version: "4.3.9"
mastodon_git_upstream_url: "https://github.com/mastodon/mastodon.git" mastodon_git_upstream_url: "https://github.com/mastodon/mastodon.git"
mastodon_data_path: "{{ mastodon_base_path }}/data" mastodon_data_path: "{{ mastodon_base_path }}/data"

View File

@ -0,0 +1,12 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: mastodon
description: >-2
Deploy Mastodon, a social network server based on activity pub, built with ruby and nodejs
galaxy_tags:
- mastodon
- activitypub
- fediverse
- docker

44
roles/sharkey/README.md Normal file
View File

@ -0,0 +1,44 @@
# `finallycoffee.fediverse.sharkey` ansible role
## Configuration
Set the required `sharkey_config_url` variable to the domain you want sharkey to run on.
To extend/modify the sharkey configuration file (upstream: `default.yml`),
set your (structed) configuration in `sharkey_config` and it will be merged
over the upstream config file and the role built-in configuration.
### Docker compose
To extend/modify the compose project file (`compose.yml`), populate `sharkey_compose_file_overrides`.
Take care when overriding `sharkey_compose_file_role_overrides`, as this can
break the functionality of the ansible role.
## Behind a proxy
The ansible role itself will respect system proxies (in the env var `HTTP_PROXY`/`https_proxy`).
To use this role with a registry like Artifactory or Nexus3,
set `sharkey_repo_server` to your registry server with full
protocol, hostname, port. For example `sharkey_repo_server: "https://my.orgs.registry.local:8443/sharkey-internet-proxy/"`
## Stopping
### Docker compose
Set `sharkey_compose_state: "stopped"` to ensure all containers in the compose
project are stopped. This has the same effect as `docker compose stop`. Set
`sharkey_compose_state: "absent"` to not only stop all containers, but remove
them, the docker networks associated with the project etc. This is equivalent
to `docker compose down`.
> [!WARNING]
> Do not confuse `sharkey_compose_state` with `sharkey_state`!
## Deprovisioning
Set `sharkey_state: "absent"` to remove sharkey from the target, including
*all* application data, configuration files, container images.
> [!CAUTION]
> This removes all (user) data irrecoverably with no backup.

View File

@ -0,0 +1,41 @@
---
sharkey_compose_state: "{{ sharkey_state }}"
sharkey_compose_project_name: "sharkey"
sharkey_compose_project_src: "{{ sharkey_config_dir }}"
sharkey_compose_upstream_file: "{{ sharkey_compose_project_src }}/compose.upstream.yml"
sharkey_compose_file: "{{ sharkey_compose_project_src }}/compose.yml"
sharkey_compose_build: >-2
{{ (sharkey_container_image_source == 'pull') | ternary('never', 'policy') }}
sharkey_compose_redis_dir: "{{ sharkey_data_dir }}/redis"
sharkey_compose_database_dir: "{{ sharkey_data_dir }}/postgres"
sharkey_repo_server: "https://activitypub.software"
sharkey_repo_path: "Transfem-org/Sharkey"
sharkey_repo_tag: "{{ sharkey_version }}"
sharkey_compose_file_url: >-2
{{ sharkey_repo_server }}/{{ sharkey_repo_path }}/-/raw/{{ sharkey_version }}/compose_example.yml?ref_type=tags
sharkey_compose_file_overrides: ~
sharkey_compose_file_role_overrides:
services:
web:
image: "{{ sharkey_container_image }}"
volumes:
- "{{ sharkey_file_dir }}:/sharkey/files:rw"
- "{{ sharkey_config_file }}:/sharkey/.config/default.yaml:ro"
- "{{ sharkey_container_env_file }}:/sharkey/.config/docker.env:ro"
db:
env_file: "{{ sharkey_container_env_file }}"
volumes:
- "{{ sharkey_compose_database_dir }}:/var/lib/postgresql/data:rw"
redis:
volumes:
- "{{ sharkey_compose_redis_dir }}:/data:rw"
# override net segment?
sharkey_compose_file_contents: >-2
{{
(sharkey_compose_upstream_file_contents['content'] | b64decode | from_yaml)
| combine(sharkey_compose_file_role_overrides, recursive=True)
| combine(sharkey_compose_file_overrides | default({}, true), recursive=True)
| to_nice_yaml(indent=4)
}}

View File

@ -0,0 +1,30 @@
---
sharkey_config_url: ~
sharkey_config_setup_password: ~
sharkey_config_postgres_user: misskey
sharkey_config_postgres_password: "insecure_please_change_me!"
sharkey_config_postgres_db: misskey
sharkey_config_postgres_host: db
sharkey_config_postgres_port: 5432
sharkey_config_postgres_db_url: >-2
postgres://{{ sharkey_config_postgres_user }}:{{ sharkey_config_postgres_password }}@{{ sharkey_config_postgres_host }}:{{ sharkey_config_postgres_port }}/{{ sharkey_config_postgres_db }}
sharkey_config: ~
sharkey_config_file_overrides:
url: "{{ sharkey_config_url }}"
db:
host: "{{ sharkey_config_postgres_host }}"
db: "{{ sharkey_config_postgres_db }}"
user: "{{ sharkey_config_postgres_user }}"
pass: "{{ sharkey_config_postgres_password }}"
sharkey_config_file_contents: >-2
{{
(sharkey_config_upstream_file_contents['content'] | b64decode | from_yaml)
| combine(sharkey_config_file_overrides, recursive=True)
| combine(sharkey_config | default({}, true), recursive=True)
| to_nice_yaml(indent=4)
}}
sharkey_config_upstream_file: "{{ sharkey_config_dir }}/config.upstream.yaml"
sharkey_config_file: "{{ sharkey_config_dir }}/default.yaml"
sharkey_config_upstream_file_url: >-2
{{ sharkey_repo_server }}/{{ sharkey_repo_path }}/-/raw/{{ sharkey_version }}/.config/docker_example.yml?ref=tags

View File

@ -0,0 +1,47 @@
---
sharkey_container_name: sharkey
sharkey_container_image_registry: "registry.activitypub.software"
sharkey_container_iamge_namespace: "transfem-org"
sharkey_container_image_name: "sharkey"
sharkey_container_image_repository: >-2
{{
[
sharkey_container_image_registry | default([], true),
sharkey_container_iamge_namespace | default([], true),
sharkey_container_image_name
] | flatten | join('/')
}}
sharkey_container_image_tag: ~
sharkey_container_image_source: pull
sharkey_container_image_force_source: >-2
{{ sharkey_container_image_tag | default(false, true) | bool }}
sharkey_container_image: >-2
{{
[
sharkey_container_image_repository,
sharkey_container_image_tag | default(sharkey_version, true)
] | join(':')
}}
sharkey_container_default_env:
MISSKEY_URL: "{{ sharkey_config_url }}"
POSTGRES_USER: "{{ sharkey_config_postgres_user }}"
POSTGRES_PASSWORD: "{{ sharkey_config_postgres_password }}"
POSTGRES_DB: "{{ sharkey_config_postgres_db }}"
DATABASE_URL: >-2
{{
(sharkey_config_postgres_user | default(false, true))
| ternary(sharkey_config_postgres_db_url, '')
}}
sharkey_container_env: ~
sharkey_container_merged_env: >-2
{{
sharkey_container_default_env | default({}, true)
| combine(sharkey_container_env | default({}, true), recursive=True)
}}
sharkey_container_env_file_contents: |2
{% for entry in sharkey_container_merged_env | dict2items %}
{% if entry['value'] is string and entry['value'] | length > 0 %}
{{ entry['key'] }}={{ entry['value'] }}
{% endif %}
{% endfor %}
sharkey_container_env_file: "{{ sharkey_config_dir }}/docker.env"

View File

@ -0,0 +1,9 @@
---
sharkey_user: sharkey
sharkey_version: "2025.4.3"
sharkey_config_dir: "/etc/sharkey"
sharkey_data_dir: "/var/lib/sharkey"
sharkey_file_dir: "{{ sharkey_data_dir }}/files"
sharkey_state: present
sharkey_deployment_method: "docker-compose"

View File

@ -0,0 +1,10 @@
---
sharkey_user_system: true
sharkey_user_create_home: false
sharkey_user_groups: ~
sharkey_user_append_groups: >-2
{{ sharkey_user_groups | default(omit, true) }}
sharkey_user_uid: >-2
{{ sharkey_user_info.uid | default(sharkey_user) }}
sharkey_user_gid: >-2
{{ sharkey_user_info.group | default(sharkey_user) }}

View File

@ -0,0 +1,14 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: sharkey
description: >-2
Deploy Sharkey, a fork of Misskey with full Mastodon-API support
galaxy_tags:
- sharkey
- misskey
- mastodon
- docker
- activitypub
- fediverse

View File

@ -0,0 +1,26 @@
---
- name: Ensure 'sharkey_state' is valid
ansible.builtin.fail:
msg: >-2
Unsupported sharkey_state '{{ sharkey_state }}'.
Supported values are {{ sharkey_states | join(', ') }}
when: sharkey_state not in sharkey_states
- name: Ensure 'sharkey_deployment_method' is valid
ansible.builtin.fail:
msg: >-2
Unsupported sharkey_deployment_method '{{ sharkey_deployment_method }}.
Supported values are {{ sharkey_deployment_methods | join(', ') }}
when: sharkey_deployment_method not in sharkey_deployment_methods
- name: Ensure 'sharkey_config_url' is valid
ansible.builtin.fail:
msg: >-2
Variable 'sharkey_config_url' is not populated! This variable
is mandatory to set when deploying sharkey.
when:
- sharkey_state == 'present'
- >-2
sharkey_config_url is not defined
or ((sharkey_config_url | string) == 'None')
or ((sharkey_config_url | string | length) == 0)

View File

@ -0,0 +1,39 @@
---
- name: Ensure directories for compose services are {{ sharkey_state }}
ansible.builtin.file:
name: "{{ file.path }}"
state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0750"
loop:
- path: "{{ sharkey_compose_redis_dir }}"
- path: "{{ sharkey_compose_database_dir }}"
loop_control:
loop_var: file
label: "{{ file.path }}"
- name: Ensure final compose file is templated
when: sharkey_state == 'present'
block:
# TODO: wronlgy reports changed in checkmode due to hash mismatches
- name: Ensure compose files are downloaded
ansible.builtin.get_url:
url: "{{ sharkey_compose_file_url }}"
dest: "{{ sharkey_compose_upstream_file }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0444"
- name: Read compose file contents
ansible.builtin.slurp:
src: "{{ sharkey_compose_upstream_file }}"
register: sharkey_compose_upstream_file_contents
- name: Ensure modified compose file is written
ansible.builtin.copy:
content: "{{ sharkey_compose_file_contents }}"
dest: "{{ sharkey_compose_file }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0644"

View File

@ -0,0 +1,9 @@
---
- name: Ensure sharkey docker environment is templated
ansible.builtin.copy:
content: "{{ sharkey_container_env_file_contents }}"
dest: "{{ sharkey_container_env_file }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0640"
when: sharkey_state == 'present'

View File

@ -0,0 +1,68 @@
---
- name: Ensure sharkey user '{{ sharkey_user }}' is {{ sharkey_state }}
ansible.builtin.user:
name: "{{ sharkey_user }}"
state: "{{ sharkey_state }}"
system: "{{ sharkey_user_system }}"
create_home: "{{ sharkey_user_create_home }}"
groups: "{{ sharkey_user_groups }}"
append: "{{ sharkey_user_append_groups }}"
register: sharkey_user_info
- name: Ensure sharkey config directory '{{ sharkey_config_dir }}' is {{ sharkey_state }}
ansible.builtin.file:
path: "{{ sharkey_config_dir }}"
state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0750"
- name: Ensure sharkey data directory '{{ sharkey_data_dir }}' is {{ sharkey_state }}
ansible.builtin.file:
path: "{{ sharkey_data_dir }}"
state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0750"
- name: Ensure sharkey file directory '{{ sharkey_file_dir }}' is {{ sharkey_state }}
ansible.builtin.file:
path: "{{ sharkey_file_dir }}"
state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0750"
- name: Ensure sharkey config file '{{ sharkey_config_file }}' is {{ sharkey_state }}
when: sharkey_state == 'present'
block:
# TODO: wrongly reports changed in checkmode due to different hashes
- name: Ensure sharkey upstream config file is {{ sharkey_state }}
ansible.builtin.get_url:
url: "{{ sharkey_config_upstream_file_url }}"
dest: "{{ sharkey_config_upstream_file }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0440"
- name: Read upstream sharkey config file
ansible.builtin.slurp:
src: "{{ sharkey_config_upstream_file }}"
register: sharkey_config_upstream_file_contents
- name: Ensure sharkey configuration file is {{ sharkey_state }}
ansible.builtin.copy:
content: "{{ sharkey_config_file_contents }}"
dest: "{{ sharkey_config_file }}"
owner: "{{ sharkey_user_uid }}"
group: "{{ sharkey_user_gid }}"
mode: "0640"
- name: Run configure steps for deployment using containers
ansible.builtin.include_tasks:
file: "configure-docker.yml"
when: sharkey_deployment_method in ['docker-compose']
- name: Configure for {{ sharkey_deployment_method }}
ansible.builtin.include_tasks:
file: "configure-{{ sharkey_deployment_method }}.yml"

View File

@ -0,0 +1,14 @@
---
- name: Ensure sharkey container image '{{ sharkey_container_image }}' is {{ sharkey_state }}
community.docker.docker_image:
name: "{{ sharkey_container_image }}"
state: "{{ sharkey_state }}"
source: "{{ sharkey_container_image_source }}"
force_source: "{{ sharkey_container_image_force_source }}"
- name: Ensure docker compose project is {{ sharkey_compose_state }}
community.docker.docker_compose_v2:
project_name: "{{ sharkey_compose_project_name }}"
project_src: "{{ sharkey_compose_project_src }}"
state: "{{ sharkey_compose_state }}"
build: "{{ sharkey_compose_build }}"

View File

@ -0,0 +1,12 @@
---
- name: Check role prerequisites
ansible.builtin.include_tasks:
file: check.yml
- name: Run common configuration tasks
ansible.builtin.include_tasks:
file: configure.yml
- name: Deploy using {{ sharkey_deployment_method }}
ansible.builtin.include_tasks:
file: "deploy-{{ sharkey_deployment_method }}.yml"

View File

@ -0,0 +1,6 @@
---
sharkey_states:
- present
- absent
sharkey_deployment_methods:
- "docker-compose"