0853.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <title>Run Mastodon - A Federated Twitter Alternative - in Docker</title>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6. <meta charset="UTF-8">
  7. <meta name="keywords" content="Browser Based,Docker Made Easy,Home Lab,Home Lab Ideas,Install Guide,Self-Hosted,Web Based,Web Based Tools,Alternative,Homelab,Linux,Micro Blogging,Microblogging,Social Media,Social Network,Twitter,Twitter Alternative,Mastodon,Federated,Container,Containerization,Docker,Docker How To,Docker Installation Tutorial,Docker Simplified,Docker Tutorial,Ubuntu,How To,Tutorial,i12bretro">
  8. <meta name="author" content="i12bretro">
  9. <meta name="description" content="Run Mastodon - A Federated Twitter Alternative - in Docker">
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  11. <meta name="revised" content="02/10/2023 02:00:52 PM" />
  12. <link rel="icon" type="image/x-icon" href="includes/favicon.ico">
  13. <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  14. <script type="text/javascript" src="includes/js/steps.js"></script>
  15. <link href="css/steps.css" rel="stylesheet" type="text/css" />
  16. </head>
  17. <body>
  18. <div id="gridContainer">
  19. <div class="topMargin"></div>
  20. <div id="listName" class="topMargin">
  21. <h1>Run Mastodon - A Federated Twitter Alternative - in Docker</h1>
  22. </div>
  23. <div></div>
  24. <div id="content">
  25. <h2>What is Mastodon?</h2>
  26. <blockquote><em>Mastodon is a free, open-source social network server based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub)! -<a href="https://github.com/mastodon/mastodon" target="_blank">https://github.com/mastodon/mastodon</a></em></blockquote>
  27. <h2>Installing Docker</h2>
  28. <ol>
  29. <li>Log into the Linux based device</li>
  30. <li>Run the following commands in the terminal
  31. <div class="codeBlock"># install prerequisites<br />
  32. sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg-agent -y<br />
  33. # add docker gpg key<br />
  34. curl -fsSL https://download.docker.com/linux/$(awk -F&#39;=&#39; &#39;/^ID=/{ print $NF }&#39; /etc/os-release)/gpg | sudo apt-key add -<br />
  35. # add docker software repository<br />
  36. sudo add-apt-repository &quot;deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/$(awk -F&#39;=&#39; &#39;/^ID=/{ print $NF }&#39; /etc/os-release) $(lsb_release -cs) stable&quot;<br />
  37. # install docker<br />
  38. sudo apt install docker-ce docker-compose containerd.io -y<br />
  39. # enable and start docker service<br />
  40. sudo systemctl enable docker &amp;&amp; sudo systemctl start docker<br />
  41. # add the current user to the docker group<br />
  42. sudo usermod -aG docker $USER<br />
  43. # reauthenticate for the new group membership to take effect<br />
  44. su - $USER</div>
  45. </li>
  46. </ol>
  47. <h2>Generating SSL Certificate with Let&#39;s Encrypt</h2>
  48. <p><em>NOTE: In order for Let&#39;s Encrypt to verify ownership of the DNS name, the host certbot is running from must be accessible via port 80 (http) or port 443 (https). For homelab users, this will normally involve port forwarding from the router to the certbot host, which is beyond the scope of this tutorial. Just note, I have forwarded port 80 on my router to the host running certbot for this handshake to complete successfully.</em></p>
  49. <ol>
  50. <li>Continue with the following commands in a terminal window
  51. <div class="codeBlock"># remove apt version of certbot if installed<br />
  52. sudo apt remove certbot -y<br />
  53. # install snapd<br />
  54. sudo apt install snapd -y<br />
  55. # install snap core and update<br />
  56. sudo snap install core; sudo snap refresh core<br />
  57. # install certbot snap<br />
  58. sudo snap install --classic certbot<br />
  59. # create certbot symbolic link<br />
  60. sudo ln -s /snap/bin/certbot /usr/bin/certbot<br />
  61. # if a web server process is currently using port 80, stop it before proceeding<br />
  62. # generate a certificate<br />
  63. sudo certbot certonly --standalone --preferred-challenges http -d &lt;%DNS NAME%&gt;</div>
  64. </li>
  65. <li>When prompted, enter an email address and agree to the terms of service</li>
  66. <li>Choose whether to share your email and receive emails from certbot</li>
  67. <li>Certbot will output information regarding the location of the certificate files</li>
  68. <li>Continue with the following commands in a terminal window
  69. <div class="codeBlock"># create ssl-certs group<br />
  70. sudo groupadd ssl-certs<br />
  71. # add $USER and root users to group<br />
  72. sudo usermod -aG ssl-certs $USER<br />
  73. sudo usermod -aG ssl-certs root<br />
  74. # verify the members of ssl-cert<br />
  75. getent group ssl-certs<br />
  76. # set owner group of /etc/letsencrypt<br />
  77. sudo chgrp -R ssl-certs /etc/letsencrypt<br />
  78. # set permissions on /etc/letsencrypt<br />
  79. sudo chmod -R g=rX /etc/letsencrypt</div>
  80. </li>
  81. </ol>
  82. <h2>Running the Mastodon Container Stack</h2>
  83. <ol>
  84. <li>Now that Docker is installed, run the following commands to setup the Mastodon Docker containers
  85. <div class="codeBlock"># create working directories<br />
  86. mkdir ~/docker/postgres -p &amp;&amp; mkdir ~/docker/redis -p &amp;&amp; mkdir ~/docker/mastodon/public/system -p &amp;&amp; mkdir ~/docker/nginx/conf -p<br />
  87. # pull the mastodon web container<br />
  88. docker pull tootsuite/mastodon<br />
  89. # generate secrets, run this 2 times<br />
  90. docker run --rm -it tootsuite/mastodon bundle exec rake secret<br />
  91. # generate VAPID keys<br />
  92. docker run --rm -it tootsuite/mastodon bundle exec rake mastodon:webpush:generate_vapid_key<br />
  93. # create a mastodon .env file<br />
  94. # copy the generated secrets and keys into the .env file<br />
  95. # make sure to set the LOCAL_DOMAIN as this cannot be changed later<br />
  96. nano ~/docker/mastodon/.env</div>
  97. </li>
  98. <li>Paste the following into the .env file, then edit the LOCAL_DOMAIN, WEB_DOMAIN, PostgreSQL, Secrets, Web Push and SMTP settings<br />
  99. <span style="font-size:12px;">NOTE: A full example .env file can be find at <a href="https://github.com/mastodon/mastodon/blob/main/.env.production.sample" style="font-size:12px;" target="_blank">https://github.com/mastodon/mastodon/blob/main/.env.production.sample</a></span>
  100. <p># This is a sample configuration file. You can generate your configuration<br />
  101. # with the `rake mastodon:setup` interactive setup wizard, but to customize<br />
  102. # your setup even further, you&#39;ll need to edit it manually. This sample does<br />
  103. # not demonstrate all available configuration options. Please look at<br />
  104. # https://docs.joinmastodon.org/admin/config/ for the full documentation.</p>
  105. <p># Note that this file accepts slightly different syntax depending on whether<br />
  106. # you are using `docker-compose` or not. In particular, if you use<br />
  107. # `docker-compose`, the value of each declared variable will be taken verbatim,<br />
  108. # including surrounding quotes.<br />
  109. # See: https://github.com/mastodon/mastodon/issues/16895</p>
  110. <p># Federation<br />
  111. # ----------<br />
  112. # This identifies your server and cannot be changed safely later<br />
  113. # ----------<br />
  114. LOCAL_DOMAIN=i12bretro.local</p>
  115. <p># ----------<br />
  116. # Optional, if different than LOCAL_DOMAIN<br />
  117. # ----------<br />
  118. #WEB_DOMAIN=toots.webredirect.org</p>
  119. <p># Redis<br />
  120. # -----<br />
  121. REDIS_HOST=redis<br />
  122. REDIS_PORT=6379</p>
  123. <p># PostgreSQL<br />
  124. # ----------<br />
  125. DB_HOST=postgres<br />
  126. DB_USER=mastodon_rw<br />
  127. DB_NAME=mastodon<br />
  128. DB_PASS=Ma5toD0n!<br />
  129. DB_PORT=5432</p>
  130. <p># Secrets<br />
  131. # -------<br />
  132. # Make sure to use `rake secret` to generate secrets<br />
  133. # -------<br />
  134. SECRET_KEY_BASE=<br />
  135. OTP_SECRET=</p>
  136. <p># Web Push<br />
  137. # --------<br />
  138. # Generate with `rake mastodon:webpush:generate_vapid_key`<br />
  139. # --------<br />
  140. VAPID_PRIVATE_KEY=<br />
  141. VAPID_PUBLIC_KEY=</p>
  142. <p># Sending mail<br />
  143. # ------------<br />
  144. SMTP_SERVER=smtp.example.com<br />
  145. SMTP_PORT=25<br />
  146. SMTP_LOGIN=<br />
  147. SMTP_PASSWORD=<br />
  148. SMTP_FROM_ADDRESS=mastodon@example.com</p>
  149. <p><br />
  150. # IP and session retention<br />
  151. # -----------------------<br />
  152. # Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml<br />
  153. # to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).<br />
  154. # -----------------------<br />
  155. IP_RETENTION_PERIOD=31556952<br />
  156. SESSION_RETENTION_PERIOD=31556952</p>
  157. </li>
  158. <li>Press CTRL+O, Enter, CTRL+X to write the changes to .env</li>
  159. <li>Continue with the following steps in the terminal
  160. <div class="codeBlock"># set owner of docker directory<br />
  161. sudo chown &quot;$USER&quot;:&quot;$USER&quot; ~/docker -R<br />
  162. # create containers<br />
  163. docker network create containers<br />
  164. # run the postgesql container<br />
  165. docker run -d --name postgres -e POSTGRES_USER=mastodon_rw -e POSTGRES_PASSWORD=Ma5toD0n! -e POSTGRES_DB=mastodon -v ~/docker/postgres:/var/lib/postgresql/data --network containers --restart=unless-stopped postgres:latest<br />
  166. # run the redis container<br />
  167. docker run -d --name redis -v ~/docker/redis:/data --network containers --restart=unless-stopped redis<br />
  168. # initialize the mastodon database<br />
  169. docker run --rm -it --network containers --env-file ~/docker/mastodon/.env tootsuite/mastodon rails db:migrate<br />
  170. # run the mastodon frontend container<br />
  171. docker run -d --name mastodon --env-file ~/docker/mastodon/.env -p 3000:3000 -v ~/docker/mastodon/public/system:/mastodon/public/system --network containers --restart=unless-stopped tootsuite/mastodon bash -c &quot;rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000&quot;<br />
  172. # connect to shell inside mastodon container<br />
  173. docker exec -it mastodon /bin/bash<br />
  174. # set the RAILS_ENV variable<br />
  175. RAILS_ENV=production<br />
  176. # create an owner/admin account<br />
  177. # copy the password output for later<br />
  178. bin/tootctl accounts create &lt;%username%&gt; --email &lt;%email address%&gt; --confirmed --role Owner<br />
  179. # exit the container<br />
  180. exit<br />
  181. # run the mastodon streaming container<br />
  182. docker run -d --name mastodon-stream --env-file ~/docker/mastodon/.env -p 4000:4000 --network containers --restart=unless-stopped tootsuite/mastodon node ./streaming<br />
  183. # run the mastodon sidekiq container<br />
  184. docker run -d --name mastodon-sidekiq --env-file ~/docker/mastodon/.env --network containers -v ~/docker/mastodon/public/system:/mastodon/public/system --restart=unless-stopped tootsuite/mastodon bundle exec sidekiq</div>
  185. </li>
  186. </ol>
  187. <h2>Setting Up the Nginx Proxy Server</h2>
  188. <ol>
  189. <li>Now that all the pieces of Mastodon are running, we&#39;ll configure an nginx proxy server
  190. <div class="codeBlock"># download the default mastodon nginx configuration<br />
  191. wget -O ~/docker/nginx/conf/mastodon.conf https://raw.githubusercontent.com/mastodon/mastodon/main/dist/nginx.conf<br />
  192. # replace some options to work running in docker containers<br />
  193. sed -i &quot;s/try_files \$uri =404;/try_files \$uri @proxy;/&quot; ~/docker/nginx/conf/mastodon.conf<br />
  194. # update the server_name with the URL being used to reach mastodon<br />
  195. # make sure to replace WEB_DOMAIN<br />
  196. sed -i &quot;s/server_name example.com;/\server_name &lt;%WEB_DOMAIN%&gt;;/&quot; ~/docker/nginx/conf/mastodon.conf<br />
  197. # update mastodon frontend server<br />
  198. sed -i &#39;s/server 127.0.0.1:3000/server mastodon:3000/&#39; ~/docker/nginx/conf/mastodon.conf<br />
  199. # update mastodon stream server<br />
  200. sed -i &#39;s/server 127.0.0.1:4000/server mastodon-stream:4000/&#39; ~/docker/nginx/conf/mastodon.conf<br />
  201. # update the ssl certificate path<br />
  202. # make sure to replace DNS NAME<br />
  203. sed -i &#39;s/# ssl_certificate\s*\/etc\/letsencrypt\/live\/example.com\/fullchain.pem;/ssl_certificate\t\/etc\/letsencrypt\/live\/&lt;%DNS NAME%&gt;\/fullchain.pem;/&#39; ~/docker/nginx/conf/mastodon.conf<br />
  204. # update the ssl key path<br />
  205. # make sure to replace DNS NAME<br />
  206. sed -i &#39;s/# ssl_certificate_key\s*\/etc\/letsencrypt\/live\/example.com\/privkey.pem;/ssl_certificate_key\t\/etc\/letsencrypt\/live\/&lt;%DNS NAME%&gt;\/privkey.pem;/&#39; ~/docker/nginx/conf/mastodon.conf<br />
  207. # create nginx proxy container<br />
  208. docker run --name nginx -p 80:80 -p 443:443 --network containers -v ~/docker/nginx/conf:/etc/nginx/conf.d:ro -v /etc/letsencrypt:/etc/letsencrypt:ro -d nginx</div>
  209. </li>
  210. <li>Open a web browser and navigate to https://&lt;%WEB_DOMAIN%&gt;</li>
  211. <li>Click Sign in then login using the owner email and generated password from earlier</li>
  212. <li>Select Preferences from the lower right of the user interface</li>
  213. <li>Select Account from the left navigation menu</li>
  214. <li>Enter the generated password in the Current password field, then enter and confirm a new password for the current user &gt; Click Save Changes</li>
  215. <li>Select Logout from the left navigation menu</li>
  216. <li>Log back in using the owner account email address and updated password</li>
  217. <li>Welcome to Mastodon</li>
  218. </ol> </div>
  219. </div>
  220. </body>
  221. </html>