mobilizon: event planning tool

single-dockerfile
Trammell Hudson 3 years ago
parent 0f909336c9
commit 459a89f350
  1. 1
      env.production
  2. 1
      html/index.html
  3. 108
      mobilizon/config.exs
  4. 26
      mobilizon/docker-compose.yml
  5. 24
      mobilizon/env.production
  6. 50
      mobilizon/setup
  7. 2
      nginx/certbot-renew
  8. 35
      nginx/nginx/templates/events.conf.template
  9. 4
      start-all

@ -8,3 +8,4 @@ NEXTCLOUD_HOSTNAME=cloud.hackerspace.zone
GRAFANA_HOSTNAME=dashboard.hackerspace.zone GRAFANA_HOSTNAME=dashboard.hackerspace.zone
GITEA_HOSTNAME=git.hackerspace.zone GITEA_HOSTNAME=git.hackerspace.zone
MATRIX_HOSTNAME=matrix.hackerspace.zone MATRIX_HOSTNAME=matrix.hackerspace.zone
MOBILIZON_HOSTNAME=events.hackerspace.zone

@ -6,6 +6,7 @@ An easy to install set of self-hosted, single-sign-on, open-source services.
<li><a href="https://matrix.hackerspace.zone/">matrix</a>: realtime chat <li><a href="https://matrix.hackerspace.zone/">matrix</a>: realtime chat
<li><a href="https://docs.hackerspace.zone/">hedgedoc</a>: collaborative markdown editing <li><a href="https://docs.hackerspace.zone/">hedgedoc</a>: collaborative markdown editing
<li><a href="https://social.hackerspace.zone/">mastodon</a>: federated social media <li><a href="https://social.hackerspace.zone/">mastodon</a>: federated social media
<li><a href="https://events.hackerspace.zone/">mobilizon</a>: event planning and RSVP
<li><a href="https://cloud.hackerspace.zone/">nextcloud</a>: self hosted documents and calendaring <li><a href="https://cloud.hackerspace.zone/">nextcloud</a>: self hosted documents and calendaring
<li><a href="https://dashboard.hackerspace.zone/">grafana</a>: dashboards and statistic collection <li><a href="https://dashboard.hackerspace.zone/">grafana</a>: dashboards and statistic collection
<li><a href="https://git.hackerspace.zone/">gitea</a>: git repository hosting <li><a href="https://git.hackerspace.zone/">gitea</a>: git repository hosting

@ -0,0 +1,108 @@
# 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", "noreply@mobilizon.lan"),
email_reply_to: System.get_env("MOBILIZON_REPLY_EMAIL", "noreply@mobilizon.lan")
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", "localhost"),
port: System.get_env("MOBILIZON_SMTP_PORT", "25"),
username: System.get_env("MOBILIZON_SMTP_USERNAME", nil),
password: System.get_env("MOBILIZON_SMTP_PASSWORD", nil),
tls: :if_available,
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
ssl: System.get_env("MOBILIZON_SMTP_SSL", "false"),
retries: 1,
no_mx_lookups: false,
auth: :if_available
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

@ -0,0 +1,26 @@
version: "3"
services:
mobilizon:
image: framasoft/mobilizon
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"
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,50 @@
#!/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?"
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
../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"

@ -7,7 +7,7 @@ cd "$DIRNAME"
source ../env.production source ../env.production
source ./env.production source ./env.production
domain_args="-d $DOMAIN_NAME,$KEYCLOAK_HOSTNAME,$HEDGEDOC_HOSTNAME,$MASTODON_HOSTNAME,$NEXTCLOUD_HOSTNAME,$GRAFANA_HOSTNAME,$MATRIX_HOSTNAME,$GITEA_HOSTNAME" domain_args="-d $DOMAIN_NAME,$KEYCLOAK_HOSTNAME,$HEDGEDOC_HOSTNAME,$MASTODON_HOSTNAME,$NEXTCLOUD_HOSTNAME,$GRAFANA_HOSTNAME,$MATRIX_HOSTNAME,$GITEA_HOSTNAME,$MOBILIZON_HOSTNAME"
rsa_key_size=2048 rsa_key_size=2048
set -x set -x

@ -0,0 +1,35 @@
server {
server_name ${MOBILIZON_HOSTNAME};
client_max_body_size 128m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on;
gzip_disable "msie6";
proxy_read_timeout 1800s;
location / {
proxy_pass http://host.docker.internal:7000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# force login with OIDC
location /login {
return 302 https://${MOBILIZON_HOSTNAME}/auth/keycloak;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem;
include /etc/nginx/includes/options-ssl-nginx.conf;
include /etc/nginx/includes/challenge.conf;
ssl_dhparam /etc/nginx/includes/ssl-dhparams.pem;
}

@ -17,6 +17,8 @@ SERVICES+=\ nextcloud
SERVICES+=\ mastodon SERVICES+=\ mastodon
SERVICES+=\ grafana SERVICES+=\ grafana
SERVICES+=\ matrix SERVICES+=\ matrix
SERVICES+=\ gitea
SERVICES+=\ mobilizon
HOSTS+=\ $KEYCLOAK_HOST HOSTS+=\ $KEYCLOAK_HOST
HOSTS+=\ $HEDGEDOC_HOST HOSTS+=\ $HEDGEDOC_HOST
@ -24,6 +26,8 @@ HOSTS+=\ $NEXTCLOUD_HOST
HOSTS+=\ $MASTODON_HOST HOSTS+=\ $MASTODON_HOST
HOSTS+=\ $GRAFANA_HOST HOSTS+=\ $GRAFANA_HOST
HOSTS+=\ $MATRIX_HOST HOSTS+=\ $MATRIX_HOST
HOSTS+=\ $GITEA_HOST
HOSTS+=\ $MOBILIZON_HOST
for host in $HOSTS ; do for host in $HOSTS ; do
host $host > /dev/null || die "$host: DNS entry not present?" host $host > /dev/null || die "$host: DNS entry not present?"

Loading…
Cancel
Save