1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 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. Pleroma/Soykaf)"
71 email = get_option(options, :admin_email, "What is your admin email address?")
77 "What email address do you want to use for sending email notifications?",
85 "Do you want search engines to index your site? (y/n)",
93 "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
97 dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
99 dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
105 "What is the user used to connect to your database?",
113 "What is the password used to connect to your database?",
114 :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
122 "Would you like to use RUM indices?",
130 "What port will the app listen to (leave it if you are using the default setup with nginx)?",
138 "What ip will the app listen to (leave it if you are using the default setup with nginx)?",
146 "What directory should media uploads go in (when using the local uploader)?",
147 Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads])
154 "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
155 Pleroma.Config.get([:instance, :static_dir])
158 Config.put([:instance, :static_dir], static_dir)
160 secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
161 jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
162 signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
163 {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
164 template_dir = Application.app_dir(:pleroma, "priv") <> "/templates"
168 template_dir <> "/sample_config.eex",
172 notify_email: notify_email,
179 jwt_secret: jwt_secret,
180 signing_salt: signing_salt,
181 web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
182 web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
183 db_configurable?: db_configurable?,
184 static_dir: static_dir,
185 uploads_dir: uploads_dir,
186 rum_enabled: rum_enabled,
187 listen_ip: listen_ip,
188 listen_port: listen_port
193 template_dir <> "/sample_psql.eex",
197 rum_enabled: rum_enabled
200 shell_info("Writing config to #{config_path}.")
202 File.write(config_path, result_config)
203 shell_info("Writing the postgres script to #{psql_path}.")
204 File.write(psql_path, result_psql)
206 write_robots_txt(indexable, template_dir)
209 "\n All files successfully written! Refer to the installation instructions for your platform for next steps"
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, template_dir) do
223 template_dir <> "/robots_txt.eex",
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}.")