1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Mix.Tasks.Pleroma.Instance do
11 @shortdoc "Manages Pleroma instance"
12 @moduledoc File.read!("docs/administration/CLI_tasks/instance.md")
14 def run(["gen" | rest]) do
23 instance_name: :string,
25 notify_email: :string,
32 db_configurable: :string,
45 [config_path, psql_path] = [
46 Keyword.get(options, :output, "config/generated_config.exs"),
47 Keyword.get(options, :output_psql, "config/setup_db.psql")
50 will_overwrite = Enum.filter(paths, &File.exists?/1)
51 proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
59 "What domain will your instance use? (e.g pleroma.soykaf.com)"
68 "What is the name of your instance? (e.g. The Corndog Emporium)",
72 email = get_option(options, :admin_email, "What is your admin email address?")
78 "What email address do you want to use for sending email notifications?",
86 "Do you want search engines to index your site? (y/n)",
94 "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
98 dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
100 dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
106 "What is the user used to connect to your database?",
114 "What is the password used to connect to your database?",
115 :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
123 "Would you like to use RUM indices?",
131 "What port will the app listen to (leave it if you are using the default setup with nginx)?",
139 "What ip will the app listen to (leave it if you are using the default setup with nginx)?",
147 "What directory should media uploads go in (when using the local uploader)?",
148 Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads])
155 "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
156 Pleroma.Config.get([:instance, :static_dir])
159 Config.put([:instance, :static_dir], static_dir)
161 secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
162 jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
163 signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
164 {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
165 template_dir = Application.app_dir(:pleroma, "priv") <> "/templates"
169 template_dir <> "/sample_config.eex",
173 notify_email: notify_email,
180 jwt_secret: jwt_secret,
181 signing_salt: signing_salt,
182 web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
183 web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
184 db_configurable?: db_configurable?,
185 static_dir: static_dir,
186 uploads_dir: uploads_dir,
187 rum_enabled: rum_enabled,
188 listen_ip: listen_ip,
189 listen_port: listen_port
194 template_dir <> "/sample_psql.eex",
198 rum_enabled: rum_enabled
201 shell_info("Writing config to #{config_path}.")
203 File.write(config_path, result_config)
204 shell_info("Writing the postgres script to #{psql_path}.")
205 File.write(psql_path, result_psql)
207 write_robots_txt(indexable, template_dir)
210 "\n All files successfully written! Refer to the installation instructions for your platform for next steps."
213 if db_configurable? do
215 " Please transfer your config to the database after running database migrations. Refer to \"Transfering the config to/from the database\" section of the docs for more information."
220 "The task would have overwritten the following files:\n" <>
221 (Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
222 "Rerun with `--force` to overwrite them."
227 defp write_robots_txt(indexable, template_dir) do
230 template_dir <> "/robots_txt.eex",
234 static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static/")
236 unless File.exists?(static_dir) do
237 File.mkdir_p!(static_dir)
240 robots_txt_path = Path.join(static_dir, "robots.txt")
242 if File.exists?(robots_txt_path) do
243 File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
244 shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
247 File.write(robots_txt_path, robots_txt)
248 shell_info("Writing #{robots_txt_path}.")