Add postgres + WIP plume + fix diplonat

This commit is contained in:
Quentin 2022-08-24 19:54:15 +02:00
parent 1172e8e511
commit 00b754727d
Signed by: quentin
GPG key ID: E9602264D639FF68
25 changed files with 553 additions and 3 deletions

View file

@ -1,5 +1,5 @@
job "core" { job "core" {
datacenters = ["dc1", "neptune"] datacenters = ["orion", "neptune"]
type = "system" type = "system"
priority = 90 priority = 90
@ -21,6 +21,7 @@ job "core" {
image = "lxpz/amd64_diplonat:4" image = "lxpz/amd64_diplonat:4"
network_mode = "host" network_mode = "host"
readonly_rootfs = true readonly_rootfs = true
privileged = true
volumes = [ volumes = [
"secrets:/etc/diplonat", "secrets:/etc/diplonat",
] ]

View file

@ -0,0 +1,8 @@
version: '3.4'
services:
plume:
build:
context: ./plume
args:
VERSION: 8709f6cf9f8ff7e3c5ee7ea699ee7c778e92fefc
image: superboum/plume:v8

View file

@ -0,0 +1,54 @@
FROM rust:1.58.1-slim-bullseye as builder
RUN apt-get update && \
apt-get install -y \
pkg-config \
git \
curl \
postgresql \
postgresql-contrib \
libpq-dev \
gettext \
git \
python \
curl \
gcc \
make \
openssl \
libssl-dev \
libclang-dev
ARG VERSION
WORKDIR /opt
RUN git clone -n https://git.joinplu.me/Plume/Plume.git plume
WORKDIR /opt/plume
RUN git checkout ${VERSION}
WORKDIR /opt/plume/script
RUN chmod a+x ./wasm-deps.sh && ./wasm-deps.sh
WORKDIR /opt/plume
RUN cargo install wasm-pack
RUN chmod a+x ./script/plume-front.sh && ./script/plume-front.sh
RUN cargo install --path ./ --force --no-default-features --features postgres
RUN cargo install --path plume-cli --force --no-default-features --features postgres
RUN cargo clean
#-----------------------------
FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
libpq5 \
libssl1.1 \
rclone \
fuse
WORKDIR /app
COPY --from=builder /opt/plume /app
COPY --from=builder /usr/local/cargo/bin/plm /usr/local/bin/
COPY --from=builder /usr/local/cargo/bin/plume /usr/local/bin/
CMD ["plume"]

View file

@ -0,0 +1,3 @@
Try build:
sudo docker build -t superboum/plume:v1 --build-arg VERSION=003dcf861a9f55720b03d52f2f95f5f59e338809 .

View file

@ -0,0 +1,32 @@
BASE_URL=plume.deuxfleurs.fr
# generate one with openssl rand -base64 32
ROCKET_SECRET_KEY={{ key "secrets/plume/secret_key" | trimSpace }}
# Mail settings
#MAIL_SERVER=smtp.example.org
#MAIL_USER=example
#MAIL_PASSWORD=123456
#MAIL_HELO_NAME=example.org
# DATABASE SETUP
POSTGRES_PASSWORD={{ key "secrets/plume/pgsql_pw" | trimSpace }}
POSTGRES_USER=plume
POSTGRES_DB=plume
DATABASE_URL=postgres://plume:{{ key "secrets/plume/pgsql_pw" | trimSpace }}@psql-proxy.service.prod.consul:5432/plume
MIGRATION_DIRECTORY=migrations/postgres
USE_HTTPS=0
ROCKET_ADDRESS=::
ROCKET_PORT={{ env "NOMAD_PORT_web_port" }}
MEDIA_UPLOAD_DIRECTORY=/app/static/media
SEARCH_INDEX=/app/search_index
LDAP_ADDR=ldap://bottin.service.prod.consul:389
LDAP_BASE_DN=ou=users,dc=deuxfleurs,dc=fr
LDAP_USER_NAME_ATTR=cn
LDAP_USER_MAIL_ATTR=mail
LDAP_TLS=false
RUST_BACKTRACE=1
RUST_LOG=info

View file

@ -0,0 +1,82 @@
job "plume-blog" {
datacenters = ["dc1"]
type = "service"
constraint {
attribute = "${attr.cpu.arch}"
value = "amd64"
}
group "plume" {
count = 1
network {
port "web_port" { }
}
task "plume" {
constraint {
attribute = "${attr.unique.hostname}"
operator = "="
value = "digitale"
}
driver = "docker"
config {
image = "superboum/plume:v8"
network_mode = "host"
ports = [ "web_port" ]
#command = "cat"
#args = [ "/dev/stdout" ]
volumes = [
"/mnt/ssd/plume/search_index:/app/search_index",
"/mnt/ssd/plume/media:/app/static/media"
]
}
template {
data = file("../config/app.env")
destination = "secrets/app.env"
env = true
}
resources {
memory = 500
cpu = 100
}
service {
name = "plume"
tags = [
"plume",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:plume.deuxfleurs.fr",
"tricot plume.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
check {
type = "http"
protocol = "http"
port = "web_port"
path = "/"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "600s"
ignore_warnings = false
}
}
}
restart {
interval = "30m"
attempts = 20
delay = "15s"
mode = "delay"
}
}
}
}

View file

@ -0,0 +1,31 @@
{
"suffix": "dc=deuxfleurs,dc=fr",
"bind": "0.0.0.0:389",
"consul_host": "http://consul:8500",
"log_level": "debug",
"acl": [
"*,dc=deuxfleurs,dc=fr::read:*:* !userpassword",
"*::read modify:SELF:*",
"ANONYMOUS::bind:*,ou=users,dc=deuxfleurs,dc=fr:",
"ANONYMOUS::bind:cn=admin,dc=deuxfleurs,dc=fr:",
"*,ou=services,ou=users,dc=deuxfleurs,dc=fr::bind:*,ou=users,dc=deuxfleurs,dc=fr:*",
"*,ou=services,ou=users,dc=deuxfleurs,dc=fr::read:*:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:add:*,ou=invitations,dc=deuxfleurs,dc=fr:*",
"ANONYMOUS::bind:*,ou=invitations,dc=deuxfleurs,dc=fr:",
"*,ou=invitations,dc=deuxfleurs,dc=fr::delete:SELF:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:add:*,ou=users,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::add:*,ou=users,dc=deuxfleurs,dc=fr:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=seafile,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=seafile,ou=groups,dc=deuxfleurs,dc=fr:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=nextcloud,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=seafile,ou=nextcloud,dc=deuxfleurs,dc=fr:*",
"cn=admin,dc=deuxfleurs,dc=fr::read add modify delete:*:*",
"*:cn=admin,ou=groups,dc=deuxfleurs,dc=fr:read add modify delete:*:*"
]
}

View file

@ -0,0 +1,28 @@
version: '3.4'
services:
plume:
image: superboum/plume:v1
env_file:
- plume.env
depends_on:
- consul
- postgres
ports:
- "7878:7878"
postgres:
image: postgres:9.6.19
environment:
- POSTGRES_DB=plume
- POSTGRES_USER=plume
- POSTGRES_PASSWORD=plume
bottin:
image: lxpz/bottin_amd64:14
depends_on:
- consul
volumes:
- ./bottin.json:/config.json
consul:
image: consul:1.8.4

View file

@ -0,0 +1,31 @@
BASE_URL=integration.env
# generate one with openssl rand -base64 32
ROCKET_SECRET_KEY=cXZbKoxWIBo0wdaD8tbA1B3BlH2LBSUmgzdyZZr8QxI=
# Mail settings
#MAIL_SERVER=smtp.example.org
#MAIL_USER=example
#MAIL_PASSWORD=123456
#MAIL_HELO_NAME=example.org
# DATABASE SETUP
POSTGRES_PASSWORD=plume
POSTGRES_USER=plume
POSTGRES_DB=plume
DATABASE_URL=postgres://plume:plume@postgres:5432/plume
MIGRATION_DIRECTORY=migrations/postgres
USE_HTTPS=0
ROCKET_ADDRESS=0.0.0.0
ROCKET_PORT=7878
MEDIA_UPLOAD_DIRECTORY=/app/static/media
SEARCH_INDEX=/app/search_index
DOMAIN_NAME="integration.env"
INSTANCE_NAME="Integration Instance"
LDAP_ADDR=ldap://bottin:389
LDAP_BASE_DN=ou=users,dc=deuxfleurs,dc=fr
LDAP_USER_NAME_ATTR=cn
LDAP_USER_MAIL_ATTR=mail
LDAP_TLS=false

View file

@ -0,0 +1 @@
USER Backup AWS access key ID

View file

@ -0,0 +1 @@
USER Backup AWS secret access key

View file

@ -0,0 +1 @@
USER Restic password to encrypt backups

View file

@ -0,0 +1 @@
USER Restic repository, eg. s3:https://s3.garage.tld

View file

@ -0,0 +1 @@
SERVICE_PASSWORD plume

View file

@ -0,0 +1 @@
CMD openssl rand -base64 32

View file

@ -0,0 +1,9 @@
version: '3.4'
services:
postgres:
build:
args:
# https://github.com/sorintlab/stolon/releases
STOLON_VERSION: 3bb7499f815f77140551eb762b200cf4557f57d3
context: ./postgres
image: superboum/amd64_postgres:v11

View file

@ -0,0 +1,25 @@
From c4e0e967752868626772a3317a17d25d181daeda Mon Sep 17 00:00:00 2001
From: Quentin Dufour <quentin@deuxfleurs.fr>
Date: Thu, 15 Apr 2021 12:35:12 +0200
Subject: [PATCH] Add max-rate to pg_basebackup
---
internal/postgresql/postgresql.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/internal/postgresql/postgresql.go b/internal/postgresql/postgresql.go
index 00c14bc..a37a28c 100644
--- a/internal/postgresql/postgresql.go
+++ b/internal/postgresql/postgresql.go
@@ -963,7 +963,7 @@ func (p *Manager) SyncFromFollowed(followedConnParams ConnParams, replSlot strin
log.Infow("running pg_basebackup")
name := filepath.Join(p.pgBinPath, "pg_basebackup")
- args := []string{"-R", "-v", "-P", "-Xs", "-D", p.dataDir, "-d", followedConnString}
+ args := []string{"-R", "-v", "-P", "--max-rate", "5M", "-Xs", "-D", p.dataDir, "-d", followedConnString}
if replSlot != "" {
args = append(args, "--slot", replSlot)
}
--
2.30.2

View file

@ -0,0 +1,16 @@
FROM golang:1.19.0-bullseye AS builder
ARG STOLON_VERSION
WORKDIR /stolon
RUN git clone https://github.com/sorintlab/stolon .
RUN git pull && git checkout ${STOLON_VERSION}
RUN go mod download
COPY 0001-Add-max-rate-to-pg_basebackup.patch .
RUN git apply 0001-Add-max-rate-to-pg_basebackup.patch
RUN make && chmod +x /stolon/bin/*
FROM postgres:14.5-bullseye
COPY --from=builder /stolon/bin /usr/local/bin
USER postgres
ENTRYPOINT []
CMD ["/bin/bash"]

View file

@ -0,0 +1,25 @@
data_directory = '/var/lib/postgresql/9.6/main' # use data in another directory
hba_file = '/etc/postgresql/9.6/main/pg_hba.conf' # host-based authentication file
ident_file = '/etc/postgresql/9.6/main/pg_ident.conf' # ident configuration file
external_pid_file = '/var/run/postgresql/9.6-main.pid' # write an extra PID file
listen_addresses = '*' #listen on every ip / interfaces
port = 5432 # (change requires restart)
max_connections = 100 # (change requires restart)
unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories
ssl = true # (change requires restart)
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' # (change requires restart)
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' # (change requires restart)
shared_buffers = 128MB # min 128kB
dynamic_shared_memory_type = posix # the default is the first option
log_line_prefix = '%m [%p] %q%u@%d ' # special values:
log_timezone = 'UTC'
cluster_name = '9.6/main' # added to process titles if nonempty
stats_temp_directory = '/var/run/postgresql/9.6-main.pg_stat_tmp'
datestyle = 'iso, mdy'
timezone = 'UTC'
lc_messages = 'C.UTF-8' # locale for system error message
lc_monetary = 'C.UTF-8' # locale for monetary formatting
lc_numeric = 'C.UTF-8' # locale for number formatting
lc_time = 'C.UTF-8' # locale for time formatting
default_text_search_config = 'pg_catalog.english'

View file

@ -0,0 +1,3 @@
PG_SU_PWD={{ key "secrets/postgres/keeper/pg_su_pwd" | trimSpace }}
PG_REPL_USER={{ key "secrets/postgres/keeper/pg_repl_username" | trimSpace }}
PG_REPL_PWD={{ key "secrets/postgres/keeper/pg_repl_pwd" | trimSpace }}

View file

@ -0,0 +1,193 @@
job "postgres14" {
datacenters = ["orion"]
type = "system"
priority = 90
update {
max_parallel = 1
min_healthy_time = "2m"
healthy_deadline = "5m"
auto_revert = true
}
group "postgres" {
network {
port "psql_proxy_port" { static = 5432 }
port "psql_port" { static = 5433 }
}
task "sentinel" {
driver = "docker"
config {
image = "superboum/amd64_postgres:v11"
network_mode = "host"
readonly_rootfs = false
command = "/usr/local/bin/stolon-sentinel"
args = [
"--cluster-name", "chelidoine",
"--store-backend", "consul",
"--store-endpoints", "https://consul.service.prod.consul:8501",
"--store-ca-file", "/certs/consul-ca.crt",
"--store-cert-file", "/certs/consul-client.crt",
"--store-key", "/certs/consul-client.key",
]
volumes = [
"secrets/certs:/certs",
]
}
resources {
memory = 100
}
template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "secrets/certs/consul-ca.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "secrets/certs/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "secrets/certs/consul-client.key"
}
}
task "proxy" {
driver = "docker"
config {
image = "superboum/amd64_postgres:v11"
network_mode = "host"
readonly_rootfs = false
command = "/usr/local/bin/stolon-proxy"
args = [
"--cluster-name", "chelidoine",
"--store-backend", "consul",
"--store-endpoints", "https://consul.service.prod.consul:8501",
"--store-ca-file", "/certs/consul-ca.crt",
"--store-cert-file", "/certs/consul-client.crt",
"--store-key", "/certs/consul-client.key",
"--port", "${NOMAD_PORT_psql_proxy_port}",
"--listen-address", "0.0.0.0",
"--log-level", "info"
]
volumes = [
"secrets/certs:/certs",
]
ports = [ "psql_proxy_port" ]
}
resources {
memory = 100
}
template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "secrets/certs/consul-ca.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "secrets/certs/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "secrets/certs/consul-client.key"
}
service {
tags = ["sql"]
port = "psql_proxy_port"
address_mode = "host"
name = "psql-proxy"
check {
type = "tcp"
port = "psql_proxy_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "10m"
ignore_warnings = false
}
}
}
}
task "keeper" {
driver = "docker"
config {
image = "superboum/amd64_postgres:v11"
network_mode = "host"
readonly_rootfs = false
command = "/usr/local/bin/stolon-keeper"
args = [
"--cluster-name", "chelidoine",
"--store-backend", "consul",
"--store-endpoints", "https://consul.service.prod.consul:8501",
"--store-ca-file", "/certs/consul-ca.crt",
"--store-cert-file", "/certs/consul-client.crt",
"--store-key", "/certs/consul-client.key",
"--data-dir", "/mnt/persist",
"--pg-su-password", "${PG_SU_PWD}",
"--pg-repl-username", "${PG_REPL_USER}",
"--pg-repl-password", "${PG_REPL_PWD}",
/*
The postgres daemon accepts 0.0.0.0, ::, and * here but not Stolon.
Otherwise you will have the following error and your cluster will be broken (no replication)
WARN cmd/keeper.go:1979 provided --pg-listen-address "*": is not an ip address but a hostname. This will be advertized to the other components and may have undefined behaviors if resolved differently by other hosts
WARN cmd/keeper.go:1984 cannot resolve provided --pg-listen-address "*": lookup *: no such host
*/
"--pg-listen-address", "${attr.unique.network.ip-address}",
"--pg-port", "${NOMAD_PORT_psql_port}",
"--pg-bin-path", "/usr/lib/postgresql/14/bin/"
]
ports = [ "psql_port" ]
volumes = [
"/mnt/ssd/postgres:/mnt/persist",
"/mnt/storage/postgres_extended:/mnt/slow",
"secrets/certs:/certs"
]
}
template {
data = file("../config/keeper/env.tpl")
destination = "secrets/env"
env = true
}
template {
data = "{{ key \"secrets/consul/consul-ca.crt\" }}"
destination = "secrets/certs/consul-ca.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.crt\" }}"
destination = "secrets/certs/consul-client.crt"
}
template {
data = "{{ key \"secrets/consul/consul-client.key\" }}"
destination = "secrets/certs/consul-client.key"
}
resources {
memory = 1000
}
service {
tags = ["sql"]
port = "psql_port"
address_mode = "host"
name = "psql-keeper"
check {
type = "tcp"
port = "psql_port"
interval = "60s"
timeout = "5s"
}
}
}
}
}

View file

@ -0,0 +1 @@
SERVICE_PASSWORD replicator

View file

@ -0,0 +1 @@
CONST replicator

View file

@ -0,0 +1 @@
USER postgres superuser password

View file

@ -37,10 +37,10 @@ pass $PREFIX/consul$YEAR.crt > $CERTDIR/consul.crt
pass $PREFIX/consul$YEAR-client.crt > $CERTDIR/consul-client.crt pass $PREFIX/consul$YEAR-client.crt > $CERTDIR/consul-client.crt
pass $PREFIX/consul$YEAR-client.key > $CERTDIR/consul-client.key pass $PREFIX/consul$YEAR-client.key > $CERTDIR/consul-client.key
socat -dd tcp4-listen:4646,reuseaddr,fork openssl:localhost:14646,cert=$CERTDIR/nomad-client.crt,key=$CERTDIR/nomad-client.key,cafile=$CERTDIR/nomad.crt & socat -dd tcp4-listen:4646,reuseaddr,fork openssl:localhost:14646,cert=$CERTDIR/nomad-client.crt,key=$CERTDIR/nomad-client.key,cafile=$CERTDIR/nomad.crt,verify=0 &
child1=$! child1=$!
socat -dd tcp4-listen:8500,reuseaddr,fork openssl:localhost:8501,cert=$CERTDIR/consul-client.crt,key=$CERTDIR/consul-client.key,cafile=$CERTDIR/consul.crt & socat -dd tcp4-listen:8500,reuseaddr,fork openssl:localhost:8501,cert=$CERTDIR/consul-client.crt,key=$CERTDIR/consul-client.key,cafile=$CERTDIR/consul.crt,verify=0 &
child2=$! child2=$!
wait "$child1" wait "$child1"