Move configuration to traditional way

️ This is the way.

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-01-30 20:27:25 +01:00
parent 98051b08c3
commit 9e3df495dc
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
32 changed files with 368 additions and 256 deletions

View File

@ -1,22 +0,0 @@
# Settings
MOBILIZON_INSTANCE_NAME="<%= instance_name %>"
MOBILIZON_INSTANCE_HOST="<%= instance_domain %>"
MOBILIZON_INSTANCE_PORT=4002
MOBILIZON_INSTANCE_EMAIL="<%= instance_email %>"
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=true
# API
GRAPHQL_API_ENDPOINT="https://<%= instance_domain %>"
GRAPHQL_API_FULL_PATH=""
# APP
MIX_ENV=prod
MOBILIZON_LOGLEVEL="info"
MOBILIZON_SECRET="<%= instance_secret %>"
# Database
MOBILIZON_DATABASE_USERNAME="<%= database_username %>"
MOBILIZON_DATABASE_PASSWORD="<%= database_password %>"
MOBILIZON_DATABASE_DBNAME="<%= database_name %>"
MOBILIZON_DATABASE_HOST="<%= database_host %>"
MOBILIZON_DATABASE_PORT=<%= database_port %>

7
.gitignore vendored
View File

@ -15,12 +15,6 @@ erl_crash.dump
# variables. # variables.
/config/*.secret.exs /config/*.secret.exs
.env.production
.env.test
/.env
.env.2
.env.1
/setup_db.psql /setup_db.psql
.elixir_ls .elixir_ls
@ -35,6 +29,7 @@ site/
test/fixtures/image_tmp.jpg test/fixtures/image_tmp.jpg
test/uploads/ test/uploads/
uploads/* uploads/*
release/
!uploads/.gitkeep !uploads/.gitkeep
.idea .idea
*.mo *.mo

View File

@ -24,7 +24,7 @@ cache:
key: ${CI_COMMIT_REF_SLUG} key: ${CI_COMMIT_REF_SLUG}
paths: paths:
- ~/.cache/Cypress - ~/.cache/Cypress
- build/ - _build/
- deps/ - deps/
- js/node_modules - js/node_modules
- cache/Cypress - cache/Cypress
@ -34,7 +34,7 @@ lint:
script: script:
- export EXITVALUE=0 - export EXITVALUE=0
- mix deps.get - mix deps.get
- mix credo -a || export EXITVALUE=1 - mix credo --strict -a || export EXITVALUE=1
- mix format --check-formatted --dry-run || export EXITVALUE=1 - mix format --check-formatted --dry-run || export EXITVALUE=1
- cd js - cd js
- yarn install - yarn install

View File

@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Special operations
Config has moved from `.env` files to a more traditional way to handle things in the Elixir world, with `.exs` files.
To migrate existing configuration, you can simply run `mix mobilizon.instance gen` and fill in the adequate values previously in `.env` files (you don't need to perform the operations to create the database).
A minimal file template [is available](https://framagit.org/framasoft/mobilizon/blob/master/priv/templates/config.template.eex) to check for missing configuration.
Also make sure to remove the `EnvironmentFile=` line from the systemd service and set `Environment=MIX_ENV=prod` instead. See [the updated file](https://framagit.org/framasoft/mobilizon/blob/master/support/systemd/mobilizon.service).
### Added
- Possibility to participate anonymously to an event
- Possibility to participate to a remote event (being redirected by providing federated identity)
## [1.0.0-beta.2] - 2019-12-18 ## [1.0.0-beta.2] - 2019-12-18
### Special operations ### Special operations

View File

@ -5,7 +5,7 @@ init:
start: stop start: stop
@bash docker/message.sh "starting Mobilizon with docker" @bash docker/message.sh "starting Mobilizon with docker"
docker-compose up -d api docker-compose up -d api
@bash docker/message.sh "started" @bash docker/message.sh "Docker server started."
stop: stop:
@bash docker/message.sh "stopping Mobilizon" @bash docker/message.sh "stopping Mobilizon"
docker-compose down docker-compose down

View File

@ -10,15 +10,15 @@ config :mobilizon,
ecto_repos: [Mobilizon.Storage.Repo], ecto_repos: [Mobilizon.Storage.Repo],
env: Mix.env() env: Mix.env()
config :mobilizon, Mobilizon.Storage.Repo, types: Mobilizon.Storage.PostgresTypes
config :mobilizon, :instance, config :mobilizon, :instance,
name: System.get_env("MOBILIZON_INSTANCE_NAME") || "My Mobilizon Instance", name: "My Mobilizon Instance",
description: description: "Change this to a proper description of your instance",
System.get_env("MOBILIZON_INSTANCE_DESCRIPTION") || hostname: "localhost",
"Change this to a proper description of your instance", registrations_open: false,
hostname: System.get_env("MOBILIZON_INSTANCE_HOST") || "localhost",
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") || false,
registration_email_whitelist: [], registration_email_whitelist: [],
demo: System.get_env("MOBILIZON_INSTANCE_DEMO_MODE") || false, demo: false,
repository: Mix.Project.config()[:source_url], repository: Mix.Project.config()[:source_url],
allow_relay: true, allow_relay: true,
# Federation is to be activated with Mobilizon 1.0.0-beta.2 # Federation is to be activated with Mobilizon 1.0.0-beta.2
@ -27,8 +27,8 @@ config :mobilizon, :instance,
upload_limit: 10_000_000, upload_limit: 10_000_000,
avatar_upload_limit: 2_000_000, avatar_upload_limit: 2_000_000,
banner_upload_limit: 4_000_000, banner_upload_limit: 4_000_000,
email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL") || "noreply@localhost", email_from: "noreply@localhost",
email_reply_to: System.get_env("MOBILIZON_INSTANCE_EMAIL") || "noreply@localhost" email_reply_to: "noreply@localhost"
config :mime, :types, %{ config :mime, :types, %{
"application/activity+json" => ["activity-json"], "application/activity+json" => ["activity-json"],
@ -37,10 +37,17 @@ config :mime, :types, %{
# Configures the endpoint # Configures the endpoint
config :mobilizon, Mobilizon.Web.Endpoint, config :mobilizon, Mobilizon.Web.Endpoint,
url: [host: "localhost"], http: [
transport_options: [socket_opts: [:inet6]]
],
url: [
host: "mobilizon.local",
scheme: "https"
],
secret_key_base: "1yOazsoE0Wqu4kXk3uC5gu3jDbShOimTCzyFL3OjCdBmOXMyHX87Qmf3+Tu9s0iM", secret_key_base: "1yOazsoE0Wqu4kXk3uC5gu3jDbShOimTCzyFL3OjCdBmOXMyHX87Qmf3+Tu9s0iM",
render_errors: [view: Mobilizon.Web.ErrorView, accepts: ~w(html json)], render_errors: [view: Mobilizon.Web.ErrorView, accepts: ~w(html json)],
pubsub: [name: Mobilizon.PubSub, adapter: Phoenix.PubSub.PG2] pubsub: [name: Mobilizon.PubSub, adapter: Phoenix.PubSub.PG2],
cache_static_manifest: "priv/static/manifest.json"
# Upload configuration # Upload configuration
config :mobilizon, Mobilizon.Web.Upload, config :mobilizon, Mobilizon.Web.Upload,
@ -73,14 +80,31 @@ config :mobilizon, :media_proxy,
] ]
] ]
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Bamboo.SMTPAdapter,
server: "localhost",
hostname: "localhost",
port: 25,
# or {:system, "SMTP_USERNAME"}
username: nil,
# or {:system, "SMTP_PASSWORD"}
password: nil,
# can be `:always` or `:never`
tls: :if_available,
# or {":system", ALLOWED_TLS_VERSIONS"} w/ comma seprated values (e.g. "tlsv1.1,tlsv1.2")
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
# can be `true`
ssl: false,
retries: 1,
# can be `true`
no_mx_lookups: false
# Configures Elixir's Logger # Configures Elixir's Logger
config :logger, :console, config :logger, :console,
format: "$time $metadata[$level] $message\n", format: "$time $metadata[$level] $message\n",
metadata: [:request_id] metadata: [:request_id]
config :mobilizon, Mobilizon.Web.Auth.Guardian, config :mobilizon, Mobilizon.Web.Auth.Guardian, issuer: "mobilizon"
issuer: "mobilizon",
secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo"
config :guardian, Guardian.DB, config :guardian, Guardian.DB,
repo: Mobilizon.Storage.Repo, repo: Mobilizon.Storage.Repo,
@ -96,7 +120,7 @@ config :geolix,
%{ %{
id: :city, id: :city,
adapter: Geolix.Adapter.MMDB2, adapter: Geolix.Adapter.MMDB2,
source: System.get_env("GEOLITE_CITIES_PATH") || "priv/data/GeoLite2-City.mmdb" source: "priv/data/GeoLite2-City.mmdb"
} }
] ]
@ -124,36 +148,31 @@ config :http_signatures,
config :mobilizon, :activitypub, sign_object_fetches: true config :mobilizon, :activitypub, sign_object_fetches: true
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
config :mobilizon, Mobilizon.Service.Geospatial.Nominatim, config :mobilizon, Mobilizon.Service.Geospatial.Nominatim,
endpoint: endpoint: "https://nominatim.openstreetmap.org",
System.get_env("GEOSPATIAL_NOMINATIM_ENDPOINT") || "https://nominatim.openstreetmap.org", api_key: nil
api_key: System.get_env("GEOSPATIAL_NOMINATIM_API_KEY") || nil
config :mobilizon, Mobilizon.Service.Geospatial.Addok, config :mobilizon, Mobilizon.Service.Geospatial.Addok,
endpoint: System.get_env("GEOSPATIAL_ADDOK_ENDPOINT") || "https://api-adresse.data.gouv.fr" endpoint: "https://api-adresse.data.gouv.fr"
config :mobilizon, Mobilizon.Service.Geospatial.Photon, config :mobilizon, Mobilizon.Service.Geospatial.Photon, endpoint: "https://photon.komoot.de"
endpoint: System.get_env("GEOSPATIAL_PHOTON_ENDPOINT") || "https://photon.komoot.de"
config :mobilizon, Mobilizon.Service.Geospatial.GoogleMaps, config :mobilizon, Mobilizon.Service.Geospatial.GoogleMaps,
api_key: System.get_env("GEOSPATIAL_GOOGLE_MAPS_API_KEY") || nil, api_key: nil,
fetch_place_details: System.get_env("GEOSPATIAL_GOOGLE_MAPS_FETCH_PLACE_DETAILS") || true fetch_place_details: true
config :mobilizon, Mobilizon.Service.Geospatial.MapQuest, config :mobilizon, Mobilizon.Service.Geospatial.MapQuest, api_key: nil
api_key: System.get_env("GEOSPATIAL_MAP_QUEST_API_KEY") || nil
config :mobilizon, Mobilizon.Service.Geospatial.Mimirsbrunn, config :mobilizon, Mobilizon.Service.Geospatial.Mimirsbrunn, endpoint: nil
endpoint: System.get_env("GEOSPATIAL_MIMIRSBRUNN_ENDPOINT") || nil
config :mobilizon, Mobilizon.Service.Geospatial.Pelias, config :mobilizon, Mobilizon.Service.Geospatial.Pelias, endpoint: nil
endpoint: System.get_env("GEOSPATIAL_PELIAS_ENDPOINT") || nil
config :mobilizon, :maps, config :mobilizon, :maps,
tiles: [ tiles: [
endpoint: endpoint: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
System.get_env("MAPS_TILES_ENDPOINT") || attribution: "© The OpenStreetMap Contributors"
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution: System.get_env("MAPS_TILES_ATTRIBUTION")
] ]
config :mobilizon, :anonymous, config :mobilizon, :anonymous,

View File

@ -8,10 +8,10 @@ import Config
# with brunch.io to recompile .js and .css sources. # with brunch.io to recompile .js and .css sources.
config :mobilizon, Mobilizon.Web.Endpoint, config :mobilizon, Mobilizon.Web.Endpoint,
http: [ http: [
port: System.get_env("MOBILIZON_INSTANCE_PORT") || 4000 port: 4000
], ],
url: [ url: [
host: System.get_env("MOBILIZON_INSTANCE_HOST") || "mobilizon.local", host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"),
port: 80, port: 80,
scheme: "http" scheme: "http"
], ],
@ -65,13 +65,36 @@ config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Bamboo.LocalAdapter
# Configure your database # Configure your database
config :mobilizon, Mobilizon.Storage.Repo, config :mobilizon, Mobilizon.Storage.Repo,
types: Mobilizon.Storage.PostgresTypes, username: System.get_env("MOBILIZON_DATABASE_USERNAME", "mobilizon"),
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon", password: System.get_env("MOBILIZON_DATABASE_PASSWORD", "mobilizon"),
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon", database: System.get_env("MOBILIZON_DATABASE_DBNAME", "mobilizon_dev"),
database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_dev", hostname: System.get_env("MOBILIZON_DATABASE_HOST", "localhost"),
hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost", port: "5432",
port: System.get_env("MOBILIZON_DATABASE_PORT") || "5432",
pool_size: 10, pool_size: 10,
show_sensitive_data_on_connection_error: true show_sensitive_data_on_connection_error: true
config :mobilizon, :instance,
name: System.get_env("MOBILIZON_INSTANCE_NAME", "Mobilizon"),
hostname: System.get_env("MOBILIZON_INSTANCE_HOST", "Mobilizon"),
email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL"),
email_reply_to: System.get_env("MOBILIZON_INSTANCE_EMAIL"),
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") == "true"
config :mobilizon, :activitypub, sign_object_fetches: false config :mobilizon, :activitypub, sign_object_fetches: false
require Logger
cond do
System.get_env("INSTANCE_CONFIG") &&
File.exists?("./config/#{System.get_env("INSTANCE_CONFIG")}") ->
import_config System.get_env("INSTANCE_CONFIG")
System.get_env("DOCKER", "false") == "false" && File.exists?("./config/dev.secret.exs") ->
import_config "dev.secret.exs"
System.get_env("DOCKER", "false") == "true" ->
Logger.info("Using environment configuration for Docker")
true ->
Logger.error("No configuration file found")
end

View File

@ -2,86 +2,26 @@ import Config
config :mobilizon, Mobilizon.Web.Endpoint, config :mobilizon, Mobilizon.Web.Endpoint,
http: [ http: [
port: System.get_env("MOBILIZON_INSTANCE_PORT") || 4000, port: 4000
transport_options: [socket_opts: [:inet6]]
], ],
url: [ url: [
host: System.get_env("MOBILIZON_INSTANCE_HOST") || "mobilizon.me", host: "mobilizon.local",
port: 443, scheme: "https",
scheme: "https" port: 443
], ]
secret_key_base:
System.get_env("MOBILIZON_SECRET") || "ThisShouldBeAVeryStrongStringPleaseReplaceMe",
cache_static_manifest: "priv/static/manifest.json"
# Configure your database
config :mobilizon, Mobilizon.Storage.Repo,
types: Mobilizon.Storage.PostgresTypes,
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon",
database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_prod",
hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost",
port: System.get_env("MOBILIZON_DATABASE_PORT") || "5432",
pool_size: 15
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Bamboo.SMTPAdapter,
server: "localhost",
hostname: "localhost",
port: 25,
# or {:system, "SMTP_USERNAME"}
username: nil,
# or {:system, "SMTP_PASSWORD"}
password: nil,
# can be `:always` or `:never`
tls: :if_available,
# or {":system", ALLOWED_TLS_VERSIONS"} w/ comma seprated values (e.g. "tlsv1.1,tlsv1.2")
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
# can be `true`
ssl: false,
retries: 1,
# can be `true`
no_mx_lookups: false
# Do not print debug messages in production # Do not print debug messages in production
config :logger, level: System.get_env("MOBILIZON_LOGLEVEL") |> String.to_atom() || :info config :logger, level: :info
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim cond do
System.get_env("INSTANCE_CONFIG") &&
File.exists?("./config/#{System.get_env("INSTANCE_CONFIG")}") ->
import_config System.get_env("INSTANCE_CONFIG")
# ## SSL Support File.exists?("./config/dev.secret.exs") ->
# import_config "dev.secret.exs"
# To get SSL working, you will need to add the `https` key
# to the previous section and set your `:url` port to 443:
#
# config :mobilizon, Mobilizon.Web.Endpoint,
# ...
# url: [host: "example.com", port: 443],
# https: [:inet6,
# port: 443,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")]
#
# Where those two env variables return an absolute path to
# the key and cert in disk or a relative path inside priv,
# for example "priv/ssl/server.key".
#
# We also recommend setting `force_ssl`, ensuring no data is
# ever sent via http, always redirecting to https:
#
# config :mobilizon, Mobilizon.Web.Endpoint,
# force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.
# ## Using releases true ->
# require Logger
# If you are doing OTP releases, you need to instruct Phoenix Logger.error("No configuration file found")
# to start the server for all endpoints: end
#
# config :phoenix, :serve_endpoints, true
#
# Alternatively, you can configure exactly which server to
# start per endpoint:
#
# config :mobilizon, Mobilizon.Web.Endpoint, server: true
#

View File

@ -8,11 +8,13 @@ config :mobilizon, :instance,
# you can enable the server option below. # you can enable the server option below.
config :mobilizon, Mobilizon.Web.Endpoint, config :mobilizon, Mobilizon.Web.Endpoint,
http: [ http: [
port: System.get_env("MOBILIZON_INSTANCE_PORT") || 80 port: 80
], ],
url: [ url: [
host: System.get_env("MOBILIZON_INSTANCE_HOST") || "mobilizon.test" host: "mobilizon.test",
scheme: "http"
], ],
secret_key_base: "some secret",
server: false server: false
# Print only warnings and errors during test # Print only warnings and errors during test
@ -26,7 +28,7 @@ config :logger,
# Configure your database # Configure your database
config :mobilizon, Mobilizon.Storage.Repo, config :mobilizon, Mobilizon.Storage.Repo,
types: Mobilizon.Storage.PostgresTypes, types: Mobilizon.Storage.PostgresTypes,
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon", username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon_test",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon", password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon",
database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_test", database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_test",
hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost", hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost",
@ -44,3 +46,9 @@ config :exvcr,
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock
config :mobilizon, Oban, queues: false, prune: :disabled config :mobilizon, Oban, queues: false, prune: :disabled
config :mobilizon, Mobilizon.Web.Auth.Guardian, secret_key: "some secret"
if System.get_env("DOCKER", "false") == "false" && File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs"
end

View File

@ -22,6 +22,7 @@ services:
- postgres - postgres
environment: environment:
MIX_ENV: "dev" MIX_ENV: "dev"
DOCKER: "true"
MOBILIZON_INSTANCE_NAME: My Mobilizon Instance MOBILIZON_INSTANCE_NAME: My Mobilizon Instance
MOBILIZON_INSTANCE_HOST: mobilizon.me MOBILIZON_INSTANCE_HOST: mobilizon.me
MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me

View File

@ -15,7 +15,7 @@ mix mobilizon.instance gen [<options>]
### Options ### Options
* `-f`, `--force` Whether to erase existing files * `-f`, `--force` Whether to erase existing files
* `-o`, `--output PATH` The path to output the `.env` file. Defaults to `.env.production`. * `-o`, `--output PATH` The path to output the `prod.secret.exs` file. Defaults to `config/prod.secret.exs`.
* `--output_psql PATH` The path to output the SQL script. Defaults to `setup_db.psql`. * `--output_psql PATH` The path to output the SQL script. Defaults to `setup_db.psql`.
* `--domain DOMAIN` The instance's domain * `--domain DOMAIN` The instance's domain
* `--instance_name INSTANCE_NAME` The instance's name * `--instance_name INSTANCE_NAME` The instance's name
@ -25,34 +25,3 @@ mix mobilizon.instance gen [<options>]
* `--dbuser DBUSER` The database user (aka role) to use for the database connection * `--dbuser DBUSER` The database user (aka role) to use for the database connection
* `--dbpass DBPASS` The database user's password to use for the database connection * `--dbpass DBPASS` The database user's password to use for the database connection
* `--dbport DBPORT` The database port * `--dbport DBPORT` The database port
## Depreciated commands
### move_participant_stats
!!! tip "Environment"
You need to run these commands with the appropriate environment loaded
Task to move participant stats directly on the `event` table (so there's no need to count event participants each time).
This task should **only be run once** when migrating from `v1.0.0-beta.1` to `v1.0.0-beta.2`.
This task will be removed in version `v1.0.0-beta.3`.
```bash
mix mobilizon.move_participant_stats
```
### setup_search
!!! tip "Environment"
You need to run these commands with the appropriate environment loaded
Task to setup search for existing events.
This task should **only be run once** when migrating from `v1.0.0-beta.1` to `v1.0.0-beta.2`.
This task will be removed in version `v1.0.0-beta.3`.
```bash
mix mobilizon.setup_search
```

View File

@ -1,7 +1,7 @@
# Manage actors # Manage actors
!!! tip "Environment" !!! tip "Environment"
You need to run these commands with the appropriate environment loaded You need to run these commands with the appropriate environment loaded, so probably prefix with `MIX_ENV=prod`.
## List all available commands ## List all available commands
```bash ```bash

View File

@ -1,7 +1,7 @@
# Manage users # Manage users
!!! tip "Environment" !!! tip "Environment"
You need to run these commands with the appropriate environment loaded You need to run these commands with the appropriate environment loaded, so probably prefix with `MIX_ENV=prod`.
## List all available commands ## List all available commands

View File

@ -3,7 +3,7 @@
Manages remote relays Manages remote relays
!!! tip "Environment" !!! tip "Environment"
You need to run these commands with the appropriate environment loaded You need to run these commands with the appropriate environment loaded, so probably prefix with `MIX_ENV=prod`.
## Make your instance follow a mobilizon instance ## Make your instance follow a mobilizon instance

View File

@ -0,0 +1,31 @@
# Email
Mobilizon requires a SMTP server to deliver emails. Using 3rd-party mail providers (Mandrill, SendGrid, Mailjet, …) will be possible in the future.
## SMTP configuration
Mobilizon default settings assumes a SMTP server listens on `localhost`, port `25`. To specify a specific server and credentials, you can add the following section in your `prod.secret.exs` file and modify credentials to your needs.
```elixir
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Bamboo.SMTPAdapter,
server: "localhost",
hostname: "localhost",
port: 25,
username: nil,
password: nil,
# can be `:always` or `:never`
tls: :if_available,
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
# can be `true`
ssl: false,
retries: 1,
# can be `true`
no_mx_lookups: false,
# can be `:always`. If your smtp relay requires authentication set it to `:always`.
auth: :if_available
```
!!! tip
The hostname option sets the FQDN to the header of your emails, its optional, but if you don't set it, the underlying `gen_smtp` module will use the hostname of your machine, like `localhost`.
You'll need to restart Mobilizon to recompile the app and apply the new settings.

View File

@ -10,18 +10,28 @@ However, providing a geocoding service is quite expensive, especially if you wan
!!! note "Hardware setup" !!! note "Hardware setup"
To give an idea of what hardware is required to self-host a geocoding service, we successfully installed and used [Addok](#addok), [Pelias](#pelias) and [Mimirsbrunn](#mimirsbrunn) on a 8 cores/16GB RAM machine without any issues **importing only French addresses and data**. To give an idea of what hardware is required to self-host a geocoding service, we successfully installed and used [Addok](#addok), [Pelias](#pelias) and [Mimirsbrunn](#mimirsbrunn) on a 8 cores/16GB RAM machine without any issues **importing only French addresses and data**.
## Change geocoder
To change geocoder backend, you need to add the following line in `prod.secret.exs`:
```elixir
config :mobilizon, Mobilizon.Service.Geospatial,
service: Mobilizon.Service.Geospatial.Nominatim
```
And change `Nominatim` to one of the supported geocoders. Depending on the provider, you'll also need to add some special config to specify eventual endpoints or API keys.
For instance, when using `Mimirsbrunn`, you'll need the following configuration:
```elixir
config :mobilizon, Mobilizon.Service.Geospatial,
service: Mobilizon.Service.Geospatial.Mimirsbrunn
config :mobilizon, Mobilizon.Service.Geospatial.Mimirsbrunn,
endpoint: "https://my-mimir-instance.tld"
```
## List of supported geocoders ## List of supported geocoders
This is the list of all geocoders supported by Mobilizon. The current default one is [Nominatim](#nominatim) and uses the official OpenStreetMap instance. This is the list of all geocoders supported by Mobilizon. The current default one is [Nominatim](#nominatim) and uses the official OpenStreetMap instance.
!!! bug
Changing geocoder through `.env` configuration isn't currently supported by Mobilizon.
Instead you need to edit the following line in `config.prod.exs`:
```elixir
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
```
And change `Nominatim` to one of the supported geocoders. This change might be overwritten when updating Mobilizon.
### Nominatim ### Nominatim
[Nominatim](https://wiki.openstreetmap.org/wiki/Nominatim) is a GPL-2.0 licenced tool to search data by name and address. It's written in C and PHP and uses PostgreSQL. [Nominatim](https://wiki.openstreetmap.org/wiki/Nominatim) is a GPL-2.0 licenced tool to search data by name and address. It's written in C and PHP and uses PostgreSQL.
@ -35,6 +45,13 @@ It's the current default search tool on the [OpenStreetMap homepage](https://www
Several companies provide hosted instances of Nominatim that you can query via an API, for example see [MapQuest Open Initiative](https://developer.mapquest.com/documentation/open/nominatim-search). Several companies provide hosted instances of Nominatim that you can query via an API, for example see [MapQuest Open Initiative](https://developer.mapquest.com/documentation/open/nominatim-search).
** Default configuration **
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.Nominatim,
endpoint: "https://nominatim.openstreetmap.org",
api_key: nil
```
### Addok ### Addok
[Addok](https://github.com/addok/addok) is a WTFPL licenced search engine for address (and only address). It's written in Python and uses Redis. [Addok](https://github.com/addok/addok) is a WTFPL licenced search engine for address (and only address). It's written in Python and uses Redis.
@ -42,6 +59,12 @@ It's used by French government for [adresse.data.gouv.fr](https://adresse.data.g
!!! warning "Terms" !!! warning "Terms"
When using France's Addok instance at `api-adresse.data.gouv.fr` (default endpoint for this geocoder if not configured otherwise), you need to read and accept the [GCU](https://adresse.data.gouv.fr/cgu) (in French). When using France's Addok instance at `api-adresse.data.gouv.fr` (default endpoint for this geocoder if not configured otherwise), you need to read and accept the [GCU](https://adresse.data.gouv.fr/cgu) (in French).
** Default configuration **
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.Addok,
endpoint: "https://api-adresse.data.gouv.fr"
```
### Photon ### Photon
@ -50,6 +73,12 @@ It's used by French government for [adresse.data.gouv.fr](https://adresse.data.g
!!! warning "Terms" !!! warning "Terms"
The terms of use for the official instance (default endpoint for this geocoder if not configured otherwise) are simply the following: The terms of use for the official instance (default endpoint for this geocoder if not configured otherwise) are simply the following:
> You can use the API for your project, but please be fair - extensive usage will be throttled. We do not guarantee for the availability and usage might be subject of change in the future. > You can use the API for your project, but please be fair - extensive usage will be throttled. We do not guarantee for the availability and usage might be subject of change in the future.
** Default configuration **
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.Photon,
endpoint: "https://photon.komoot.de"
```
### Pelias ### Pelias
@ -58,24 +87,53 @@ It's used by French government for [adresse.data.gouv.fr](https://adresse.data.g
There's [Geocode Earth](https://geocode.earth/) SAAS that provides a Pelias API. There's [Geocode Earth](https://geocode.earth/) SAAS that provides a Pelias API.
They offer discounts for Open-Source projects. [See the pricing](https://geocode.earth/). They offer discounts for Open-Source projects. [See the pricing](https://geocode.earth/).
**Configuration example**
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.Pelias,
endpoint: nil
```
### Mimirsbrunn ### Mimirsbrunn
[Mimirsbrunn](https://github.com/CanalTP/mimirsbrunn) is an AGPL-3.0 licensed geocoding written in Rust and powered by ElasticSearch. [Mimirsbrunn](https://github.com/CanalTP/mimirsbrunn) is an AGPL-3.0 licensed geocoding written in Rust and powered by ElasticSearch.
Mimirsbrunn is used by [Qwant Maps](https://www.qwant.com/maps) and [Navitia](https://www.navitia.io). Mimirsbrunn is used by [Qwant Maps](https://www.qwant.com/maps) and [Navitia](https://www.navitia.io).
** Default configuration **
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.Mimirsbrunn,
endpoint: nil
```
### Google Maps ### Google Maps
[Google Maps](https://developers.google.com/maps/documentation/geocoding/intro) is a proprietary service that provides APIs for geocoding. [Google Maps](https://developers.google.com/maps/documentation/geocoding/intro) is a proprietary service that provides APIs for geocoding.
They don't have a free plan, but offer credit when creating a new account. [See the pricing](https://cloud.google.com/maps-platform/pricing/). They don't have a free plan, but offer credit when creating a new account. [See the pricing](https://cloud.google.com/maps-platform/pricing/).
** Default configuration **
!!! note
`fetch_place_details` tells GoogleMaps to also fetch some details on a place when geocoding. It can be more expensive, since you're doing two requests to Google instead of one.
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.GoogleMaps,
api_key: nil,
fetch_place_details: true
```
### MapQuest ### MapQuest
[MapQuest](https://developer.mapquest.com/documentation/open/geocoding-api/) is a proprietary service that provides APIs for geocoding. [MapQuest](https://developer.mapquest.com/documentation/open/geocoding-api/) is a proprietary service that provides APIs for geocoding.
They offer a free plan. [See the pricing](https://developer.mapquest.com/plans). They offer a free plan. [See the pricing](https://developer.mapquest.com/plans).
** Default configuration **
```elixir
config :mobilizon, Mobilizon.Service.Geospatial.MapQuest,
api_key: nil
```
### More geocoding services ### More geocoding services
Geocoding implementations are simple modules that need to implement the [`Mobilizon.Service.Geospatial.Provider` behaviour](https://framasoft.frama.io/mobilizon/backend/Mobilizon.Service.Geospatial.Provider.html), so feel free to write your own! Geocoding implementations are simple modules that need to implement the [`Mobilizon.Service.Geospatial.Provider` behaviour](https://framasoft.frama.io/mobilizon/backend/Mobilizon.Service.Geospatial.Provider.html), so feel free to write your own!

View File

@ -1,15 +0,0 @@
# Docker
You can quickly get a server running using Docker. You'll need both [Docker](https://www.docker.com/community-edition) and [Docker-Compose](https://docs.docker.com/compose/install/).
Start by cloning the repo
```bash
git clone https://framagit.org/framasoft/mobilizon && cd mobilizon
```
Then, just run `make` to build containers.
```bash
make
```
This will start a database container, an API container also containing the front-end running on `localhost`.

View File

@ -1,13 +1,14 @@
# Install # Install
!!! info "Docker"
Docker production installation is not yet supported. See [issue #352](https://framagit.org/framasoft/mobilizon/issues/352).
## Pre-requisites ## Pre-requisites
* A Linux machine with **root access** * A Linux machine with **root access**
* A **domain name** (or subdomain) for the Mobilizon server, e.g. `example.net` * A **domain name** (or subdomain) for the Mobilizon server, e.g. `example.net`
* An **SMTP server** to deliver emails * An **SMTP server** to deliver emails
!!! tip
You can also install Mobilizon [with Docker](docker.md).
## Dependencies ## Dependencies
@ -88,12 +89,33 @@ Mobilizon provides a command line tool to generate configuration
mix mobilizon.instance gen mix mobilizon.instance gen
``` ```
This will ask you questions about your instance and generate a `.env.prod` file. This will ask you questions about your setup and your instance to generate a `prod.secret.exs` file in the `config/` folder, and a `setup_db.psql` file to setup the database.
### Database setup
### Migration The `setup_db.psql` file contains SQL instructions to create a PostgreSQL user and database with the chosen credentials and add the required extensions to the Mobilizon database.
Run database migrations: `mix ecto.migrate`. You will have to do this again after most updates. Execute
```bash
sudo -u postgres psql -f setup_db.psql
```
!!! warning
When it's done, don't forget to remove the `setup_db.psql` file.
### Database Migration
Run database migrations:
```bash
MIX_ENV=prod mix ecto.migrate
```
!!! note
Note the `MIX_ENV=prod` environment variable prefix in front of the command. You will have to use it for each `mix` command from now on.
You will have to do this again after most updates.
!!! tip !!! tip
If some migrations fail, it probably means you're not using a recent enough version of PostgreSQL, or that you haven't installed the required extensions. If some migrations fail, it probably means you're not using a recent enough version of PostgreSQL, or that you haven't installed the required extensions.
@ -147,3 +169,13 @@ sudo ln -s /etc/nginx/sites-available/mobilizon.conf /etc/nginx/sites-enabled/
Edit the file `/etc/nginx/sites-available` and adapt it to your own configuration. Edit the file `/etc/nginx/sites-available` and adapt it to your own configuration.
Test the configuration with `sudo nginx -t` and reload nginx with `systemctl reload nginx`. Test the configuration with `sudo nginx -t` and reload nginx with `systemctl reload nginx`.
## Optional tasks
### Geolocation databases
Mobilizon can use geolocation from MMDB format data from sources like [MaxMind GeoIP](https://dev.maxmind.com/geoip/geoip2/geolite2/) databases or [db-ip.com](https://db-ip.com/db/download/ip-to-city-lite) databases. This allows showing events happening near the user's location.
You will need to download the City database and put it into `priv/data/GeoLite2-City.mmdb`.
Mobilizon will only show a warning at startup if the database is missing, but it isn't required.

View File

@ -10,7 +10,7 @@ Some tasks (like database migrations) can take a while, so we advise you to run
# Backup # Backup
Always make sure your database and `.env.production` file are properly backuped before performing upgrades. Always make sure your database and `config` folder are properly backuped before performing upgrades.
Unless stated otherwise in the release notes, the following steps are enough to upgrade Mobilizon. Unless stated otherwise in the release notes, the following steps are enough to upgrade Mobilizon.
@ -57,7 +57,7 @@ cd ../
### Recompile Mobilizon ### Recompile Mobilizon
```bash ```bash
mix compile MIX_ENV=prod mix compile
``` ```
Let's switch back to your regular user. Let's switch back to your regular user.
@ -72,7 +72,7 @@ Go back to the `mobilizon` user.
```bash ```bash
sudo -i -u mobilizon sudo -i -u mobilizon
cd live cd live
mix ecto.migrate MIX_ENV=prod mix ecto.migrate
``` ```
### Restart Mobilizon ### Restart Mobilizon
Let's switch back one last time to your regular user. Let's switch back one last time to your regular user.

View File

@ -1,11 +1,12 @@
# Development # Development
Clone the repository: Clone the repository:
```bash
# With HTTPS
git clone https://framagit.org/framasoft/mobilizon && cd mobilizon
# With SSH ```bash tab="HTTPS"
git clone https://framagit.org/framasoft/mobilizon && cd mobilizon
```
```bash tab="SSH"
git clone git@framagit.org:framasoft/mobilizon.git && cd mobilizon git clone git@framagit.org:framasoft/mobilizon.git && cd mobilizon
``` ```
@ -14,19 +15,19 @@ Run Mobilizon:
* with Docker and Docker-Compose (**Recommended**) * with Docker and Docker-Compose (**Recommended**)
* without Docker and Docker-Compose (This involves more work on your part, use Docker and Docker-Compose if you can) * without Docker and Docker-Compose (This involves more work on your part, use Docker and Docker-Compose if you can)
## With Docker and Docker-Compose ## With Docker
* Install [Docker](https://docs.docker.com/install/#supported-platforms) and [Docker-Compose](https://docs.docker.com/compose/install/) for your system. * Install [Docker](https://docs.docker.com/install/#supported-platforms) and [Docker-Compose](https://docs.docker.com/compose/install/) for your system.
* Run `make start` to build, then launch a database container and an API container. * Run `make start` to build, then launch a database container and an API container.
* Follow the progress of the build with `docker-compose logs -f`. * Follow the progress of the build with `docker-compose logs -f`.
* Access `localhost:4000` in your browser once the containers are fully built and launched. * Access `localhost:4000` in your browser once the containers are fully built and launched.
## Without Docker and Docker-Compose ## Without Docker
* Install dependencies: * Install dependencies:
* Elixir (and Erlang) by following the instructions at [https://elixir-lang.github.io/install.html](https://elixir-lang.github.io/install.html) * [Elixir (and Erlang)](https://elixir-lang.org/install.html)
* [PostgreSQL]() with PostGIS * PostgreSQL >= 9.6 with PostGIS
* Install NodeJS (we guarantee support for the latest LTS and later) ![](https://img.shields.io/badge/node-%3E%3D%2012.0+-brightgreen.svg) * [Install NodeJS](https://nodejs.org/en/download/) (we guarantee support for the latest LTS and later) ![](https://img.shields.io/badge/node-%3E%3D%2012.0+-brightgreen.svg)
* Start services: * Start services:
* Start postgres * Start postgres
* Setup services: * Setup services:
@ -48,3 +49,9 @@ Run Mobilizon:
Now you can visit [`localhost:4000`](http://localhost:4000) in your browser Now you can visit [`localhost:4000`](http://localhost:4000) in your browser
and see the website (server *and* client) in action. and see the website (server *and* client) in action.
## FAQ
### Issues with argon2 when creating users.
This is because you installed deps through Docker and are now using Mobilizon without it, or the other way around. Just `rm -r deps/argon2_elixir` and trigger `mix deps.get` again.

View File

@ -7,7 +7,7 @@ We format our code with the Elixir Formatter and check for issues with [Credo](h
Please run these two commands before pushing code: Please run these two commands before pushing code:
* `mix format` * `mix format`
* `mix credo` * `mix credo --strict -a`
These two commands must not return an error code, since they are required to pass inside CI. These two commands must not return an error code, since they are required to pass inside CI.

4
js/.gitignore vendored
View File

@ -9,10 +9,6 @@ selenium-debug.log
styleguide/ styleguide/
# local env files
.env.local
.env.*.local
# Log files # Log files
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

View File

@ -707,7 +707,7 @@ defmodule Mobilizon.Federation.ActivityPub do
# Get recipients for an activity or object # Get recipients for an activity or object
@spec get_recipients(map()) :: list() @spec get_recipients(map()) :: list()
defp get_recipients(data) do defp get_recipients(data) do
(data["to"] || []) ++ (data["cc"] || []) Map.get(data, "to", []) ++ Map.get(data, "cc", [])
end end
@spec create_event(map(), map()) :: {:ok, map()} @spec create_event(map(), map()) :: {:ok, map()}
@ -870,17 +870,18 @@ defmodule Mobilizon.Federation.ActivityPub do
audience <- audience <-
follower.actor |> Audience.calculate_to_and_cc_from_mentions() |> Map.merge(additional), follower.actor |> Audience.calculate_to_and_cc_from_mentions() |> Map.merge(additional),
reject_data <- %{ reject_data <- %{
"to" => follower.actor.url, "to" => [follower.actor.url],
"type" => "Reject", "type" => "Reject",
"actor" => follower.actor.url, "actor" => follower.target_actor.url,
"object" => follower_as_data "object" => follower_as_data
}, },
update_data <- update_data <-
reject_data audience
|> Map.merge(audience) |> Map.merge(reject_data)
|> Map.merge(%{ |> Map.merge(%{
"id" => "#{Endpoint.url()}/reject/follow/#{follower.id}" "id" => "#{Endpoint.url()}/reject/follow/#{follower.id}"
}) do }) do
Logger.error(inspect(update_data))
{:ok, follower, update_data} {:ok, follower, update_data}
else else
err -> err ->

View File

@ -405,14 +405,14 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
Handle incoming `Reject` activities wrapping a `Follow` activity Handle incoming `Reject` activities wrapping a `Follow` activity
""" """
def do_handle_incoming_reject_following(follow_object, %Actor{} = actor) do def do_handle_incoming_reject_following(follow_object, %Actor{} = actor) do
with {:follow, {:ok, %Follower{approved: false, target_actor: followed} = follow}} <- with {:follow, {:ok, %Follower{target_actor: followed} = follow}} <-
{:follow, get_follow(follow_object)}, {:follow, get_follow(follow_object)},
{:same_actor, true} <- {:same_actor, actor.id == followed.id}, {:same_actor, true} <- {:same_actor, actor.id == followed.id},
{:ok, activity, _} <- {:ok, activity, _} <-
ActivityPub.reject(:follow, follow) do ActivityPub.reject(:follow, follow) do
{:ok, activity, follow} {:ok, activity, follow}
else else
{:follow, _} -> {:follow, _err} ->
Logger.debug( Logger.debug(
"Tried to handle a Reject activity but it's not containing a Follow activity" "Tried to handle a Reject activity but it's not containing a Follow activity"
) )

View File

@ -54,8 +54,8 @@ defmodule Mobilizon.GraphQL.API.Follows do
def reject(%Actor{} = follower, %Actor{} = followed) do def reject(%Actor{} = follower, %Actor{} = followed) do
Logger.debug("We're trying to reject a follow") Logger.debug("We're trying to reject a follow")
with %Follower{} = follow <- with {:follower, %Follower{} = follow} <-
Actors.is_following(follower, followed), {:follower, Actors.is_following(follower, followed)},
{:ok, %Activity{} = activity, %Follower{} = follow} <- {:ok, %Activity{} = activity, %Follower{} = follow} <-
ActivityPub.reject( ActivityPub.reject(
:follow, :follow,
@ -64,7 +64,10 @@ defmodule Mobilizon.GraphQL.API.Follows do
) do ) do
{:ok, activity, follow} {:ok, activity, follow}
else else
%Follower{approved: true} -> {:follower, nil} ->
{:error, "Follow not found"}
{:follower, %Follower{approved: true}} ->
{:error, "Follow already accepted"} {:error, "Follow already accepted"}
end end
end end

View File

@ -58,7 +58,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
paths = paths =
[config_path, psql_path] = [ [config_path, psql_path] = [
Keyword.get(options, :output, ".env"), Keyword.get(options, :output, "config/prod.secret.exs"),
Keyword.get(options, :output_psql, "setup_db.psql") Keyword.get(options, :output_psql, "setup_db.psql")
] ]
@ -113,11 +113,30 @@ defmodule Mix.Tasks.Mobilizon.Instance do
"autogenerated" "autogenerated"
) )
secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64) listen_port =
Common.get_option(
options,
:listen_port,
"What port will the app listen to (leave it if you are using the default setup with nginx)?",
4000
)
listen_ip =
Common.get_option(
options,
:listen_ip,
"What ip will the app listen to (leave it if you are using the default setup with nginx)?",
"127.0.0.1"
)
instance_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
auth_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
template_dir = Application.app_dir(:mobilizon, "priv") <> "/templates"
result_config = result_config =
EEx.eval_file( EEx.eval_file(
".env.sample" |> Path.expand(__DIR__ <> "../../../../../"), "#{template_dir}/config.template.eex",
instance_domain: domain, instance_domain: domain,
instance_port: port, instance_port: port,
instance_email: email, instance_email: email,
@ -128,12 +147,15 @@ defmodule Mix.Tasks.Mobilizon.Instance do
database_username: dbuser, database_username: dbuser,
database_password: dbpass, database_password: dbpass,
version: Mobilizon.Mixfile.project() |> Keyword.get(:version), version: Mobilizon.Mixfile.project() |> Keyword.get(:version),
instance_secret: secret instance_secret: instance_secret,
auth_secret: auth_secret,
listen_ip: listen_ip,
listen_port: listen_port
) )
result_psql = result_psql =
EEx.eval_file( EEx.eval_file(
"support/postgresql/setup_db.psql" |> Path.expand(__DIR__ <> "../../../../../"), "#{template_dir}/setup_db.eex",
database_name: dbname, database_name: dbname,
database_username: dbuser, database_username: dbuser,
database_password: dbpass database_password: dbpass
@ -155,12 +177,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
2. Run `sudo -u postgres psql -f #{Common.escape_sh_path(psql_path)} && rm #{ 2. Run `sudo -u postgres psql -f #{Common.escape_sh_path(psql_path)} && rm #{
Common.escape_sh_path(psql_path) Common.escape_sh_path(psql_path)
}`. }`.
""" <> """
if config_path in [".env.production", ".env.dev", ".env.test"] do
""
else
"3. Run `mv #{Common.escape_sh_path(config_path)} '.env.production'`."
end
) )
else else
Mix.shell().error( Mix.shell().error(

View File

@ -37,7 +37,7 @@ defmodule Mobilizon.Addresses do
%Address{} %Address{}
|> Address.changeset(attrs) |> Address.changeset(attrs)
|> Repo.insert( |> Repo.insert(
on_conflict: :replace_all_except_primary_key, on_conflict: {:replace_all_except, [:id]},
conflict_target: [:origin_id] conflict_target: [:origin_id]
) )
end end

View File

@ -135,6 +135,7 @@ defmodule Mobilizon.Mixfile do
"ecto.setup" "ecto.setup"
], ],
test: [ test: [
"ecto.create",
"ecto.migrate", "ecto.migrate",
&run_test/1 &run_test/1
], ],

View File

@ -21,6 +21,8 @@ markdown_extensions:
plugins: plugins:
- search - search
- git-revision-date-localized - git-revision-date-localized
- minify:
minify_html: true
theme: theme:
name: 'material' name: 'material'
custom_dir: 'docs/theme/' custom_dir: 'docs/theme/'

View File

@ -0,0 +1,31 @@
# Mobilizon instance configuration
import Config
config :mobilizon, Mobilizon.Web.Endpoint,
url: [host: "<%= instance_domain %>", scheme: "https", port: <%= instance_port %>],
http: [ip: {<%= String.replace(listen_ip, ".", ", ") %>}, port: <%= listen_port %>],
secret_key_base: "<%= instance_secret %>"
config :mobilizon, Mobilizon.Web.Auth.Guardian,
secret_key: "<%= auth_secret %>"
config :mobilizon, :instance,
name: "<%= instance_name %>",
description: "Change this to a proper description of your instance",
hostname: "<%= instance_domain %>",
registrations_open: false,
demo: false,
allow_relay: true,
federating: true,
email_from: "tcit@tcit.fr",
email_reply_to: "tcit@tcit.fr"
config :mobilizon, Mobilizon.Storage.Repo,
adapter: Ecto.Adapters.Postgres,
username: "<%= database_username %>",
password: "<%= database_password %>",
database: "<%= database_name %>",
hostname: "<%= database_host %>",
port: "<%= database_port %>",
pool_size: 10

View File

@ -9,7 +9,7 @@ ExecStart=/usr/local/bin/mix phx.server
ExecReload=/bin/kill $MAINPID ExecReload=/bin/kill $MAINPID
KillMode=process KillMode=process
Restart=on-failure Restart=on-failure
EnvironmentFile=/var/www/mobilizon/.env Environment=MIX_ENV=prod
; Some security directives. ; Some security directives.
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops. ; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.