feat: managing my Pleroma instance with GitOps.
This is a big milestone for me as this is the first project where I completely set up GitOps for managing my Pleroma platform. [skip ci]
This commit is contained in:
parent
fec64b95ab
commit
9b7e3f3955
9 changed files with 353 additions and 0 deletions
61
.gitlab-ci.yml
Normal file
61
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
stages:
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
# TODO: research and add a suitable WorkFlow.
|
||||||
|
|
||||||
|
variables:
|
||||||
|
ANSIBLE_FORCE_COLOR: "True"
|
||||||
|
INVENTORY: ${CI_PROJECT_DIR}/ansible/inventory/free-flow/hosts
|
||||||
|
PLEROMA_PLAYBOOK_DIRECTORY: /ansible/pleroma-playbook
|
||||||
|
PLEROMA_INFRASTRUCTURE_DIRECTORY: ${CI_PROJECT_DIR}
|
||||||
|
VAULT_AUTH_METHOD: approle
|
||||||
|
|
||||||
|
image: registry.gitlab.com/dananglin/pleroma-ansible-playbook:v0.1.3
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- .gitlab/ci/bin/generate-inventory
|
||||||
|
- .gitlab/ci/bin/update-config-for-testing
|
||||||
|
- cd ${PLEROMA_PLAYBOOK_DIRECTORY}
|
||||||
|
|
||||||
|
deploy:testing:
|
||||||
|
environment:
|
||||||
|
name: ${PLEROMA_ENVIRONMENT}
|
||||||
|
url: ${TESTING_PLEROMA_FQDN}
|
||||||
|
rules:
|
||||||
|
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "testing" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
|
||||||
|
when: always
|
||||||
|
script:
|
||||||
|
- "make pleroma"
|
||||||
|
stage: deploy
|
||||||
|
tags:
|
||||||
|
- pleroma-ansible-testing
|
||||||
|
variables:
|
||||||
|
EXTRA_ARGS: "--extra-vars enable_pleroma_upgrade=True"
|
||||||
|
PLEROMA_ENVIRONMENT: testing
|
||||||
|
PLEROMA_ANSIBLE_HOST: ${TESTING_PLEROMA_ANSIBLE_HOST}
|
||||||
|
PLEROMA_ANSIBLE_USER: ${TESTING_PLEROMA_ANSIBLE_USER}
|
||||||
|
PLEROMA_ANSIBLE_PASSWORD: ${TESTING_PLEROMA_ANSIBLE_PASSWORD}
|
||||||
|
VAULT_ROLE_ID: ${TESTING_VAULT_ROLE_ID}
|
||||||
|
VAULT_SECRET_ID: ${TESTING_VAULT_SECRET_ID}
|
||||||
|
|
||||||
|
deploy:production:
|
||||||
|
environment:
|
||||||
|
name: ${PLEROMA_ENVIRONMENT}
|
||||||
|
url: https://fedi.dananglin.me.uk
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PROJECT_PATH == "dananglin/pleroma-free-flow"'
|
||||||
|
when: always
|
||||||
|
script:
|
||||||
|
- "make pleroma"
|
||||||
|
stage: deploy
|
||||||
|
tags:
|
||||||
|
- pleroma-ansible-production
|
||||||
|
variables:
|
||||||
|
ANSIBLE_PRIVATE_KEY_FILE: ${PRODUCTION_PLEROMA_ANSIBLE_PRIVATE_KEY_FILE}
|
||||||
|
EXTRA_ARGS: "--extra-vars enable_pleroma_upgrade=True"
|
||||||
|
PLEROMA_ENVIRONMENT: production
|
||||||
|
PLEROMA_ANSIBLE_HOST: ${PRODUCTION_PLEROMA_ANSIBLE_HOST}
|
||||||
|
PLEROMA_ANSIBLE_USER: ${PRODUCTION_PLEROMA_ANSIBLE_USER}
|
||||||
|
VAULT_ROLE_ID: ${PRODUCTION_PLEROMA_VAULT_ROLE_ID}
|
||||||
|
VAULT_SECRET_ID: ${PRODUCTION_PLEROMA_VAULT_SECRET_ID}
|
11
.gitlab/ci/bin/generate-inventory
Executable file
11
.gitlab/ci/bin/generate-inventory
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ANSIBLE_SSH_VARS="ansible_connection=ssh ansible_host=${PLEROMA_ANSIBLE_HOST} ansible_user=${PLEROMA_ANSIBLE_USER}"
|
||||||
|
|
||||||
|
if [ "${PLEROMA_ENVIRONMENT:-nil}" == "testing" ]; then
|
||||||
|
ANSIBLE_SSH_VARS="${ANSIBLE_SSH_VARS} ansible_password=${PLEROMA_ANSIBLE_PASSWORD}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i -e "s/free-flow/free-flow $ANSIBLE_SSH_VARS/g" ${INVENTORY}
|
24
.gitlab/ci/bin/update-config-for-testing
Executable file
24
.gitlab/ci/bin/update-config-for-testing
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONFIGURATION_FILE=${PLEROMA_INFRASTRUCTURE_DIRECTORY}/ansible/inventory/free-flow/host_vars/free-flow/pleroma-configuration.yml
|
||||||
|
|
||||||
|
if [ "${PLEROMA_ENVIRONMENT:-nil}" == "testing" ]; then
|
||||||
|
|
||||||
|
# 1) Ensure vault secrets are retrieved from the development path.
|
||||||
|
# 2) Change instance name.
|
||||||
|
# 3) Change instance description.
|
||||||
|
# 4) Disable healthcheck.
|
||||||
|
# 5) Change the domain name.
|
||||||
|
# 6) Disable let's encrypt (until we get ngrok set up).
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
-e 's/secret=pleroma\/production/secret=pleroma\/development/g' \
|
||||||
|
-e 's/^.*instanceName:.*$/ instanceName: "Free Flow (Test Instance)"/' \
|
||||||
|
-e 's/^.*instanceDescription:.*$/ instanceDescription: "Pleroma test instance for Free Flow"/' \
|
||||||
|
-e 's/^.*healthCheck:.*$/ healthCheck: "false"/' \
|
||||||
|
-e "s/^.*host:.*$/ host: ${TESTING_PLEROMA_FQDN}/" \
|
||||||
|
${CONFIGURATION_FILE}
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
pleroma:
|
||||||
|
config:
|
||||||
|
email: &email daangling@gmail.com
|
||||||
|
host: fedi.dananglin.me.uk
|
||||||
|
listeningPort: 10000
|
||||||
|
instanceName: "Free Flow"
|
||||||
|
instanceDescription: "Yet another single-user Pleroma instance in the Fediverse."
|
||||||
|
secretKeyBase: "{{ lookup('hashi_vault', 'secret=pleroma/production:secretKeyBase') }}"
|
||||||
|
signingSalt: "{{ lookup('hashi_vault', 'secret=pleroma/production:signingSalt') }}"
|
||||||
|
webPushEncryption:
|
||||||
|
email: *email
|
||||||
|
privateKey: "{{ lookup('hashi_vault', 'secret=pleroma/production:webPushEncryption.privateKey') }}"
|
||||||
|
publicKey: "{{ lookup('hashi_vault', 'secret=pleroma/production:webPushEncryption.publicKey') }}"
|
||||||
|
characterLimit: 5000
|
||||||
|
registrationsOpen: "false"
|
||||||
|
configurableFromDatabase: "false"
|
||||||
|
healthCheck: "true"
|
||||||
|
remotePostRetentionDays: 30
|
||||||
|
logLevel: info
|
||||||
|
federating: "true"
|
||||||
|
chatEnabled: "false"
|
||||||
|
mrf:
|
||||||
|
simplePolicy:
|
||||||
|
reject:
|
||||||
|
- baraag.net
|
||||||
|
- gab.com
|
||||||
|
- switter.at
|
||||||
|
- vipgirlfriend.xxx
|
||||||
|
- pawoo.net
|
||||||
|
federatedTimelineRemoval:
|
||||||
|
- freespeechextremist.com
|
||||||
|
- sinblr.com
|
||||||
|
mediaRemoval: []
|
||||||
|
mediaNsfw: []
|
||||||
|
frontend:
|
||||||
|
background: "{{ lookup('env', 'PLEROMA_INFRASTRUCTURE_DIRECTORY') }}/assets/background/photo-of-starry-night.jpg"
|
||||||
|
themes:
|
||||||
|
custom:
|
||||||
|
- name: night-owl
|
||||||
|
path: "{{ lookup('env', 'PLEROMA_INFRASTRUCTURE_DIRECTORY') }}/assets/themes/night-owl.json"
|
||||||
|
default: night-owl
|
||||||
|
db:
|
||||||
|
name: "{{ lookup('hashi_vault', 'secret=pleroma/production:database.name') }}"
|
||||||
|
user: "{{ lookup('hashi_vault', 'secret=pleroma/production:database.user') }}"
|
||||||
|
password: "{{ lookup('hashi_vault', 'secret=pleroma/production:database.password') }}"
|
||||||
|
connLimit: 15
|
||||||
|
ssl:
|
||||||
|
csr:
|
||||||
|
countryName: "GB"
|
||||||
|
emailAddress: *email
|
||||||
|
organizationName: "Dan Anglin"
|
||||||
|
organizationUnitName: "DevOps"
|
||||||
|
stateOrProvinceName: "Hertfordshire"
|
||||||
|
letsEncrypt:
|
||||||
|
enable: true
|
||||||
|
acmeAccountEmail: *email
|
||||||
|
acmeDirectory: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
remainingDays: 30
|
||||||
|
termsAgreed: yes
|
||||||
|
validateCerts: true
|
||||||
|
keybase:
|
||||||
|
enable: true
|
||||||
|
proof:
|
||||||
|
filepath: "{{ lookup('env', 'PLEROMA_INFRASTRUCTURE_DIRECTORY') }}/assets/keybase/keybase.txt"
|
|
@ -0,0 +1,2 @@
|
||||||
|
pleroma_version: 2.0.7
|
||||||
|
pleroma_download_url: file:///opt/pleroma-installation/pleroma-{{ pleroma_version }}.zip
|
11
ansible/inventory/free-flow/hosts
Normal file
11
ansible/inventory/free-flow/hosts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[pleroma]
|
||||||
|
free-flow
|
||||||
|
|
||||||
|
[pleroma_database:children]
|
||||||
|
pleroma
|
||||||
|
|
||||||
|
[pleroma_main:children]
|
||||||
|
pleroma
|
||||||
|
|
||||||
|
[pleroma_proxy:children]
|
||||||
|
pleroma
|
BIN
assets/background/photo-of-starry-night.jpg
Normal file
BIN
assets/background/photo-of-starry-night.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
76
assets/keybase/keybase.txt
Normal file
76
assets/keybase/keybase.txt
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
==================================================================
|
||||||
|
https://keybase.io/dananglin
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
I hereby claim:
|
||||||
|
|
||||||
|
* I am an admin of https://fedi.dananglin.me.uk
|
||||||
|
* I am dananglin (https://keybase.io/dananglin) on keybase.
|
||||||
|
* I have a public key with fingerprint 2DA0 1412 E54B 4D09 1EC7 832B 6881 FFE2 487C 411A
|
||||||
|
|
||||||
|
To do so, I am signing this object:
|
||||||
|
|
||||||
|
{
|
||||||
|
"body": {
|
||||||
|
"key": {
|
||||||
|
"eldest_kid": "01209ab244758a00dbdaa62f22e39f0a01626be8eed46486fad7cf98d8960c5733100a",
|
||||||
|
"fingerprint": "2da01412e54b4d091ec7832b6881ffe2487c411a",
|
||||||
|
"host": "keybase.io",
|
||||||
|
"key_id": "6881ffe2487c411a",
|
||||||
|
"kid": "01017c0ec830219a1bc8b485cd8ffc2888e5c7d8867ea0700a7489d19fa2531d4d610a",
|
||||||
|
"uid": "cabbfca4014ba07a1b45acccf673ca19",
|
||||||
|
"username": "dananglin"
|
||||||
|
},
|
||||||
|
"service": {
|
||||||
|
"hostname": "fedi.dananglin.me.uk",
|
||||||
|
"protocol": "https:"
|
||||||
|
},
|
||||||
|
"type": "web_service_binding",
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"ctime": 1573089617,
|
||||||
|
"expire_in": 157680000,
|
||||||
|
"prev": "0640a7700c3ed34aa9e0952b106d15173939196e781450fdb1439c3142c5c154",
|
||||||
|
"seqno": 31,
|
||||||
|
"tag": "signature"
|
||||||
|
}
|
||||||
|
|
||||||
|
which yields the signature:
|
||||||
|
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
Version: Keybase OpenPGP v2.1.3
|
||||||
|
Comment: https://keybase.io/crypto
|
||||||
|
|
||||||
|
yMNzAnicbVJ/TFVVHOcBRjxnGCNquYDuNFa86J7781yM5Ec+7GUZYmtGgPeeey7c
|
||||||
|
4P1+j/cYoCRqgyih2GKOJJpClE8TGwkO42fTYI6MKMKU3nxzpoQbDBWWdB/T/ur8
|
||||||
|
c3a++3w+5/P5nDO0JixEryt6b9m/pSL9Sd1If6s7JG/Qnl1OSFa5jEgpJ4rxyoZL
|
||||||
|
ZOx0FRSrMpFCkIAiBVGiGIZnoUiSsiSLIkcpFIVpQSFFEnAUJ2GIscxwDOQUUeaR
|
||||||
|
IkAZChyJWJ6mAUmKhIFQVEshdtgcqsWlyVKyxmQAhVlGYmRSABjxkKYkDkKgKJhi
|
||||||
|
II8YAILEIqszyNDMSaITJ6tWbaYdClbs/Q/+gW8S8IjECNIkBQQRSAhKDGSRDBUF
|
||||||
|
URBCzCJehpDjsUjymkeegYIMBEWkWBrIjMyBFd/uFTkkSpKCREYzLWlwTY5hRYSQ
|
||||||
|
wvE0EoEQBDqxwyKasYaWRYtoKSxRLUSlgdDGpSrCwWaDUe5DFCyryf/hks042V2s
|
||||||
|
idgcVpcVWUs0RJHLZXOmBBVcZbYgxYOlgvtiBZJqkbVCNUYpdjhVq4VIARoSudSg
|
||||||
|
OtB6J7UHALyBwF6b6sAFqmVlzEFSW8F7cGmwJY7RgmvpEY1lmhFFAZMCS0mA5GTA
|
||||||
|
Ap4WaAEIHOYhYFhSkSXA0AKiAUMhFgGWIYLx7BYrkUIDzadYqGk61UKL6HI7MFE5
|
||||||
|
0P9OeIhOH/LQqtDgTwvRR6598P/yo6L+iTn4ocmWsK1y/vieH/PXfNt5PM1vMJUk
|
||||||
|
HLt+wPzGxOXV1Z5dxIaWY02BoX2DfW9X571yp/lCT29Y5vlevzsu9am9qGV73PDI
|
||||||
|
Z0lL7fHwXBod07HQW84v//3E3YaI8aVAeqZ3KjG+ZbLQ8XjDWO2Xv1ifMXrqXl2M
|
||||||
|
brwxPe6qCG/ZndVYON/dWfOdOW94bY1kqnjk5nyGbbN+XVdU3fLirth532R5/q8V
|
||||||
|
eUNX23M3vRgXnmHWrUtUPNn2kc6Yzm/80YHTjucPX93R39rF6aqic05srM1sa21U
|
||||||
|
28Obl/cZs+91+Wcnv/Lpm6qnbr020VGXu3M6dCKyJmF6dv7pF0IXmi/HJl8z6k7A
|
||||||
|
9MiNZxv69+/wdm+rrboQ0/MFumZQLL/1Fvl/CHRHLf48szqyrciwhfr4zoa2Uzb7
|
||||||
|
w4J303hH9QJ80zQ9PONdNIRmhd/bPhNzcqfUWrnqSqbYxOpm+ktn6cTHzlzS28/e
|
||||||
|
aqj6fGyffvSQP6IqLGfrwO+HbkflfLr0bBqay0ry1b//7k9NX9+8aDWelkaN131K
|
||||||
|
7Z8N9R+8nPrW64+eG3jp+6wzJfX07QhPaoTdl550aW9fXJ/9wO6L66cnY8S7gWGo
|
||||||
|
2+pQm6fMn9yoGp3KkImTf5l6Th2OPXjk/EyZ8w/bnGtPeO5RT7x3MDdn/5Wqo0c+
|
||||||
|
ygqsNz7nNw27x7LmMn0mg/Ffy+jIVA==
|
||||||
|
=AISr
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
|
||||||
|
And finally, I am proving ownership of this host by posting or
|
||||||
|
appending to this document.
|
||||||
|
|
||||||
|
View my publicly-auditable identity here: https://keybase.io/dananglin
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
|
103
assets/themes/night-owl.json
Normal file
103
assets/themes/night-owl.json
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
{
|
||||||
|
"_pleroma_theme_version": 2,
|
||||||
|
"name": "Free Flow - Night Owl",
|
||||||
|
"theme": {
|
||||||
|
"fonts": {
|
||||||
|
"interface": {
|
||||||
|
"family": "sans-serif"
|
||||||
|
},
|
||||||
|
"input": {
|
||||||
|
"family": "sans-serif"
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"family": "sans-serif"
|
||||||
|
},
|
||||||
|
"postCode": {
|
||||||
|
"family": "monospace"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shadows": {
|
||||||
|
"buttonPressed": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": "10",
|
||||||
|
"spread": "4",
|
||||||
|
"color": "#5d5fc8",
|
||||||
|
"alpha": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -1,
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#FFFFFF",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"button": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": 2,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#3664f3",
|
||||||
|
"alpha": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#FFFFFF",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -1,
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"opacity": {
|
||||||
|
"bg": "0.85"
|
||||||
|
},
|
||||||
|
"colors": {
|
||||||
|
"bg": "#0d0e0f",
|
||||||
|
"text": "#c1c1e7",
|
||||||
|
"link": "#5198c6",
|
||||||
|
"fg": "#0d0e0f",
|
||||||
|
"btn": "#0f2740",
|
||||||
|
"btnText": "#cdcddd",
|
||||||
|
"alertError": "#c3292c",
|
||||||
|
"cRed": "#ff474a",
|
||||||
|
"cBlue": "#0095ff",
|
||||||
|
"cGreen": "#5edea2",
|
||||||
|
"cOrange": "#e1754f"
|
||||||
|
},
|
||||||
|
"radii": {
|
||||||
|
"btn": "3",
|
||||||
|
"input": "0",
|
||||||
|
"checkbox": "0",
|
||||||
|
"panel": "5",
|
||||||
|
"avatar": "2",
|
||||||
|
"avatarAlt": "5",
|
||||||
|
"tooltip": "4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue