club 🦆ito
This commit is contained in:
commit
76d25ba162
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
max_line_length = 120
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.terraform.lock.hcl
|
||||||
|
.terraform
|
14
config.joao.yaml
Normal file
14
config.joao.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
_config: !!joao
|
||||||
|
vault: nidito
|
||||||
|
name: pati.to:club
|
||||||
|
smtp:
|
||||||
|
host: smtp.mailgun.org
|
||||||
|
port: 587
|
||||||
|
username: no-reply@mail.club.pati.to
|
||||||
|
password: !!secret
|
||||||
|
do_token: !!secret
|
||||||
|
cdn:
|
||||||
|
bucket: club-patito
|
||||||
|
endpoint: sjc1.vultrobjects.com
|
||||||
|
key: !!secret
|
||||||
|
secret: !!secret
|
341
gotosocial.yaml
Normal file
341
gotosocial.yaml
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
{{- $domain := "club.pati.to" -}}
|
||||||
|
###########################
|
||||||
|
##### GENERAL CONFIG ######
|
||||||
|
###########################
|
||||||
|
# String. Log level to use throughout the application. Must be lower-case.
|
||||||
|
# Options: ["trace","debug","info","warn","error","fatal"]
|
||||||
|
# Default: "info"
|
||||||
|
log-level: "info"
|
||||||
|
log-db-queries: false
|
||||||
|
|
||||||
|
application-name: "club patito"
|
||||||
|
|
||||||
|
# String. Hostname that this server will be reachable at. Defaults to localhost for local testing,
|
||||||
|
# but you should *definitely* change this when running for real, or your server won't work at all.
|
||||||
|
# DO NOT change this after your server has already run once, or you will break things!
|
||||||
|
# Examples: ["gts.example.org","some.server.com"]
|
||||||
|
# Default: "localhost"
|
||||||
|
host: "{{ $domain }}"
|
||||||
|
|
||||||
|
# String. Domain to use when federating profiles. This is useful when you want your server to be at
|
||||||
|
# eg., "gts.example.org", but you want the domain on accounts to be "example.org" because it looks better
|
||||||
|
# or is just shorter/easier to remember.
|
||||||
|
# To make this setting work properly, you need to redirect requests at "example.org/.well-known/webfinger"
|
||||||
|
# to "gts.example.org/.well-known/webfinger" so that GtS can handle them properly.
|
||||||
|
# You should also redirect requests at "example.org/.well-known/nodeinfo" in the same way.
|
||||||
|
# An empty string (ie., not set) means that the same value as 'host' will be used.
|
||||||
|
# DO NOT change this after your server has already run once, or you will break things!
|
||||||
|
# Examples: ["example.org","server.com"]
|
||||||
|
# Default: ""
|
||||||
|
account-domain: "{{ $domain }}"
|
||||||
|
|
||||||
|
# String. Protocol to use for the server. Only change to http for local testing!
|
||||||
|
# This should be the protocol part of the URI that your server is actually reachable on. So even if you're
|
||||||
|
# running GoToSocial behind a reverse proxy that handles SSL certificates for you, instead of using built-in
|
||||||
|
# letsencrypt, it should still be https.
|
||||||
|
# Options: ["http","https"]
|
||||||
|
# Default: "https"
|
||||||
|
protocol: "https"
|
||||||
|
|
||||||
|
# String. Address to bind the GoToSocial server to.
|
||||||
|
# This can be an IPv4 address or an IPv6 address (surrounded in square brackets), or a hostname.
|
||||||
|
# Default value will bind to all interfaces.
|
||||||
|
# You probably won't need to change this unless you're setting GoToSocial up in some fancy way or
|
||||||
|
# you have specific networking requirements.
|
||||||
|
# Examples: ["0.0.0.0", "172.128.0.16", "localhost", "[::]", "[2001:db8::fed1]"]
|
||||||
|
# Default: "0.0.0.0"
|
||||||
|
bind-address: "0.0.0.0"
|
||||||
|
|
||||||
|
# Int. Listen port for the GoToSocial webserver + API. If you're running behind a reverse proxy and/or in a docker,
|
||||||
|
# container, just set this to whatever you like (or leave the default), and make sure it's forwarded properly.
|
||||||
|
# If you are running with built-in letsencrypt enabled, and running GoToSocial directly on a host machine, you will
|
||||||
|
# probably want to set this to 443 (standard https port), unless you have other services already using that port.
|
||||||
|
# This *MUST NOT* be the same as the letsencrypt port specified below, unless letsencrypt is turned off.
|
||||||
|
# Examples: [443, 6666, 8080]
|
||||||
|
# Default: 8080
|
||||||
|
port: {{ env "NOMAD_PORT_gotosocial" }}
|
||||||
|
|
||||||
|
# Array of string. CIDRs or IP addresses of proxies that should be trusted when determining real client IP from behind a reverse proxy.
|
||||||
|
# If you're running inside a Docker container behind Traefik or Nginx, for example, add the subnet of your docker network,
|
||||||
|
# or the gateway of the docker network, and/or the address of the reverse proxy (if it's not running on the host network).
|
||||||
|
# Example: ["127.0.0.1/32", "172.20.0.1"]
|
||||||
|
# Default: ["127.0.0.1/32", "::1"] (localhost ipv4 + ipv6)
|
||||||
|
trusted-proxies:
|
||||||
|
- "10.100.0.0/20"
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "::1"
|
||||||
|
|
||||||
|
############################
|
||||||
|
##### DATABASE CONFIG ######
|
||||||
|
############################
|
||||||
|
|
||||||
|
# Config pertaining to the Gotosocial database connection
|
||||||
|
|
||||||
|
# String. Database type.
|
||||||
|
# Options: ["postgres","sqlite"]
|
||||||
|
# Default: "postgres"
|
||||||
|
db-type: "sqlite"
|
||||||
|
|
||||||
|
# String. Database address or parameters.
|
||||||
|
#
|
||||||
|
# For Postgres, this should be the address or socket at which the database can be reached.
|
||||||
|
#
|
||||||
|
# For Sqlite, this should be the path to your sqlite database file. Eg., /opt/gotosocial/sqlite.db.
|
||||||
|
# If the file doesn't exist at the specified path, it will be created.
|
||||||
|
# If just a filename is provided (no directory) then the database will be created in the same directory
|
||||||
|
# as the GoToSocial binary.
|
||||||
|
# If address is set to :memory: then an in-memory database will be used (no file).
|
||||||
|
# WARNING: :memory: should NOT BE USED except for testing purposes.
|
||||||
|
#
|
||||||
|
# Examples: ["localhost","my.db.host","127.0.0.1","192.111.39.110",":memory:", "sqlite.db"]
|
||||||
|
# Default: ""
|
||||||
|
db-address: "/alloc/gotosocial.db"
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
##### WEB CONFIG #####
|
||||||
|
######################
|
||||||
|
|
||||||
|
# Config pertaining to templating and serving of web pages/email notifications and the like
|
||||||
|
|
||||||
|
# String. Directory from which gotosocial will attempt to load html templates (.tmpl files).
|
||||||
|
# Examples: ["/some/absolute/path/", "./relative/path/", "../../some/weird/path/"]
|
||||||
|
# Default: "./web/template/"
|
||||||
|
web-template-base-dir: "/gotosocial/web/template/"
|
||||||
|
|
||||||
|
# String. Directory from which gotosocial will attempt to serve static web assets (images, scripts).
|
||||||
|
# Examples: ["/some/absolute/path/", "./relative/path/", "../../some/weird/path/"]
|
||||||
|
# Default: "./web/assets/"
|
||||||
|
web-asset-base-dir: "/gotosocial/web/assets/"
|
||||||
|
|
||||||
|
###########################
|
||||||
|
##### INSTANCE CONFIG #####
|
||||||
|
###########################
|
||||||
|
|
||||||
|
# Config pertaining to instance federation settings, pages to hide/expose, etc.
|
||||||
|
|
||||||
|
# Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=open in order
|
||||||
|
# to see a list of instances that this instance 'peers' with. Even if set to 'false', then authenticated
|
||||||
|
# users (members of the instance) will still be able to query the endpoint.
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: false
|
||||||
|
instance-expose-peers: false
|
||||||
|
|
||||||
|
# Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=suspended in order
|
||||||
|
# to see a list of instances that this instance blocks/suspends. This will also allow unauthenticated
|
||||||
|
# users to see the list through the web UI. Even if set to 'false', then authenticated users (members
|
||||||
|
# of the instance) will still be able to query the endpoint.
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: false
|
||||||
|
instance-expose-suspended: false
|
||||||
|
|
||||||
|
# Bool. This flag tweaks whether GoToSocial will deliver ActivityPub messages
|
||||||
|
# to the shared inbox of a recipient, if one is available, instead of delivering
|
||||||
|
# each message to each actor who should receive a message individually.
|
||||||
|
#
|
||||||
|
# Shared inbox delivery can significantly reduce network load when delivering
|
||||||
|
# to multiple recipients share an inbox (eg., on large Mastodon instances).
|
||||||
|
#
|
||||||
|
# See: https://www.w3.org/TR/activitypub/#shared-inbox-delivery
|
||||||
|
#
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
instance-deliver-to-shared-inboxes: true
|
||||||
|
|
||||||
|
###########################
|
||||||
|
##### ACCOUNTS CONFIG #####
|
||||||
|
###########################
|
||||||
|
|
||||||
|
# Config pertaining to creation and maintenance of accounts on the server, as well as defaults for new accounts.
|
||||||
|
|
||||||
|
# Bool. Do we want people to be able to just submit sign up requests, or do we want invite only?
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
accounts-registration-open: true
|
||||||
|
|
||||||
|
# Bool. Do sign up requests require approval from an admin/moderator before an account can sign in/use the server?
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
accounts-approval-required: true
|
||||||
|
|
||||||
|
# Bool. Are sign up requests required to submit a reason for the request (eg., an explanation of why they want to join the instance)?
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
accounts-reason-required: true
|
||||||
|
|
||||||
|
# Bool. Allow accounts on this instance to set custom CSS for their profile pages and statuses.
|
||||||
|
# Enabling this setting will allow accounts to upload custom CSS via the /user settings page,
|
||||||
|
# which will then be rendered on the web view of the account's profile and statuses.
|
||||||
|
#
|
||||||
|
# For instances with public sign ups, it is **HIGHLY RECOMMENDED** to leave this setting on 'false',
|
||||||
|
# since setting it to true allows malicious accounts to make their profile pages misleading, unusable
|
||||||
|
# or even dangerous to visitors. In other words, you should only enable this setting if you trust
|
||||||
|
# the users on your instance not to produce harmful CSS.
|
||||||
|
#
|
||||||
|
# Regardless of what this value is set to, any uploaded CSS will not be federated to other instances,
|
||||||
|
# it will only be shown on profiles and statuses on *this* instance.
|
||||||
|
#
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: false
|
||||||
|
accounts-allow-custom-css: false
|
||||||
|
|
||||||
|
########################
|
||||||
|
##### MEDIA CONFIG #####
|
||||||
|
########################
|
||||||
|
|
||||||
|
# Config pertaining to media uploads (videos, image, image descriptions, emoji).
|
||||||
|
|
||||||
|
# Int. Maximum allowed image upload size in bytes.
|
||||||
|
# Examples: [2097152, 10485760]
|
||||||
|
# Default: 10485760 -- aka 10MB
|
||||||
|
media-image-max-size: 10485760
|
||||||
|
|
||||||
|
# Int. Maximum allowed video upload size in bytes.
|
||||||
|
# Examples: [2097152, 10485760]
|
||||||
|
# Default: 41943040 -- aka 40MB
|
||||||
|
media-video-max-size: 41943040
|
||||||
|
|
||||||
|
# Int. Minimum amount of characters required as an image or video description.
|
||||||
|
# Examples: [500, 1000, 1500]
|
||||||
|
# Default: 0 (not required)
|
||||||
|
media-description-min-chars: 0
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters permitted in an image or video description.
|
||||||
|
# Examples: [500, 1000, 1500]
|
||||||
|
# Default: 500
|
||||||
|
media-description-max-chars: 500
|
||||||
|
|
||||||
|
# Int. Number of days to cache media from remote instances before they are removed from the cache.
|
||||||
|
# A job will run every day at midnight to clean up any remote media older than the given amount of days.
|
||||||
|
#
|
||||||
|
# When remote media is removed from the cache, it is deleted from storage but the database entries for the media
|
||||||
|
# are kept so that it can be fetched again if requested by a user.
|
||||||
|
#
|
||||||
|
# If this is set to 0, then media from remote instances will be cached indefinitely.
|
||||||
|
# Examples: [30, 60, 7, 0]
|
||||||
|
# Default: 30
|
||||||
|
media-remote-cache-days: 30
|
||||||
|
|
||||||
|
# Int. Max size in bytes of emojis uploaded to this instance via the admin API.
|
||||||
|
# The default is the same as the Mastodon size limit for emojis (50kb), which allows
|
||||||
|
# for good interoperability. Raising this limit may cause issues with federation
|
||||||
|
# of your emojis to other instances, so beware.
|
||||||
|
# Examples: [51200, 102400]
|
||||||
|
# Default: 51200
|
||||||
|
media-emoji-local-max-size: 51200
|
||||||
|
|
||||||
|
# Int. Max size in bytes of emojis to download from other instances.
|
||||||
|
# By default this is 100kb, or twice the size of the default for media-emoji-local-max-size.
|
||||||
|
# This strikes a good balance between decent interoperability with instances that have
|
||||||
|
# higher emoji size limits, and not taking up too much space in storage.
|
||||||
|
# Examples: [51200, 102400]
|
||||||
|
# Default: 51200
|
||||||
|
media-emoji-remote-max-size: 102400
|
||||||
|
|
||||||
|
##########################
|
||||||
|
##### STORAGE CONFIG #####
|
||||||
|
##########################
|
||||||
|
|
||||||
|
# Config pertaining to storage of user-created uploads (videos, images, etc).
|
||||||
|
|
||||||
|
# String. Type of storage backend to use.
|
||||||
|
# Examples: ["local", "s3"]
|
||||||
|
# Default: "local" (storage on local disk)
|
||||||
|
storage-backend: "s3"
|
||||||
|
{{ with secret "cfg/svc/tree/pati.to:club" }}
|
||||||
|
storage-s3-endpoint: "{{ .Data.cdn.endpoint }}"
|
||||||
|
storage-s3-access-key: "{{ .Data.cdn.key }}"
|
||||||
|
storage-s3-secret-key: "{{ .Data.cdn.secret }}"
|
||||||
|
storage-s3-bucket: "{{ .Data.cdn.bucket }}"
|
||||||
|
{{- end }}
|
||||||
|
###########################
|
||||||
|
##### STATUSES CONFIG #####
|
||||||
|
###########################
|
||||||
|
|
||||||
|
# Config pertaining to the creation of statuses/posts, and permitted limits.
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters permitted for a new status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [140, 500, 5000]
|
||||||
|
# Default: 5000
|
||||||
|
statuses-max-chars: 1024
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters allowed in the CW/subject header of a status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [100, 200]
|
||||||
|
# Default: 100
|
||||||
|
statuses-cw-max-chars: 100
|
||||||
|
|
||||||
|
# Int. Maximum amount of options to permit when creating a new poll.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [4, 6, 10]
|
||||||
|
# Default: 6
|
||||||
|
statuses-poll-max-options: 6
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters to permit per poll option when creating a new poll.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [50, 100, 150]
|
||||||
|
# Default: 50
|
||||||
|
statuses-poll-option-max-chars: 50
|
||||||
|
|
||||||
|
# Int. Maximum amount of media files that can be attached to a new status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [4, 6, 10]
|
||||||
|
# Default: 6
|
||||||
|
statuses-media-max-files: 6
|
||||||
|
|
||||||
|
|
||||||
|
#######################
|
||||||
|
##### SMTP CONFIG #####
|
||||||
|
#######################
|
||||||
|
{{ with secret "cfg/svc/tree/pati.to:club" -}}
|
||||||
|
smtp-host: "{{ .Data.smtp.host }}"
|
||||||
|
smtp-port: {{ .Data.smtp.port }}
|
||||||
|
smtp-username: "{{ .Data.smtp.username }}"
|
||||||
|
smtp-password: "{{ .Data.smtp.password }}"
|
||||||
|
smtp-from: "no-reply@mail.{{ $domain }}"
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
#############################
|
||||||
|
##### ADVANCED SETTINGS #####
|
||||||
|
#############################
|
||||||
|
|
||||||
|
# Advanced settings pertaining to http timeouts, security, cookies, and more.
|
||||||
|
#
|
||||||
|
# ONLY ADJUST THESE SETTINGS IF YOU KNOW WHAT YOU ARE DOING!
|
||||||
|
#
|
||||||
|
# Most users will not need to (and should not) touch these settings, since
|
||||||
|
# they are set to sensible defaults, and may break if they are changed.
|
||||||
|
#
|
||||||
|
# Nevertheless, they are provided for the sake of allowing server admins to
|
||||||
|
# tweak their instance for performance or security reasons.
|
||||||
|
|
||||||
|
# String. Value of the SameSite attribute of cookies set by GoToSocial.
|
||||||
|
# Defaults to 'lax' to ensure that the OIDC flow does not break, which is
|
||||||
|
# fine in most cases. If you want to harden your instance against CSRF attacks
|
||||||
|
# and don't mind if some login-related things might break, you can set this
|
||||||
|
# to 'strict' instead.
|
||||||
|
#
|
||||||
|
# For an overview of what this does, see:
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
||||||
|
#
|
||||||
|
# Options: ["lax", "strict"]
|
||||||
|
# Default: "lax"
|
||||||
|
advanced-cookies-samesite: "lax"
|
||||||
|
|
||||||
|
# Int. Amount of requests to permit from a single IP address within a span of 5 minutes.
|
||||||
|
# If this amount is exceeded, a 429 HTTP error code will be returned.
|
||||||
|
# See https://docs.gotosocial.org/en/latest/api/swagger/#rate-limit.
|
||||||
|
#
|
||||||
|
# If you find yourself adjusting this limit because it's regularly being exceeded,
|
||||||
|
# you should first verify that your settings for `trusted-proxies` (above) are correct.
|
||||||
|
# In many cases, when the rate limit is exceeded it is because your instance sees all
|
||||||
|
# incoming requests as coming from the *same IP address* (you can verify this by looking
|
||||||
|
# at the client IPs in your instance logs). If this is the case, try adding that IP
|
||||||
|
# address to your `trusted-proxies` *BEFORE* you go adjusting this rate limit setting!
|
||||||
|
#
|
||||||
|
# If you set this to 0 or less, rate limiting will be disabled entirely.
|
||||||
|
#
|
||||||
|
# Examples: [1000, 500, 0]
|
||||||
|
# Default: 1000
|
||||||
|
advanced-rate-limit-requests: 1000
|
143
gts.nomad
Normal file
143
gts.nomad
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
job "club-patito" {
|
||||||
|
datacenters = ["nyc1"]
|
||||||
|
region = "nyc1"
|
||||||
|
|
||||||
|
vault {
|
||||||
|
policies = ["club-patito"]
|
||||||
|
|
||||||
|
change_mode = "signal"
|
||||||
|
change_signal = "SIGHUP"
|
||||||
|
}
|
||||||
|
|
||||||
|
group "club-patito" {
|
||||||
|
reschedule {
|
||||||
|
delay = "5s"
|
||||||
|
delay_function = "fibonacci"
|
||||||
|
max_delay = "5m"
|
||||||
|
unlimited = true
|
||||||
|
}
|
||||||
|
|
||||||
|
restart {
|
||||||
|
attempts = 60
|
||||||
|
interval = "10m"
|
||||||
|
delay = "10s"
|
||||||
|
mode = "delay"
|
||||||
|
}
|
||||||
|
|
||||||
|
network {
|
||||||
|
mode = "host"
|
||||||
|
port "gotosocial" {
|
||||||
|
host_network = "private"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "db-restore" {
|
||||||
|
lifecycle {
|
||||||
|
hook = "prestart"
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = "docker"
|
||||||
|
user = "nobody"
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 128
|
||||||
|
memory = 64
|
||||||
|
memory_max = 512
|
||||||
|
}
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "litestream/litestream:0.3.9"
|
||||||
|
args = ["restore", "/alloc/gotosocial.db"]
|
||||||
|
volumes = ["secrets/litestream.yaml:/etc/litestream.yml"]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = file("litestream.yaml")
|
||||||
|
destination = "secrets/litestream.yaml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "db-replicate" {
|
||||||
|
lifecycle {
|
||||||
|
hook = "prestart"
|
||||||
|
sidecar = true
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = "docker"
|
||||||
|
user = "nobody"
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 256
|
||||||
|
memory = 128
|
||||||
|
memory_max = 512
|
||||||
|
}
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "litestream/litestream:0.3.9"
|
||||||
|
args = ["replicate"]
|
||||||
|
volumes = ["secrets/litestream.yaml:/etc/litestream.yml"]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = file("litestream.yaml")
|
||||||
|
destination = "secrets/litestream.yaml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "gotosocial" {
|
||||||
|
driver = "docker"
|
||||||
|
user = "nobody"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "superseriousbusiness/gotosocial:0.6.0"
|
||||||
|
ports = ["gotosocial"]
|
||||||
|
args = [
|
||||||
|
"--config-path",
|
||||||
|
"/secrets/gotosocial.yaml",
|
||||||
|
"server",
|
||||||
|
"start"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = file("gotosocial.yaml")
|
||||||
|
destination = "secrets/gotosocial.yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 256
|
||||||
|
memory = 512
|
||||||
|
memory_max = 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "gotosocial"
|
||||||
|
port = "gotosocial"
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"nidito.service",
|
||||||
|
"nidito.dns.enabled",
|
||||||
|
"nidito.http.enabled",
|
||||||
|
"nidito.http.public",
|
||||||
|
"nidito.ingress.enabled",
|
||||||
|
]
|
||||||
|
|
||||||
|
meta {
|
||||||
|
nidito-acl = "allow external"
|
||||||
|
nidito-http-buffering = "off"
|
||||||
|
nidito-http-tls = "pati.to"
|
||||||
|
nidito-http-domain = "club.pati.to"
|
||||||
|
nidito-http-wss = "on"
|
||||||
|
nidito-http-max-body-size = "40m"
|
||||||
|
}
|
||||||
|
|
||||||
|
check {
|
||||||
|
name = "gotosocial"
|
||||||
|
type = "tcp"
|
||||||
|
interval = "10s"
|
||||||
|
timeout = "2s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
litestream.yaml
Normal file
9
litestream.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{{- with secret "cfg/infra/tree/provider:cdn" }}
|
||||||
|
access-key-id: {{ .Data.key }}
|
||||||
|
secret-access-key: {{ .Data.secret }}
|
||||||
|
|
||||||
|
dbs:
|
||||||
|
- path: /alloc/gotosocial.db
|
||||||
|
replicas:
|
||||||
|
- url: s3://{{ .Data.bucket }}.{{ .Data.endpoint }}/club-patito/gotosocial.db
|
||||||
|
{{- end }}
|
145
main.tf
Normal file
145
main.tf
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
terraform {
|
||||||
|
backend "consul" {
|
||||||
|
path = "nidito/state/service/club-patito"
|
||||||
|
}
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
acme = {
|
||||||
|
source = "vancluever/acme"
|
||||||
|
version = "~> 2.5.3"
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalocean = {
|
||||||
|
source = "digitalocean/digitalocean"
|
||||||
|
version = "~> 2.16.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
vault = {
|
||||||
|
source = "hashicorp/vault"
|
||||||
|
version = "~> 3.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
required_version = ">= 1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
policies = {
|
||||||
|
"sys/capabilities-self" = ["update"]
|
||||||
|
"auth/token/renew-self" = ["update"]
|
||||||
|
"config/kv/provider:cdn" = ["read"]
|
||||||
|
"config/kv/pati.to:club" = ["read"]
|
||||||
|
"cfg/infra/tree/provider:cdn" = ["read"]
|
||||||
|
"cfg/svc/tree/pati.to:club" = ["read"]
|
||||||
|
}
|
||||||
|
|
||||||
|
mx_servers = {
|
||||||
|
"mxa.mailgun.org." = 10,
|
||||||
|
"mxb.mailgun.org." = 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "acme" {
|
||||||
|
server_url = "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO tokens for compute resources
|
||||||
|
data "vault_generic_secret" "DO" {
|
||||||
|
path = "cfg/infra/tree/provider:digitalocean"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "digitalocean" {
|
||||||
|
token = data.vault_generic_secret.DO.data.patito
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "digitalocean" {
|
||||||
|
alias = "compute"
|
||||||
|
token = data.vault_generic_secret.DO.data.token
|
||||||
|
}
|
||||||
|
|
||||||
|
data "digitalocean_droplet" "bedstuy" {
|
||||||
|
provider = digitalocean.compute
|
||||||
|
name = "bedstuy"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vault_policy" "service" {
|
||||||
|
name = "club-patito"
|
||||||
|
policy = <<-HCL
|
||||||
|
%{ for path in sort(keys(local.policies)) }path "${path}" {
|
||||||
|
capabilities = ${jsonencode(local.policies[path])}
|
||||||
|
}
|
||||||
|
|
||||||
|
%{ endfor }
|
||||||
|
HCL
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "to_pati_club" {
|
||||||
|
domain = "pati.to"
|
||||||
|
type = "A"
|
||||||
|
ttl = 3600
|
||||||
|
name = "club"
|
||||||
|
value = data.digitalocean_droplet.bedstuy.ipv4_address
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "txt_smtp_domainkey" {
|
||||||
|
domain = "pati.to"
|
||||||
|
type = "TXT"
|
||||||
|
name = "mailo._domainkey.mail.club"
|
||||||
|
value = "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG2sUJLqDOqMnjMy3+fNI0rdrGb8VrI84yloaXE9R8aLEXkm0jlANiFEmVF7s7ZvoDoKm0v5Lm/JsvM/Rl8n9TS2QYMqhmVsEmuBHwOVhekUDW/LKvfDxfNhmbquvU4z+/fn2WBx19dLG3Ctao7pbL7B9TKR+sPJUNoFWRseucMQIDAQAB"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "txt_spf" {
|
||||||
|
domain = "pati.to"
|
||||||
|
type = "TXT"
|
||||||
|
name = "mail.club"
|
||||||
|
value = "v=spf1 include:mailgun.org ~all;"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "mx" {
|
||||||
|
for_each = local.mx_servers
|
||||||
|
domain = "pati.to"
|
||||||
|
type = "MX"
|
||||||
|
name = "mail.club"
|
||||||
|
value = each.key
|
||||||
|
priority = each.value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data "terraform_remote_state" "registration" {
|
||||||
|
backend = "consul"
|
||||||
|
workspace = "default"
|
||||||
|
config = {
|
||||||
|
address = "consul.service.casa.consul:5554"
|
||||||
|
scheme = "https"
|
||||||
|
path = "nidito/state/letsencrypt/registration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource acme_certificate cert {
|
||||||
|
account_key_pem = data.terraform_remote_state.registration.outputs.account_key
|
||||||
|
common_name = "pati.to"
|
||||||
|
subject_alternative_names = ["*.pati.to"]
|
||||||
|
recursive_nameservers = ["1.1.1.1:53", "8.8.8.8:53"]
|
||||||
|
|
||||||
|
dns_challenge {
|
||||||
|
provider = "digitalocean"
|
||||||
|
config = {
|
||||||
|
DO_AUTH_TOKEN = data.vault_generic_secret.DO.data.patito
|
||||||
|
DO_PROPAGATION_TIMEOUT = 60
|
||||||
|
DO_TTL = 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource vault_generic_secret cert {
|
||||||
|
path = "nidito/tls/${acme_certificate.cert.common_name}"
|
||||||
|
data_json = jsonencode({
|
||||||
|
private_key = acme_certificate.cert.private_key_pem,
|
||||||
|
cert = join("", [
|
||||||
|
acme_certificate.cert.certificate_pem,
|
||||||
|
acme_certificate.cert.issuer_pem,
|
||||||
|
])
|
||||||
|
issuer = acme_certificate.cert.issuer_pem,
|
||||||
|
bare_cert = acme_certificate.cert.certificate_pem,
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user