First commit
This commit is contained in:
4
bundles.yml
Normal file
4
bundles.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
dependencies:
|
||||
- url: ../common.git
|
3
consul/config/service-defaults/plausible.hcl
Normal file
3
consul/config/service-defaults/plausible.hcl
Normal file
@ -0,0 +1,3 @@
|
||||
Kind = "service-defaults"
|
||||
Name = "[[ .instance ]][[ .consul.suffix ]]"
|
||||
Protocol = "http"
|
16
consul/config/service-intentions/plausible.hcl
Normal file
16
consul/config/service-intentions/plausible.hcl
Normal file
@ -0,0 +1,16 @@
|
||||
Kind = "service-intentions"
|
||||
Name = "[[ .instance ]][[ .consul.suffix ]]"
|
||||
Sources = [
|
||||
{
|
||||
Name = "[[ (merge .plausible.server .plausible .).traefik.instance ]]"
|
||||
Permissions = [
|
||||
{
|
||||
Action = "allow"
|
||||
HTTP {
|
||||
PathPrefix = "/"
|
||||
Methods = ["GET", "HEAD", "POST", "OPTIONS"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
2
images/clickhouse/Dockerfile
Normal file
2
images/clickhouse/Dockerfile
Normal file
@ -0,0 +1,2 @@
|
||||
FROM clickhouse/clickhouse-server:[[ .plausible.clickhouse.version ]]-alpine
|
||||
LABEL maintainer="[[ .docker.maintainer ]]"
|
9
images/plausible-proxmox-backup/Dockerfile
Normal file
9
images/plausible-proxmox-backup/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM [[ .docker.repo ]][[ .docker.base_images.pbc.image ]]
|
||||
|
||||
LABEL maintainer="[[ .docker.maintainer ]]"
|
||||
|
||||
RUN set -euxo pipefail &&\
|
||||
apt update &&\
|
||||
apt install -y --no-install-recommends clickhouse-client &&\
|
||||
rm -rf /var/lib/apt/lists/* &&\
|
||||
rm -rf /var/cache/apt/archives
|
9
images/plausible/Dockerfile
Normal file
9
images/plausible/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM ghcr.io/plausible/community-edition:v[[ .plausible.server.version ]]
|
||||
LABEL maintainer="[[ .docker.maintainer ]]"
|
||||
|
||||
USER root
|
||||
|
||||
RUN set -euxo pipefail &&\
|
||||
apk add --no-cache postgresql16-client
|
||||
|
||||
USER plausible
|
11
images/plausible/root/usr/local/bin/plausible
Executable file
11
images/plausible/root/usr/local/bin/plausible
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
TABLE_EXISTS=$(psql -Aqtc "SELECT 1 FROM information_schema.tables WHERE table_schema='public' AND table_name='schema_migrations'" 2>&1)
|
||||
if [ "${TABLE_EXISTS}" != "1" ]; then
|
||||
echo "Starting database initialization"
|
||||
psql -f /app/lib/plausible-0.0.1/priv/repo/structure.sql
|
||||
else
|
||||
/entrypoint.sh db migrate
|
||||
fi
|
||||
|
||||
exec /entrypoint.sh run
|
5
init/plausible-vault-database
Executable file
5
init/plausible-vault-database
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
[[ template "common/vault.mkpgrole.sh.tpl" merge .plausible.server . ]]
|
139
plausible.nomad.hcl
Normal file
139
plausible.nomad.hcl
Normal file
@ -0,0 +1,139 @@
|
||||
job "[[ .instance ]]" {
|
||||
[[ template "common/job_start" . ]]
|
||||
|
||||
group "plausible" {
|
||||
[[- $c := merge .plausible . ]]
|
||||
[[ template "common/group_start" $c ]]
|
||||
|
||||
network {
|
||||
mode = "bridge"
|
||||
[[- if conv.ToBool $c.metrics.enabled ]]
|
||||
port "metrics" {}
|
||||
[[- end ]]
|
||||
}
|
||||
|
||||
[[ template "common/volumes" merge $c.clickhouse $c ]]
|
||||
|
||||
service {
|
||||
name = "[[ .instance ]][[ .consul.suffix ]]"
|
||||
port = 8000
|
||||
[[ template "common/service_meta" $c ]]
|
||||
[[ template "common/connect" $c ]]
|
||||
|
||||
check {
|
||||
name = "health"
|
||||
type = "http"
|
||||
path = "/api/health"
|
||||
expose = true
|
||||
[[ template "common/check_settings" $c ]]
|
||||
check_restart {
|
||||
limit = 10
|
||||
grace = "15m"
|
||||
}
|
||||
}
|
||||
|
||||
tags = [
|
||||
[[ template "common/traefik_tags" merge $c.events $c ]]
|
||||
[[ template "common/traefik_tags" merge $c.server $c ]]
|
||||
]
|
||||
}
|
||||
|
||||
[[ template "common/task.wait_for" $c ]]
|
||||
[[ template "common/task.chown_volumes" merge $c.clickhouse $c ]]
|
||||
[[ template "common/task.pgbouncer" $c ]]
|
||||
[[ template "common/task.proxmox_backup" $c ]]
|
||||
[[ template "common/task.metrics_proxy" $c ]]
|
||||
[[ template "common/task.socat_proxy" $c ]]
|
||||
|
||||
task "clickhouse" {
|
||||
[[- $d := merge $c.clickhouse $c ]]
|
||||
driver = "[[ $d.nomad.driver ]]"
|
||||
|
||||
lifecycle {
|
||||
hook = "prestart"
|
||||
sidecar = true
|
||||
}
|
||||
|
||||
config {
|
||||
image = "[[ $d.image ]]"
|
||||
pids_limit = 1000
|
||||
ulimit {
|
||||
nofile = "262144:262144"
|
||||
}
|
||||
volumes = [
|
||||
"local/clickhouse.xml:/etc/clickhouse-server/config.d/docker_related_config.xml:ro",
|
||||
]
|
||||
}
|
||||
|
||||
env {
|
||||
CLICKHOUSE_DB = "plausible_events_db"
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
[[ template "plausible/clickhouse.xml" $d ]]
|
||||
_EOT
|
||||
destination = "local/clickhouse.xml"
|
||||
}
|
||||
|
||||
[[ template "common/artifacts" $d ]]
|
||||
[[ template "common/templates" $d ]]
|
||||
[[ template "common/volumes_mount" $d ]]
|
||||
[[ template "common/resources" $d ]]
|
||||
}
|
||||
|
||||
task "plausible" {
|
||||
[[- $e := merge $c.server $c ]]
|
||||
driver = "[[ $e.nomad.driver ]]"
|
||||
leader = true
|
||||
|
||||
config {
|
||||
[[ template "common/image" $e ]]
|
||||
pids_limit = 500
|
||||
command = "sh"
|
||||
args = [
|
||||
"-c",
|
||||
"/entrypoint.sh db migrate && /entrypoint.sh run"
|
||||
]
|
||||
}
|
||||
|
||||
env {
|
||||
LISTEN_IP = "127.0.0.1"
|
||||
HTTP_PORT = 8000
|
||||
ERL_EPMD_ADDRESS = "127.0.0.1"
|
||||
ERL_MAX_PORTS = 1024
|
||||
RELEASE_VM_ARGS = "/local/vm.args"
|
||||
RELEASE_TMP = "/local/tmp"
|
||||
TMPDIR = "/local/tmp"
|
||||
}
|
||||
|
||||
[[ template "common/file_env" $e ]]
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
CLICKHOUSE_DATABASE_URL=http://127.0.0.1:8123/plausible_events_db
|
||||
[[- if ne $c.postgres.pooler.engine "none" ]]
|
||||
DATABASE_URL=postgresql://[[ .instance ]]:{{ env "NOMAD_ALLOC_ID" }}@127.0.0.1:[[ $c.postgres.pooler.port ]]/[[ $c.postgres.database ]]
|
||||
[[- else ]]
|
||||
DATABASE_URL=postgresql://[[ $c.postgres.user ]]:[[ $c.postgres.password | regexp.Replace "\\.Data\\.password" "urlquery .Data.password" ]]@[[ $c.postgres.host ]]:[[ $c.postgres.port ]]/[[ $c.postgres.database ]]
|
||||
[[- end ]]
|
||||
_EOT
|
||||
destination = "secrets/.env.db"
|
||||
uid = [[ 0 | add $e.docker.userns.uid_shift ]]
|
||||
gid = [[ 0 | add $e.docker.userns.gid_shift ]]
|
||||
perms = 400
|
||||
env = true
|
||||
}
|
||||
|
||||
template {
|
||||
data = "-kernel inet_dist_use_interface {127,0,0,1}"
|
||||
destination = "local/vm.args"
|
||||
}
|
||||
|
||||
[[ template "common/vault.policies" $e ]]
|
||||
[[ template "common/artifacts" $e ]]
|
||||
[[ template "common/templates" $e ]]
|
||||
[[ template "common/resources" $e ]]
|
||||
}
|
||||
}
|
||||
}
|
5
prep.d/10-plausible-rand-secrets
Executable file
5
prep.d/10-plausible-rand-secrets
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
[[ template "common/vault.rand_secrets" merge .plausible.server .plausible . ]]
|
55
templates/clickhouse.xml
Normal file
55
templates/clickhouse.xml
Normal file
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
This is a merge of config snippets from
|
||||
https://github.com/plausible/community-edition/tree/v2.1.5/clickhouse
|
||||
-->
|
||||
<clickhouse>
|
||||
<listen_host>127.0.0.1</listen_host>
|
||||
<mysql_port remove="true"/>
|
||||
<postgresql_port remove="true"/>
|
||||
<interserver_http_port remove="true"/>
|
||||
<cgroups_memory_usage_observer_wait_time>0</cgroups_memory_usage_observer_wait_time>
|
||||
<logger>
|
||||
<level>warning</level>
|
||||
<console>true</console>
|
||||
</logger>
|
||||
|
||||
<query_log replace="1">
|
||||
<database>system</database>
|
||||
<table>query_log</table>
|
||||
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
||||
<engine>
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY event_date
|
||||
ORDER BY (event_time)
|
||||
TTL event_date + interval 30 day
|
||||
SETTINGS ttl_only_drop_parts=1
|
||||
</engine>
|
||||
</query_log>
|
||||
|
||||
<!-- Stops unnecessary logging -->
|
||||
<metric_log remove="remove" />
|
||||
<asynchronous_metric_log remove="remove" />
|
||||
<query_thread_log remove="remove" />
|
||||
<text_log remove="remove" />
|
||||
<trace_log remove="remove" />
|
||||
<session_log remove="remove" />
|
||||
<part_log remove="remove" />
|
||||
<mark_cache_size>524288000</mark_cache_size>
|
||||
|
||||
<profile>
|
||||
<default>
|
||||
<!-- https://clickhouse.com/docs/en/operations/settings/settings#max_threads -->
|
||||
<max_threads>1</max_threads>
|
||||
<!-- https://clickhouse.com/docs/en/operations/settings/settings#max_block_size -->
|
||||
<max_block_size>8192</max_block_size>
|
||||
<!-- https://clickhouse.com/docs/en/operations/settings/settings#max_download_threads -->
|
||||
<max_download_threads>1</max_download_threads>
|
||||
<!--
|
||||
https://clickhouse.com/docs/en/operations/settings/settings#input_format_parallel_parsing -->
|
||||
<input_format_parallel_parsing>0</input_format_parallel_parsing>
|
||||
<!--
|
||||
https://clickhouse.com/docs/en/operations/settings/settings#output_format_parallel_formatting -->
|
||||
<output_format_parallel_formatting>0</output_format_parallel_formatting>
|
||||
</default>
|
||||
</profile>
|
||||
</clickhouse>
|
27
templates/proxmox-backup.sh
Normal file
27
templates/proxmox-backup.sh
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p /local/backups/clickhouse
|
||||
echo "Dumping the database"
|
||||
retry -d 1,2,4,8 --times=5 pg_dump -Fc --compress=zstd -f /local/backups/plausible.custom
|
||||
# To restore, use something like
|
||||
# zstd -dc /local/backups/clickhouse/plausible_events_db_events_data.tsv.zst | clickhouse-client --query="INSERT INTO plausible_events_db.events_data FORMAT TabSeparated";
|
||||
DB=plausible_events_db
|
||||
while read -r TABLE ; do
|
||||
if echo -n ${TABLE} | grep -q '\.inner\.' > /dev/null 2>&1; then
|
||||
echo "skip materialized view ${TABLE} (${DB})"
|
||||
continue;
|
||||
fi
|
||||
echo "export table ${TABLE} from database ${DB}"
|
||||
# dump schema
|
||||
clickhouse-client -q "SHOW CREATE TABLE ${DB}.${TABLE}" > "/local/backups/clickhouse/${DB}_${TABLE}_schema.sql"
|
||||
# dump
|
||||
clickhouse-client -q "SELECT * FROM ${DB}.${TABLE} FORMAT TabSeparated" | zstd -c > "/local/backups/clickhouse/${DB}_${TABLE}_data.tsv.zst"
|
||||
done < <(clickhouse-client -q "SHOW TABLES FROM ${DB}")
|
||||
|
||||
echo "Sending data to Proxmox Backup Server"
|
||||
[[ template "common/pbs_backup" . ]] data.pxar:/local/backups
|
||||
|
||||
echo "Removing dumps"
|
||||
rm -rf /local/backups
|
110
variables.yml
Normal file
110
variables.yml
Normal file
@ -0,0 +1,110 @@
|
||||
---
|
||||
|
||||
# Name of this instance
|
||||
instance: plausible
|
||||
|
||||
plausible:
|
||||
|
||||
# Consul settings
|
||||
consul:
|
||||
connect:
|
||||
# COnnect to postgres and smtp through the mesh
|
||||
upstreams:
|
||||
- destination_name: postgres[[ .consul.suffix ]]
|
||||
local_bind_port: 5432
|
||||
- destination_name: '[[ .mail.smtp_service_name ]]'
|
||||
local_bind_port: 25
|
||||
|
||||
# Vault settings
|
||||
vault:
|
||||
# We need a secret key and a totp vault with exact length, so use custom commands
|
||||
rand_secrets:
|
||||
- fields:
|
||||
- secret_key_base
|
||||
cmd: openssl rand -base64 48
|
||||
- fields:
|
||||
- totp_vault_key
|
||||
cmd: openssl rand -base64 32
|
||||
|
||||
# Public URL where plausible is exposed
|
||||
public_url: https://plausible.example.org
|
||||
|
||||
# Plausible server settings
|
||||
server:
|
||||
# Version of plausible to deploy
|
||||
version: 2.1.5
|
||||
|
||||
# Docker image to use
|
||||
image: '[[ .docker.repo ]]plausible:[[ .plausible.server.version ]]-1'
|
||||
|
||||
# Env vars to set in the container
|
||||
env:
|
||||
BASE_URL: '[[ .plausible.public_url ]]'
|
||||
MAILER_EMAIL: '[[ .instance ]]@[[ .consul.domain ]]'
|
||||
SMTP_HOST_ADDR: 127.0.0.1
|
||||
SMTP_HOST_PORT: 25
|
||||
SECRET_KEY_BASE: '{{ with secret "[[ .vault.root ]]kv/service/[[ .instance ]]" }}{{ .Data.data.secret_key_base }}{{ end }}'
|
||||
TOTP_VAULT_KEY: '{{ with secret "[[ .vault.root ]]kv/service/[[ .instance ]]" }}{{ .Data.data.totp_vault_key }}{{ end }}'
|
||||
DISABLE_REGISTRATION: invite_only
|
||||
ENABLE_EMAIL_VERIFICATION: true
|
||||
LOG_FAILED_LOGIN_ATTEMPTS: true
|
||||
|
||||
# Resource allocation
|
||||
resources:
|
||||
cpu: 300
|
||||
memory: 512
|
||||
memory_max: 768
|
||||
|
||||
# Traefik settings
|
||||
# Use an explicit priority to ensure the events are handled first
|
||||
traefik:
|
||||
priority: 50
|
||||
|
||||
# Events (clients facing parts) are handled in a separated router so you can apply different middlewares
|
||||
events:
|
||||
traefik:
|
||||
rule: Host(`[[ (urlParse .plausible.public_url).Hostname ]]`) && (Path(`/api/events`) && Method(`POST`) || Path(`/js/script.js`) && Method(`GET`))
|
||||
router: events
|
||||
csp: false
|
||||
priority: 100
|
||||
middlewares:
|
||||
cors:
|
||||
- headers.accesscontrolalloworiginlist=*
|
||||
|
||||
# Clickhouse settings
|
||||
clickhouse:
|
||||
|
||||
# Clickhouse version to use
|
||||
version: 24.3.3.102
|
||||
|
||||
# Docker image to use
|
||||
image: '[[ .docker.repo ]]clickhouse:[[ .plausible.clickhouse.version ]]-1'
|
||||
|
||||
# Env vars to set in the container
|
||||
env: {}
|
||||
|
||||
# Resource allocation
|
||||
resources:
|
||||
cpu: 500
|
||||
memory: 644
|
||||
memory_max: 768
|
||||
|
||||
# VOlumes for data persistence
|
||||
volumes:
|
||||
clickhouse:
|
||||
source: '[[ .instance ]]-clickhouse'
|
||||
type: csi
|
||||
destination: /var/lib/clickhouse
|
||||
owner: 101
|
||||
group: 101
|
||||
|
||||
# Proxmox Backup settings
|
||||
proxmox_backup:
|
||||
user: 101:101
|
||||
# We use a custom Docker image to have a clickhouse-client available
|
||||
image: '[[ .docker.repo ]]plausible-proxmox-backup:[[ .docker.base_images.pbc.image | regexp.Replace "^.*:" "" ]]'
|
||||
postgres: true
|
||||
hooks:
|
||||
plausible:
|
||||
type: template
|
||||
source: plausible/proxmox-backup.sh
|
6
vault/policies/plausible.hcl
Normal file
6
vault/policies/plausible.hcl
Normal file
@ -0,0 +1,6 @@
|
||||
path "[[ .vault.root ]]kv/data/service/[[ .instance ]]" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "[[ .vault.root ]]database/creds/[[ .instance ]]" {
|
||||
capabilities = ["read"]
|
||||
}
|
1
vault/roles/plausible.json
Normal file
1
vault/roles/plausible.json
Normal file
@ -0,0 +1 @@
|
||||
[[ template "common/vault.jwt_role" merge .plausible.server .plausible . ]]
|
Reference in New Issue
Block a user