1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Mix.Tasks.Pleroma.Instance do
9 @shortdoc "Manages Pleroma instance"
11 Manages Pleroma instance.
13 ## Generate a new instance config.
15 mix pleroma.instance gen [OPTION...]
17 If any options are left unspecified, you will be prompted interactively
21 - `-f`, `--force` - overwrite any output files
22 - `-o PATH`, `--output PATH` - the output file for the generated configuration
23 - `--output-psql PATH` - the output file for the generated PostgreSQL setup
24 - `--domain DOMAIN` - the domain of your instance
25 - `--instance-name INSTANCE_NAME` - the name of your instance
26 - `--admin-email ADMIN_EMAIL` - the email address of the instance admin
27 - `--notify-email NOTIFY_EMAIL` - email address for notifications
28 - `--dbhost HOSTNAME` - the hostname of the PostgreSQL database to use
29 - `--dbname DBNAME` - the name of the database to use
30 - `--dbuser DBUSER` - the user (aka role) to use for the database connection
31 - `--dbpass DBPASS` - the password to use for the database connection
32 - `--indexable Y/N` - Allow/disallow indexing site by search engines
33 - `--db-configurable Y/N` - Allow/disallow configuring instance from admin part
34 - `--uploads-dir` - the directory uploads go in when using a local uploader
35 - `--static-dir` - the directory custom public files should be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)
38 def run(["gen" | rest]) do
47 instance_name: :string,
49 notify_email: :string,
55 db_configurable: :string,
66 [config_path, psql_path] = [
67 Keyword.get(options, :output, "config/generated_config.exs"),
68 Keyword.get(options, :output_psql, "config/setup_db.psql")
71 will_overwrite = Enum.filter(paths, &File.exists?/1)
72 proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
80 "What domain will your instance use? (e.g pleroma.soykaf.com)"
89 "What is the name of your instance? (e.g. Pleroma/Soykaf)"
92 email = get_option(options, :admin_email, "What is your admin email address?")
98 "What email address do you want to use for sending email notifications?",
106 "Do you want search engines to index your site? (y/n)",
114 "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
118 dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
120 dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
126 "What is the user used to connect to your database?",
134 "What is the password used to connect to your database?",
135 :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
143 "What directory should media uploads go in (when using the local uploader)?",
144 Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads])
151 "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
152 Pleroma.Config.get([:instance, :static_dir])
155 secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
156 signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
157 {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
161 "sample_config.eex" |> Path.expand(__DIR__),
165 notify_email: notify_email,
172 signing_salt: signing_salt,
173 web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
174 web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
175 db_configurable?: db_configurable?,
176 static_dir: static_dir,
177 uploads_dir: uploads_dir
182 "sample_psql.eex" |> Path.expand(__DIR__),
189 "Writing config to #{config_path}. You should rename it to config/prod.secret.exs or config/dev.secret.exs."
192 File.write(config_path, result_config)
193 shell_info("Writing #{psql_path}.")
194 File.write(psql_path, result_psql)
196 write_robots_txt(indexable)
202 1. Verify the contents of the generated files.
203 2. Run `sudo -u postgres psql -f #{escape_sh_path(psql_path)}`.
205 if config_path in ["config/dev.secret.exs", "config/prod.secret.exs"] do
208 "3. Run `mv #{escape_sh_path(config_path)} 'config/prod.secret.exs'`."
213 "The task would have overwritten the following files:\n" <>
214 (Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
215 "Rerun with `--force` to overwrite them."
220 defp write_robots_txt(indexable) do
223 Path.expand("robots_txt.eex", __DIR__),
227 static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static/")
229 unless File.exists?(static_dir) do
230 File.mkdir_p!(static_dir)
233 robots_txt_path = Path.join(static_dir, "robots.txt")
235 if File.exists?(robots_txt_path) do
236 File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
237 shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
240 File.write(robots_txt_path, robots_txt)
241 shell_info("Writing #{robots_txt_path}.")