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,
40 skip_release_env: :boolean,
41 release_env_file: :string
50 [config_path, psql_path] = [
51 Keyword.get(options, :output, "config/generated_config.exs"),
52 Keyword.get(options, :output_psql, "config/setup_db.psql")
55 will_overwrite = Enum.filter(paths, &File.exists?/1)
56 proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
64 "What domain will your instance use? (e.g pleroma.soykaf.com)"
73 "What is the name of your instance? (e.g. The Corndog Emporium)",
77 email = get_option(options, :admin_email, "What is your admin email address?")
83 "What email address do you want to use for sending email notifications?",
91 "Do you want search engines to index your site? (y/n)",
99 "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
103 dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
105 dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
111 "What is the user used to connect to your database?",
119 "What is the password used to connect to your database?",
120 :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
128 "Would you like to use RUM indices?",
136 "What port will the app listen to (leave it if you are using the default setup with nginx)?",
144 "What ip will the app listen to (leave it if you are using the default setup with nginx)?",
152 "What directory should media uploads go in (when using the local uploader)?",
153 Config.get([Pleroma.Uploaders.Local, :uploads])
161 "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
162 Config.get([:instance, :static_dir])
170 "Do you want to strip location (GPS) data from uploaded images? (y/n)",
178 "Do you want to anonymize the filenames of uploads? (y/n)",
186 "Do you want to deduplicate uploaded files? (y/n)",
190 Config.put([:instance, :static_dir], static_dir)
192 secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
193 jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
194 signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
195 {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
196 template_dir = Application.app_dir(:pleroma, "priv") <> "/templates"
200 template_dir <> "/sample_config.eex",
204 notify_email: notify_email,
211 jwt_secret: jwt_secret,
212 signing_salt: signing_salt,
213 web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
214 web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
215 db_configurable?: db_configurable?,
216 static_dir: static_dir,
217 uploads_dir: uploads_dir,
218 rum_enabled: rum_enabled,
219 listen_ip: listen_ip,
220 listen_port: listen_port,
223 strip: strip_uploads,
224 anonymize: anonymize_uploads,
225 dedupe: dedupe_uploads
231 template_dir <> "/sample_psql.eex",
235 rum_enabled: rum_enabled
238 shell_info("Writing config to #{config_path}.")
240 File.write(config_path, result_config)
241 shell_info("Writing the postgres script to #{psql_path}.")
242 File.write(psql_path, result_psql)
244 write_robots_txt(static_dir, indexable, template_dir)
246 if Keyword.get(options, :skip_release_env, false) do
248 Release environment file is skip. Please generate the release env file before start.
249 `MIX_ENV=#{Mix.env()} mix pleroma.release_env gen`
252 shell_info("Generation the environment file:")
255 with path when not is_nil(path) <- Keyword.get(options, :release_env_file) do
256 ["gen", "--path", path]
261 Mix.Tasks.Pleroma.ReleaseEnv.run(release_env_args)
265 "\n All files successfully written! Refer to the installation instructions for your platform for next steps."
268 if db_configurable? do
270 " 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."
275 "The task would have overwritten the following files:\n" <>
276 (Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
277 "Rerun with `--force` to overwrite them."
282 defp write_robots_txt(static_dir, indexable, template_dir) do
285 template_dir <> "/robots_txt.eex",
289 unless File.exists?(static_dir) do
290 File.mkdir_p!(static_dir)
293 robots_txt_path = Path.join(static_dir, "robots.txt")
295 if File.exists?(robots_txt_path) do
296 File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
297 shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
300 File.write(robots_txt_path, robots_txt)
301 shell_info("Writing #{robots_txt_path}.")
304 defp upload_filters(filters) when is_map(filters) do
307 [Pleroma.Upload.Filter.ExifTool]
313 if filters.anonymize do
314 enabled_filters ++ [Pleroma.Upload.Filter.AnonymizeFilename]
321 enabled_filters ++ [Pleroma.Upload.Filter.Dedupe]
329 defp upload_filters(_), do: []