diff --git a/env.production b/env.production index 10b3f52..8739e37 100644 --- a/env.production +++ b/env.production @@ -8,3 +8,4 @@ NEXTCLOUD_HOSTNAME=cloud.hackerspace.zone GRAFANA_HOSTNAME=dashboard.hackerspace.zone GITEA_HOSTNAME=git.hackerspace.zone MATRIX_HOSTNAME=matrix.hackerspace.zone +MOBILIZON_HOSTNAME=events.hackerspace.zone diff --git a/html/index.html b/html/index.html index 7f71a17..2b08ecd 100644 --- a/html/index.html +++ b/html/index.html @@ -6,6 +6,7 @@ An easy to install set of self-hosted, single-sign-on, open-source services.
  • matrix: realtime chat
  • hedgedoc: collaborative markdown editing
  • mastodon: federated social media +
  • mobilizon: event planning and RSVP
  • nextcloud: self hosted documents and calendaring
  • grafana: dashboards and statistic collection
  • gitea: git repository hosting diff --git a/mobilizon/config.exs b/mobilizon/config.exs new file mode 100644 index 0000000..d97be56 --- /dev/null +++ b/mobilizon/config.exs @@ -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 diff --git a/mobilizon/docker-compose.yml b/mobilizon/docker-compose.yml new file mode 100644 index 0000000..4f359ff --- /dev/null +++ b/mobilizon/docker-compose.yml @@ -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 diff --git a/mobilizon/env.production b/mobilizon/env.production new file mode 100644 index 0000000..4f67db1 --- /dev/null +++ b/mobilizon/env.production @@ -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 diff --git a/mobilizon/setup b/mobilizon/setup new file mode 100755 index 0000000..3a35780 --- /dev/null +++ b/mobilizon/setup @@ -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 < "$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 < /dev/null || die "$host: DNS entry not present?"