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,
37 strip_uploads: :string,
38 anonymize_uploads: :string,
39 dedupe_uploads: :string
48 [config_path, psql_path] = [
49 Keyword.get(options, :output, "config/generated_config.exs"),
50 Keyword.get(options, :output_psql, "config/setup_db.psql")
53 will_overwrite = Enum.filter(paths, &File.exists?/1)
54 proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
62 "What domain will your instance use? (e.g pleroma.soykaf.com)"
71 "What is the name of your instance? (e.g. The Corndog Emporium)",
75 email = get_option(options, :admin_email, "What is your admin email address?")
81 "What email address do you want to use for sending email notifications?",
89 "Do you want search engines to index your site? (y/n)",
97 "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
101 dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
103 dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
109 "What is the user used to connect to your database?",
117 "What is the password used to connect to your database?",
118 :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
126 "Would you like to use RUM indices?",
134 "What port will the app listen to (leave it if you are using the default setup with nginx)?",
142 "What ip will the app listen to (leave it if you are using the default setup with nginx)?",
150 "What directory should media uploads go in (when using the local uploader)?",
151 Config.get([Pleroma.Uploaders.Local, :uploads])
159 "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
160 Config.get([:instance, :static_dir])
168 "Do you want to strip location (GPS) data from uploaded images? (y/n)",
176 "Do you want to anonymize the filenames of uploads? (y/n)",
184 "Do you want to deduplicate uploaded files? (y/n)",
188 Config.put([:instance, :static_dir], static_dir)
190 secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
191 jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
192 signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
193 {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
194 template_dir = Application.app_dir(:pleroma, "priv") <> "/templates"
198 template_dir <> "/sample_config.eex",
202 notify_email: notify_email,
209 jwt_secret: jwt_secret,
210 signing_salt: signing_salt,
211 web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
212 web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
213 db_configurable?: db_configurable?,
214 static_dir: static_dir,
215 uploads_dir: uploads_dir,
216 rum_enabled: rum_enabled,
217 listen_ip: listen_ip,
218 listen_port: listen_port,
221 strip: strip_uploads,
222 anonymize: anonymize_uploads,
223 dedupe: dedupe_uploads
229 template_dir <> "/sample_psql.eex",
233 rum_enabled: rum_enabled
236 shell_info("Writing config to #{config_path}.")
238 File.write(config_path, result_config)
239 shell_info("Writing the postgres script to #{psql_path}.")
240 File.write(psql_path, result_psql)
242 write_robots_txt(static_dir, indexable, template_dir)
245 "\n All files successfully written! Refer to the installation instructions for your platform for next steps."
248 if db_configurable? do
250 " 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."
255 "The task would have overwritten the following files:\n" <>
256 (Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
257 "Rerun with `--force` to overwrite them."
262 defp write_robots_txt(static_dir, indexable, template_dir) do
265 template_dir <> "/robots_txt.eex",
269 unless File.exists?(static_dir) do
270 File.mkdir_p!(static_dir)
273 robots_txt_path = Path.join(static_dir, "robots.txt")
275 if File.exists?(robots_txt_path) do
276 File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
277 shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
280 File.write(robots_txt_path, robots_txt)
281 shell_info("Writing #{robots_txt_path}.")
284 defp upload_filters(filters) when is_map(filters) do
287 [Pleroma.Upload.Filter.ExifTool]
293 if filters.anonymize do
294 enabled_filters ++ [Pleroma.Upload.Filter.AnonymizeFilename]
301 enabled_filters ++ [Pleroma.Upload.Filter.Dedupe]
309 defp upload_filters(_), do: []