create an archive, for wip and broken services

bookstack
micro 11 hours ago
parent 7e0668d555
commit ca242249b2

@ -0,0 +1,17 @@
services:
pages:
image: caddy
volumes:
- ../data/pages/srv:/srv:ro
- ./pages.Caddyfile:/etc/caddy/Caddyfile:ro
environment:
- POSTGRES_USER=hedgedoc
- POSTGRES_PASSWORD=password
- POSTGRES_DB=hedgedoc
restart: always
env_file:
- ../env.production
- env.production
- ../data/hedgedoc/env.secrets
labels:
- "diun.enable=true"

@ -0,0 +1,2 @@
CMD_OAUTH2_CLIENT_SECRET=abcdef1234
CMD_SESSION_SECRET=abcdef1234

@ -0,0 +1,69 @@
#!/bin/bash
die() { echo >&2 "$@" ; exit 1 ; }
DIRNAME="$(dirname $0)"
cd "$DIRNAME"
source ../env.production || die "no top levle env?"
source env.production || die "no local env?"
DATA="../data/hedgedoc"
SECRETS="$DATA/env.secrets"
if [ -r "$SECRETS" ]; then
docker compose up -d || die "hedgedoc: unable to start"
exit 0
fi
docker compose down 2>/dev/null
# regenerate the client secrets
CLIENT_SECRET="$(openssl rand -hex 20)"
SESSION_SECRET="$(openssl rand -hex 20)"
mkdir -p "$DATA/uploads"
chmod 666 "$DATA/uploads"
cat <<EOF > "$SECRETS"
# DO NOT CHECK IN
CMD_OAUTH2_CLIENT_SECRET=$CLIENT_SECRET
CMD_SESSION_SECRET=$SESSION_SECRET
CMD_DOMAIN=${HEDGEDOC_HOSTNAME}
CMD_OAUTH2_AUTHORIZATION_URL=https://${KEYCLOAK_HOSTNAME}/realms/${REALM}/protocol/openid-connect/auth
CMD_OAUTH2_TOKEN_URL=https://${KEYCLOAK_HOSTNAME}/realms/${REALM}/protocol/openid-connect/token
CMD_OAUTH2_USER_PROFILE_URL=https://${KEYCLOAK_HOSTNAME}/realms/${REALM}/protocol/openid-connect/userinfo
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
CMD_OAUTH2_CLIENT_ID=hedgedoc
CMD_OAUTH2_PROVIDERNAME=Keycloak
EOF
../keycloak/client-delete hedgedoc
../keycloak/client-create <<EOF || die "unable to create hedgedoc client"
{
"clientId": "hedgedoc",
"rootUrl": "https://$HEDGEDOC_HOSTNAME",
"adminUrl": "https://$HEDGEDOC_HOSTNAME",
"redirectUris": [ "https://$HEDGEDOC_HOSTNAME/*" ],
"webOrigins": [ "https://$HEDGEDOC_HOSTNAME" ],
"clientAuthenticatorType": "client-secret",
"secret": "$CLIENT_SECRET",
"defaultClientScopes": [
"web-origins",
"acr",
"profile",
"roles",
"id",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
]
}
EOF
docker compose up -d || die "hedgedoc: unable to start container"

@ -0,0 +1,113 @@
# Mobilizon instance configuration
import Config
listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "0.0.0.0")
listen_ip =
case listen_ip |> to_charlist() |> :inet.parse_address() do
{:ok, listen_ip} -> listen_ip
_ -> raise "MOBILIZON_INSTANCE_LISTEN_IP does not match the expected IP format."
end
config :mobilizon, Mobilizon.Web.Endpoint,
server: true,
url: [host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan")],
http: [
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_PORT", "4000")),
ip: listen_ip
],
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis")
config :mobilizon, Mobilizon.Web.Auth.Guardian,
secret_key: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY", "changethis")
config :mobilizon, :instance,
name: System.get_env("MOBILIZON_INSTANCE_NAME", "Mobilizon"),
description: "Change this to a proper description of your instance",
hostname: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan"),
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN", "false") == "true",
demo: false,
allow_relay: true,
federating: true,
email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL", "woodbine@example.com"),
email_reply_to: System.get_env("MOBILIZON_REPLY_EMAIL", "woodbine@example.com")
config :mobilizon, Mobilizon.Storage.Repo,
adapter: Ecto.Adapters.Postgres,
username: System.get_env("MOBILIZON_DATABASE_USERNAME", "username"),
password: System.get_env("MOBILIZON_DATABASE_PASSWORD", "password"),
database: System.get_env("MOBILIZON_DATABASE_DBNAME", "mobilizon"),
hostname: System.get_env("MOBILIZON_DATABASE_HOST", "postgres"),
port: 5432,
pool_size: 10
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Swoosh.Adapters.SMTP,
relay: System.get_env("MOBILIZON_SMTP_SERVER", "mail.example.com"),
port: System.get_env("MOBILIZON_SMTP_PORT", "587"),
username: System.get_env("MOBILIZON_SMTP_USERNAME", "username"),
password: System.get_env("MOBILIZON_SMTP_PASSWORD", "password"),
tls: :if_available,
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
ssl: System.get_env("MOBILIZON_SMTP_SSL", "false"),
retries: 2,
no_mx_lookups: false,
auth: :always
config :geolix,
databases: [
%{
id: :city,
adapter: Geolix.Adapter.MMDB2,
source: "/var/lib/mobilizon/geo_db/GeoLite2-City.mmdb"
}
]
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local,
uploads: System.get_env("MOBILIZON_UPLOADS", "/var/lib/mobilizon/uploads")
config :mobilizon, :exports,
path: System.get_env("MOBILIZON_UPLOADS_EXPORTS", "/var/lib/mobilizon/uploads/exports"),
formats: [
Mobilizon.Service.Export.Participants.CSV,
Mobilizon.Service.Export.Participants.PDF,
Mobilizon.Service.Export.Participants.ODS
]
config :tz_world,
data_dir: System.get_env("MOBILIZON_TIMEZONES_DIR", "/var/lib/mobilizon/timezones")
#
# keycloak config for hackerspace.zone self hosted single-sign-on
#
keycloak_hostname = System.get_env("KEYCLOAK_HOSTNAME", "keycloak.example.com")
keycloak_realm = System.get_env("REALM", "example")
keycloak_secret = System.get_env("MOBILIZON_CLIENT_SECRET", "abcdef1234")
keycloak_url = "https://#{keycloak_hostname}/realms/#{keycloak_realm}"
config :ueberauth,
Ueberauth,
providers: [
keycloak: {Ueberauth.Strategy.Keycloak, [default_scope: "openid"]}
]
config :mobilizon, :auth,
oauth_consumer_strategies: [
{:keycloak, "#{keycloak_hostname}"}
]
config :ueberauth, Ueberauth.Strategy.Keycloak.OAuth,
client_id: "mobilizon",
client_secret: keycloak_secret,
site: keycloak_url,
authorize_url: "#{keycloak_url}/protocol/openid-connect/auth",
token_url: "#{keycloak_url}/protocol/openid-connect/token",
userinfo_url: "#{keycloak_url}/protocol/openid-connect/userinfo",
token_method: :post
config :web_push_encryption, :vapid_details,
subject: "mailto:mail@example.net",
public_key: "public_key",
private_key: "private_key"

@ -0,0 +1,28 @@
version: "3"
services:
mobilizon:
image: framasoft/mobilizon:4.1.0
restart: always
env_file:
- ../env.production
- ./env.production
- ../data/mobilizon/env.secrets
volumes:
- ../data/mobilizon/uploads:/var/lib/mobilizon/uploads
- ./config.exs:/etc/mobilizon/config.exs:ro
# - ${PWD}/GeoLite2-City.mmdb:/var/lib/mobilizon/geo_db/GeoLite2-City.mmdb
ports:
- "7000:7000"
labels:
- "diun.enable=true"
db:
image: postgis/postgis:13-3.1
restart: always
volumes:
- ../data/mobilizon/db:/var/lib/postgresql/data
environment:
- POSTGRES_USER=mobilizon
- POSTGRES_PASSWORD=mobilizon
- POSTGRES_DB=mobilizon

@ -0,0 +1,24 @@
# Database settings
POSTGRES_USER=mobilizon
POSTGRES_PASSWORD=changethis
POSTGRES_DB=mobilizon
MOBILIZON_DATABASE_USERNAME=mobilizon
MOBILIZON_DATABASE_PASSWORD=mobilizon
MOBILIZON_DATABASE_DBNAME=mobilizon
MOBILIZON_DATABASE_HOST=db
# Instance configuration
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=false
MOBILIZON_INSTANCE_PORT=7000
MOBILIZON_INSTANCE_EMAIL=noreply@mobilizon.lan
MOBILIZON_REPLY_EMAIL=contact@mobilizon.lan
# Email settings
MOBILIZON_SMTP_SERVER=localhost
MOBILIZON_SMTP_PORT=25
MOBILIZON_SMTP_HOSTNAME=localhost
MOBILIZON_SMTP_USERNAME=noreply@mobilizon.lan
MOBILIZON_SMTP_PASSWORD=password
MOBILIZON_SMTP_SSL=false

@ -0,0 +1,62 @@
#!/bin/bash
die() { echo >&2 "mobilizon: $@" ; exit 1 ; }
DIRNAME="$(dirname $0)"
cd "$DIRNAME"
source ../env.production || die "no top level env?"
source env.production || die "no local env?"
source ../env.smtp 2>/dev/null
DATA="../data/mobilizon"
SECRETS="$DATA/env.secrets"
if [ -r "$SECRETS" ]; then
docker compose up -d || die "unable to start"
exit 0
fi
docker compose down 2>/dev/null
CLIENT_SECRET="$(openssl rand -hex 20)"
mkdir -p "$DATA/uploads"
chmod 777 "$DATA/uploads"
mkdir -p "$(dirname "$SECRETS")"
cat <<EOF > "$SECRETS"
# DO NOT CHECK IN
MOBILIZON_INSTANCE_NAME=${DOMAIN_NAME}
MOBILIZON_INSTANCE_HOST=${MOBILIZON_HOSTNAME}
MOBILIZON_INSTANCE_SECRET_KEY_BASE=$(openssl rand -hex 20)
MOBILIZON_INSTANCE_SECRET_KEY=$(openssl rand -hex 20)
MOBILIZON_CLIENT_SECRET=${CLIENT_SECRET}
EOF
if [ -n "$SMTP_SERVER" ]; then
cat <<EOF >> "$SECRETS"
MOBILIZON_INSTANCE_EMAIL=events@${DOMAIN_NAME}
MOBILIZON_REPLY_EMAIL=noreply@${DOMAIN_NAME}
MOBILIZON_SMTP_SERVER=${SMTP_SERVER}
MOBILIZON_SMTP_PORT=${SMTP_PORT}
MOBILIZON_SMTP_USERNAME=${SMTP_USER}
MOBILIZON_SMTP_PASSWORD=${SMTP_PASSWORD}
EOF
fi
../keycloak/client-delete mobilizon
../keycloak/client-create <<EOF || die "unable to create client"
{
"clientId": "mobilizon",
"rootUrl": "https://$MOBILIZON_HOSTNAME",
"adminUrl": "https://$MOBILIZON_HOSTNAME",
"redirectUris": [ "https://$MOBILIZON_HOSTNAME/*" ],
"webOrigins": [ "https://$MOBILIZON_HOSTNAME" ],
"clientAuthenticatorType": "client-secret",
"secret": "$CLIENT_SECRET"
}
EOF
docker compose up -d || die "unable to start container"

@ -6,5 +6,5 @@ cd "$DIRNAME"
source ../env.production || die "no top level env?"
source env.production || die "no local env?"
docker-compose down 2>/dev/null
docker-compose up -d || die "diun: unable to bring up container"
docker compose down 2>/dev/null
docker compose up -d || die "diun: unable to bring up container"

@ -0,0 +1,11 @@
services:
filestash:
container_name: filestash
image: machines/filestash
restart: always
environment:
- APPLICATION_URL=files.woodbine.nyc
ports:
- "8334:8334"
volumes:
- ../data/filestash/state:/app/data/state/

@ -1,5 +1,3 @@
version: "3"
services:
grafana:
image: grafana/grafana-oss:8.5.1

@ -10,11 +10,11 @@ BASE="https://$KEYCLOAK_HOSTNAME/realms/$REALM/protocol/openid-connect"
SECRETS="../data/grafana/env.secrets"
if [ -r "$SECRETS" ]; then
docker-compose up -d || die "grafana: unable to start container"
docker compose up -d || die "grafana: unable to start container"
exit 0
fi
docker-compose down 2>/dev/null
docker compose down 2>/dev/null
GRAFANA_CLIENT_SECRET="$(openssl rand -hex 32)"
GRAFANA_ADMIN_PASSWORD="$(openssl rand -hex 4)"
@ -47,4 +47,4 @@ EOF
}
EOF
docker-compose up -d || die "grafana: unable to bring up container"
docker compose up -d || die "grafana: unable to bring up container"

@ -0,0 +1,126 @@
'use strict'
const archiver = require('archiver')
const sanitizeFilename = require('sanitize-filename')
const async = require('async')
const Router = require('express').Router
const errors = require('../errors')
const config = require('../config')
const models = require('../models')
const logger = require('../logger')
const { generateAvatar } = require('../letter-avatars')
const UserRouter = module.exports = Router()
// get me info
UserRouter.get('/me', function (req, res) {
if (req.isAuthenticated()) {
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
if (!user) { return errors.errorNotFound(res) }
const profile = models.User.getProfile(user)
res.send({
status: 'ok',
id: req.user.id,
name: profile.name,
photo: profile.photo
})
}).catch(function (err) {
logger.error('read me failed: ' + err)
return errors.errorInternalError(res)
})
} else {
res.send({
status: 'forbidden'
})
}
})
// delete the currently authenticated user
UserRouter.get('/me/delete/:token?', function (req, res) {
if (req.isAuthenticated()) {
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
if (!user) {
return errors.errorNotFound(res)
}
if (user.deleteToken === req.params.token) {
user.destroy().then(function () {
res.redirect(config.serverURL + '/')
})
} else {
return errors.errorForbidden(res)
}
}).catch(function (err) {
logger.error('delete user failed: ' + err)
return errors.errorInternalError(res)
})
} else {
return errors.errorForbidden(res)
}
})
// export the data of the authenticated user
UserRouter.get('/me/export', function (req, res) {
if (req.isAuthenticated()) {
// let output = fs.createWriteStream(__dirname + '/example.zip');
const archive = archiver('zip', {
zlib: { level: 3 } // Sets the compression level.
})
res.setHeader('Content-Type', 'application/zip')
res.attachment('archive.zip')
archive.pipe(res)
archive.on('error', function (err) {
logger.error('export user data failed: ' + err)
return errors.errorInternalError(res)
})
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
models.Note.findAll().then(function (notes) {
const filenames = {}
async.each(notes, function (note, callback) {
const basename = sanitizeFilename(note.title, { replacement: '_' })
let filename
let suffix = ''
do {
const seperator = typeof suffix === 'number' ? '-' : ''
filename = basename + seperator + suffix + '.md'
suffix++
} while (filenames[filename])
filenames[filename] = true
logger.debug('Write: ' + filename)
archive.append(Buffer.from(note.content), { name: filename, date: note.lastchangeAt })
callback(null, null)
}, function (err) {
if (err) {
return errors.errorInternalError(res)
}
archive.finalize()
})
})
}).catch(function (err) {
logger.error('export user data failed: ' + err)
return errors.errorInternalError(res)
})
} else {
return errors.errorForbidden(res)
}
})
UserRouter.get('/user/:username/avatar.svg', function (req, res, next) {
res.setHeader('Content-Type', 'image/svg+xml')
res.setHeader('Cache-Control', 'public, max-age=86400')
res.send(generateAvatar(req.params.username))
})

@ -0,0 +1,31 @@
services:
manyfold:
image: ghcr.io/manyfold3d/manyfold:latest
ports:
- 3214:3214
env_file:
- ./env.production
- ../env.production
- ../data/manyfold/env.secrets
volumes:
- ../data/manyfold/libraries:/libraries
environment:
REDIS_URL: redis://redis:6379/1
labels:
- "diun.enable=true"
depends_on:
- db
- redis
restart: always
db:
image: postgres:15
volumes:
- ../data/manyfold/database:/var/lib/postgresql/data
env_file:
- ../data/manyfold/env.secrets
restart: on-failure
redis:
image: redis:7
restart: on-failure

@ -0,0 +1,2 @@
REGISTRATION=true
MULTIUSER=true

@ -0,0 +1,9 @@
#!/bin/bash
die() { echo >&2 "$@" ; exit 1 ; }
DIRNAME="$(dirname $0)"
cd "$DIRNAME"
source ../env.production || die "no top level env?"
docker compose down 2>/dev/null
docker compose up -d || die "diun: unable to bring up container"

@ -1,6 +1,3 @@
---
version: '3'
services:
## App and Worker
app:

@ -13,11 +13,11 @@ DATA="../data/$MODULE"
SECRETS="$DATA/env.secrets"
if [ -r "$SECRETS" ]; then
docker-compose up -d || die "unable to start"
docker compose up -d || die "unable to start"
exit 0
fi
docker-compose down 2>/dev/null
docker compose down 2>/dev/null
CLIENT_SECRET="$(openssl rand -hex 20)"
@ -70,30 +70,30 @@ mkdir -p "$DATA/app-bootstrap/cache" || die "mkdir bootstrap/cache"
cp ./app.php "$DATA/app-bootstrap" || die "cp app.php"
chown -R www-data:www-data "$DATA/app-bootstrap" || die "chown bootstrap"
docker-compose up -d || die "unable to start container"
docker compose up -d || die "unable to start container"
# need to wait for stuff to finish setup
info "Sleeping while stuff starts"
sleep 20
# some of these are to work around docker file weirdness that expects the volume to be prepopulated
#docker-compose exec app bash -c "touch .env && chown www-data:www-data .env" || die ".env create"
#docker-compose exec app cp -R storage.skel storage || die "storage create"
#docker-compose exec -u www-data app composer install --prefer-dist --no-interaction --no-ansi --optimize-autoloader || die "composer install"
docker-compose exec -u www-data app php artisan key:generate || die "key:generate"
docker-compose exec -u www-data app php artisan storage:link || die "storage:link"
docker-compose exec -u www-data app php artisan migrate --force || die "migrate"
#docker-compose exec app php artisan import:cities || die "import:cities"
docker-compose exec -u www-data app php artisan instance:actor || die "instance:actor"
docker-compose exec -u www-data app php artisan passport:keys || die "passport:keys"
docker-compose exec -u www-data app php artisan route:cache || die "route:cache"
docker-compose exec -u www-data app php artisan view:cache || die "view:cache"
docker-compose exec -u www-data app php artisan config:cache || die "config:cache"
#docker compose exec app bash -c "touch .env && chown www-data:www-data .env" || die ".env create"
#docker compose exec app cp -R storage.skel storage || die "storage create"
#docker compose exec -u www-data app composer install --prefer-dist --no-interaction --no-ansi --optimize-autoloader || die "composer install"
docker compose exec -u www-data app php artisan key:generate || die "key:generate"
docker compose exec -u www-data app php artisan storage:link || die "storage:link"
docker compose exec -u www-data app php artisan migrate --force || die "migrate"
#docker compose exec app php artisan import:cities || die "import:cities"
docker compose exec -u www-data app php artisan instance:actor || die "instance:actor"
docker compose exec -u www-data app php artisan passport:keys || die "passport:keys"
docker compose exec -u www-data app php artisan route:cache || die "route:cache"
docker compose exec -u www-data app php artisan view:cache || die "view:cache"
docker compose exec -u www-data app php artisan config:cache || die "config:cache"
# bounce it to reload all of the state
docker-compose down || die "unable to bring down"
docker-compose up -d || die "unable to restart"
docker compose down || die "unable to bring down"
docker compose up -d || die "unable to restart"
#php artisan route:clear
#php artisan view:clear

@ -0,0 +1,24 @@
services:
prometheus:
image: prom/prometheus
restart: always
container_name: prometheus
user: root
volumes:
- ../data/prometheus/storage:/prometheus:rw
- ./prometheus.yaml:/etc/prometheus/prometheus.yml:ro
- ./entrypoint.sh:/entrypoint.sh:ro
entrypoint: ["/entrypoint.sh"]
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
restart: always
container_name: cadvisor
command:
- '--housekeeping_interval=15s'
- '--docker_only=true'
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro

@ -0,0 +1,10 @@
#!/bin/sh -x
chmod 777 /prometheus
exec su -s /bin/sh nobody <<EOF
exec /bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.console.templates=/etc/prometheus/consoles
EOF

@ -0,0 +1,24 @@
global:
scrape_interval: 30s
external_labels:
monitor: 'codelab-monitor'
scrape_configs:
# nginx vts data
- job_name: 'nginx'
scrape_interval: 30s
metrics_path: "/status/format/prometheus"
static_configs:
- targets: ['nginx:80']
- job_name: 'metrics'
scrape_interval: 30s
static_configs:
# grafana data from /metrics
- targets: ['dashboard:3000']
# host running the docker compose
- targets: ['172.17.0.1:9100']
- job_name: "synapse"
scrape_interval: 30s
metrics_path: "/_synapse/metrics"
static_configs:
- targets: ["matrix-synapse:9000"]

@ -0,0 +1 @@
works in progress, and broken things go here
Loading…
Cancel
Save