Local copy of Pleroma, an ActivityPub server software. Contains modifications running live on fedi.underscore.world
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

instance.ex 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Mix.Tasks.Pleroma.Instance do
  5. use Mix.Task
  6. import Mix.Pleroma
  7. @shortdoc "Manages Pleroma instance"
  8. @moduledoc """
  9. Manages Pleroma instance.
  10. ## Generate a new instance config.
  11. mix pleroma.instance gen [OPTION...]
  12. If any options are left unspecified, you will be prompted interactively
  13. ## Options
  14. - `-f`, `--force` - overwrite any output files
  15. - `-o PATH`, `--output PATH` - the output file for the generated configuration
  16. - `--output-psql PATH` - the output file for the generated PostgreSQL setup
  17. - `--domain DOMAIN` - the domain of your instance
  18. - `--instance-name INSTANCE_NAME` - the name of your instance
  19. - `--admin-email ADMIN_EMAIL` - the email address of the instance admin
  20. - `--notify-email NOTIFY_EMAIL` - email address for notifications
  21. - `--dbhost HOSTNAME` - the hostname of the PostgreSQL database to use
  22. - `--dbname DBNAME` - the name of the database to use
  23. - `--dbuser DBUSER` - the user (aka role) to use for the database connection
  24. - `--dbpass DBPASS` - the password to use for the database connection
  25. - `--rum Y/N` - Whether to enable RUM indexes
  26. - `--indexable Y/N` - Allow/disallow indexing site by search engines
  27. - `--db-configurable Y/N` - Allow/disallow configuring instance from admin part
  28. - `--uploads-dir` - the directory uploads go in when using a local uploader
  29. - `--static-dir` - the directory custom public files should be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)
  30. - `--listen-ip` - the ip the app should listen to, defaults to 127.0.0.1
  31. - `--listen-port` - the port the app should listen to, defaults to 4000
  32. """
  33. def run(["gen" | rest]) do
  34. {options, [], []} =
  35. OptionParser.parse(
  36. rest,
  37. strict: [
  38. force: :boolean,
  39. output: :string,
  40. output_psql: :string,
  41. domain: :string,
  42. instance_name: :string,
  43. admin_email: :string,
  44. notify_email: :string,
  45. dbhost: :string,
  46. dbname: :string,
  47. dbuser: :string,
  48. dbpass: :string,
  49. rum: :string,
  50. indexable: :string,
  51. db_configurable: :string,
  52. uploads_dir: :string,
  53. static_dir: :string,
  54. listen_ip: :string,
  55. listen_port: :string
  56. ],
  57. aliases: [
  58. o: :output,
  59. f: :force
  60. ]
  61. )
  62. paths =
  63. [config_path, psql_path] = [
  64. Keyword.get(options, :output, "config/generated_config.exs"),
  65. Keyword.get(options, :output_psql, "config/setup_db.psql")
  66. ]
  67. will_overwrite = Enum.filter(paths, &File.exists?/1)
  68. proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
  69. if proceed? do
  70. [domain, port | _] =
  71. String.split(
  72. get_option(
  73. options,
  74. :domain,
  75. "What domain will your instance use? (e.g pleroma.soykaf.com)"
  76. ),
  77. ":"
  78. ) ++ [443]
  79. name =
  80. get_option(
  81. options,
  82. :instance_name,
  83. "What is the name of your instance? (e.g. Pleroma/Soykaf)"
  84. )
  85. email = get_option(options, :admin_email, "What is your admin email address?")
  86. notify_email =
  87. get_option(
  88. options,
  89. :notify_email,
  90. "What email address do you want to use for sending email notifications?",
  91. email
  92. )
  93. indexable =
  94. get_option(
  95. options,
  96. :indexable,
  97. "Do you want search engines to index your site? (y/n)",
  98. "y"
  99. ) === "y"
  100. db_configurable? =
  101. get_option(
  102. options,
  103. :db_configurable,
  104. "Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n)",
  105. "n"
  106. ) === "y"
  107. dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
  108. dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma")
  109. dbuser =
  110. get_option(
  111. options,
  112. :dbuser,
  113. "What is the user used to connect to your database?",
  114. "pleroma"
  115. )
  116. dbpass =
  117. get_option(
  118. options,
  119. :dbpass,
  120. "What is the password used to connect to your database?",
  121. :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
  122. "autogenerated"
  123. )
  124. rum_enabled =
  125. get_option(
  126. options,
  127. :rum,
  128. "Would you like to use RUM indices?",
  129. "n"
  130. ) === "y"
  131. listen_port =
  132. get_option(
  133. options,
  134. :listen_port,
  135. "What port will the app listen to (leave it if you are using the default setup with nginx)?",
  136. 4000
  137. )
  138. listen_ip =
  139. get_option(
  140. options,
  141. :listen_ip,
  142. "What ip will the app listen to (leave it if you are using the default setup with nginx)?",
  143. "127.0.0.1"
  144. )
  145. uploads_dir =
  146. get_option(
  147. options,
  148. :uploads_dir,
  149. "What directory should media uploads go in (when using the local uploader)?",
  150. Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads])
  151. )
  152. static_dir =
  153. get_option(
  154. options,
  155. :static_dir,
  156. "What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)?",
  157. Pleroma.Config.get([:instance, :static_dir])
  158. )
  159. secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
  160. jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
  161. signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
  162. {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
  163. template_dir = Application.app_dir(:pleroma, "priv") <> "/templates"
  164. result_config =
  165. EEx.eval_file(
  166. template_dir <> "/sample_config.eex",
  167. domain: domain,
  168. port: port,
  169. email: email,
  170. notify_email: notify_email,
  171. name: name,
  172. dbhost: dbhost,
  173. dbname: dbname,
  174. dbuser: dbuser,
  175. dbpass: dbpass,
  176. secret: secret,
  177. jwt_secret: jwt_secret,
  178. signing_salt: signing_salt,
  179. web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
  180. web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
  181. db_configurable?: db_configurable?,
  182. static_dir: static_dir,
  183. uploads_dir: uploads_dir,
  184. rum_enabled: rum_enabled,
  185. listen_ip: listen_ip,
  186. listen_port: listen_port
  187. )
  188. result_psql =
  189. EEx.eval_file(
  190. template_dir <> "/sample_psql.eex",
  191. dbname: dbname,
  192. dbuser: dbuser,
  193. dbpass: dbpass,
  194. rum_enabled: rum_enabled
  195. )
  196. shell_info("Writing config to #{config_path}.")
  197. File.write(config_path, result_config)
  198. shell_info("Writing the postgres script to #{psql_path}.")
  199. File.write(psql_path, result_psql)
  200. write_robots_txt(indexable, template_dir)
  201. shell_info(
  202. "\n All files successfully written! Refer to the installation instructions for your platform for next steps"
  203. )
  204. else
  205. shell_error(
  206. "The task would have overwritten the following files:\n" <>
  207. (Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
  208. "Rerun with `--force` to overwrite them."
  209. )
  210. end
  211. end
  212. defp write_robots_txt(indexable, template_dir) do
  213. robots_txt =
  214. EEx.eval_file(
  215. template_dir <> "/robots_txt.eex",
  216. indexable: indexable
  217. )
  218. static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static/")
  219. unless File.exists?(static_dir) do
  220. File.mkdir_p!(static_dir)
  221. end
  222. robots_txt_path = Path.join(static_dir, "robots.txt")
  223. if File.exists?(robots_txt_path) do
  224. File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
  225. shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
  226. end
  227. File.write(robots_txt_path, robots_txt)
  228. shell_info("Writing #{robots_txt_path}.")
  229. end
  230. end