PixelFed bash installer
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.

pixelfed-install.sh 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. #!/bin/bash
  2. # simple root check
  3. if [ `id -u ` -ne 0 ]; then
  4. echo "This script must be run as root.\nJust type su - and enter root password." >&2
  5. exit 1
  6. fi
  7. # upgrade system and install software
  8. apt update
  9. apt -y dist-upgrade
  10. apt -y install apt-transport-https wget curl git software-properties-common dialog unzip
  11. apt -y autoremove
  12. # gather informations with dialogs
  13. # open fd
  14. exec 3>&1
  15. # store data hostname
  16. FULLFQDN=$(dialog --ok-label "Submit" \
  17. --backtitle "PixelFed installer Script" \
  18. --title "Install Dialog 1/4" \
  19. --form "We need some informations before we can start -\nNow we need to set a Hostname for this machine - this is where you will reach your PixelFed installation (e.g pixelfed.xyz or pixelfed.yourname.com).\nThis is also used for domain validation with Lets Encrypt." \
  20. 15 100 0 \
  21. "New Hostname: " 1 1 "$FULLFQDN" 1 15 55 0 \
  22. 2>&1 1>&3)
  23. # close fd
  24. exec 3>&-
  25. # open fd
  26. exec 3>&1
  27. # store data instance_name
  28. instance_name=$(dialog --ok-label "Submit" \
  29. --backtitle "PixelFed installer Script" \
  30. --title "Install Dialog 2/4" \
  31. --form "We need some informations before we can start -\nNow we need to set a name for your Pixelfed instance - e.g. BestPixelfedInstance." \
  32. 15 100 0 \
  33. "Instance Name: " 1 1 "$instance_name" 1 15 55 0 \
  34. 2>&1 1>&3)
  35. # close fd
  36. exec 3>&-
  37. # open fd
  38. exec 3>&1
  39. # store data admin_user
  40. admin_user=$(dialog --ok-label "Submit" \
  41. --backtitle "PixelFed installer Script" \
  42. --title "Install Dialog 3/4" \
  43. --form "We need some informations before we can start -\nNow we need the name for your admin user - e.g. admin or your name.\nA secure password will be generated and stored with other credentials in your root directory." \
  44. 15 100 0 \
  45. "Admin User: " 1 1 "$admin_user" 1 15 55 0 \
  46. 2>&1 1>&3)
  47. # close fd
  48. exec 3>&-
  49. # open fd
  50. exec 3>&1
  51. # store data admin_mail
  52. admin_mail=$(dialog --ok-label "Submit" \
  53. --backtitle "PixelFed installer Script" \
  54. --title "Install Dialog 4/4" \
  55. --form "We need some informations before we can start -\nNow we need your E-Mail address - e.g. you@example.com.\nYou will need this address to log in to your Pixelfed instance." \
  56. 15 100 0 \
  57. "Admin E-Mail address: " 1 1 "$admin_mail" 1 15 55 0 \
  58. 2>&1 1>&3)
  59. # close fd
  60. exec 3>&-
  61. # less questions
  62. export DEBIAN_FRONTEND="noninteractive"
  63. # set hostname
  64. hostnamectl set-hostname $FULLFQDN
  65. # build mysql passwords and write a password file
  66. mysql_root_pass=$(cat /dev/urandom | head -c 32 | base64 | cut -c -32)
  67. mysql_user_pass=$(cat /dev/urandom | head -c 32 | base64 | cut -c -32)
  68. echo "Mysql Root Password: $mysql_root_pass" > passwords.txt
  69. echo "Mysql User: pixelfed" >> passwords.txt
  70. echo "Mysql Password: $mysql_user_pass" >> passwords.txt
  71. # add repos for current software
  72. ## nodejs for SVGO
  73. curl -sL https://deb.nodesource.com/setup_10.x | bash -
  74. ## add nginx mainline repo
  75. wget -q -O- https://nginx.org/keys/nginx_signing.key | apt-key add -
  76. cat <<EOF> /etc/apt/sources.list.d/nginx-mainline.list
  77. deb http://nginx.org/packages/mainline/debian/ stretch nginx
  78. deb-src http://nginx.org/packages/mainline/debian/ stretch nginx
  79. EOF
  80. ## add mysql 5.7 repo - we do it the oracle way (of course it's different)
  81. debconf-set-selections <<< "mysql-apt-config mysql-apt-config/select-server select mysql-5.7"
  82. debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass $mysql_root_pass"
  83. debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass $mysql_root_pass"
  84. wget https://dev.mysql.com/get/mysql-apt-config_0.8.11-1_all.deb
  85. dpkg -i mysql-apt-config_0.8.11-1_all.deb
  86. ## add php 7.2 repo
  87. wget -q -O- https://packages.sury.org/php/apt.gpg | apt-key add -
  88. echo "deb https://packages.sury.org/php/ stretch main" | tee /etc/apt/sources.list.d/php.list
  89. apt update
  90. # installations
  91. ## install fail2ban
  92. apt -y install fail2ban
  93. ## nodejs and SVGO
  94. apt -y install nodejs
  95. npm install -g svgo
  96. ## install & configure UFW to allow only ssh and http/s
  97. apt -y install ufw
  98. ufw default deny incoming
  99. ufw default allow outgoing
  100. ufw allow 22/tcp
  101. ufw allow 80/tcp
  102. ufw allow 443/tcp
  103. ## enable UFW
  104. ufw --force enable
  105. ## install redis server
  106. apt -y install redis-server
  107. ## install & configure nginx
  108. apt -y install nginx
  109. systemctl start nginx
  110. mkdir /etc/nginx/ssl
  111. # generate secure dh parameters - higher values -> more security
  112. #openssl dhparam -out /etc/nginx/ssl/dhparam.pem 1024
  113. #openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
  114. openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
  115. ### build nginx config
  116. mkdir /etc/nginx/sites-available
  117. mkdir /etc/nginx/sites-enabled
  118. sed 's/user nginx/user www-data/g' /etc/nginx/nginx.conf -i
  119. sed 's/worker_processes 1/worker_processes auto/g' /etc/nginx/nginx.conf -i
  120. sed '/http {/a \ server_tokens off;' /etc/nginx/nginx.conf -i
  121. sed 's/#gzip on/gzip on/g' /etc/nginx/nginx.conf -i
  122. sed '/conf.d/a \ include /etc/nginx/sites-enabled/*.conf;' /etc/nginx/nginx.conf -i
  123. ### create PixelFed host file for nginx
  124. cat <<EOF > $FULLFQDN.conf
  125. server {
  126. listen 80;
  127. listen [::]:80;
  128. server_name $FULLFQDN;
  129. location /.well-known {
  130. root /usr/share/nginx/html;
  131. }
  132. return 301 https://\$host\$request_uri;
  133. }
  134. server {
  135. listen 443 http2 ssl;
  136. listen [::]:443 http2;
  137. server_name $FULLFQDN;
  138. root /var/www/pixelfed/public;
  139. index index.html index.htm index.php;
  140. access_log /var/log/nginx/access.log;
  141. client_max_body_size 20M;
  142. add_header X-Content-Type-Options nosniff;
  143. add_header X-XSS-Protection "1; mode=block";
  144. add_header X-Robots-Tag none;
  145. add_header X-Download-Options noopen;
  146. add_header X-Permitted-Cross-Domain-Policies none;
  147. ssl_certificate /etc/letsencrypt/live/$FULLFQDN/fullchain.pem;
  148. ssl_certificate_key /etc/letsencrypt/live/$FULLFQDN/privkey.pem;
  149. ssl_dhparam /etc/nginx/ssl/dhparam.pem;
  150. ssl_session_timeout 5m;
  151. ssl_protocols TLSv1.2 TLSv1.3;
  152. ssl_prefer_server_ciphers on;
  153. ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
  154. ssl_ecdh_curve secp384r1;
  155. ssl_session_cache shared:SSL:10m;
  156. add_header Strict-Transport-Security max-age=15768000;
  157. location /.well-known {
  158. root /usr/share/nginx/html;
  159. }
  160. location / {
  161. try_files \$uri \$uri/ /\$is_args\$args;
  162. }
  163. location ~ \.php$ {
  164. try_files \$uri /index.php =404;
  165. fastcgi_split_path_info ^(.+\.php)(/.+)$;
  166. fastcgi_pass unix:/run/php/php7.2-fpm.sock;
  167. fastcgi_index index.php;
  168. fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
  169. include fastcgi_params;
  170. fastcgi_param PATH_INFO \$fastcgi_path_info;
  171. }
  172. }
  173. EOF
  174. mv $FULLFQDN.conf /etc/nginx/sites-available/
  175. ### enable config in nginx
  176. ln -s /etc/nginx/sites-available/$FULLFQDN.conf /etc/nginx/sites-enabled/$FULLFQDN.conf
  177. ## install and configure letsencrypt & certbot
  178. apt -y install certbot
  179. if [ "$(certbot certonly --webroot --agree-tos -m webmaster@$FULLFQDN -d $FULLFQDN -w /usr/share/nginx/html | grep -c "Congratulations!")" == "1" ]
  180. then
  181. echo "Let's Encrypt installation okay"
  182. else
  183. echo "Something went wrong while I tried to set up Let's Encrypt. Check your DNS settings."
  184. exit 1
  185. fi
  186. ## restart nginx
  187. systemctl restart nginx
  188. ## install mysql
  189. apt -y install mysql-server
  190. ### create pixelfed user in mysql database
  191. mysql -uroot -e "CREATE DATABASE pixelfed;"
  192. mysql -uroot -e "CREATE USER pixelfed@localhost IDENTIFIED BY '${mysql_user_pass}';"
  193. mysql -uroot -e "GRANT ALL PRIVILEGES ON pixelfed.* TO 'pixelfed'@'localhost';"
  194. mysql -uroot -e "FLUSH PRIVILEGES;"
  195. ## install php & php-fpm
  196. apt -y install php7.2 php7.2-fpm php7.2-cli php7.2-json php7.2-mbstring php7.2-bcmath php7.2-zip php7.2-mysql php7.2-xml php-mcrypt libfreetype6 libjpeg62-turbo libpng16-16 libxpm4 libvpx4 libmagickwand-6.q16-3 optipng pngquant jpegoptim gifsicle imagemagick php7.2-gd php-imagick php-bcmath
  197. #### configure php-fpm
  198. sed 's/pm.max_children = 5/pm.max_children = 25/g' /etc/php/7.2/fpm/pool.d/www.conf -i
  199. sed 's/;pm.max_requests/pm.max_requests/g' /etc/php/7.2/fpm/pool.d/www.conf -i
  200. ### set php upload size
  201. sed 's/upload_max_filesize = 2M/upload_max_filesize = 20M/g' /etc/php/7.2/fpm/php.ini -i
  202. sed 's/post_max_size = 8M/post_max_size = 20M/g' /etc/php/7.2/fpm/php.ini -i
  203. #set php max_execution_time
  204. sed 's|max_execution_time =.*|max_execution_time = 600|g' /etc/php/7.2/fpm/php.ini -i
  205. systemctl restart php7.2-fpm.service
  206. ## install composer
  207. curl -sS https://getcomposer.org/installer | php
  208. mv composer.phar /usr/local/bin/composer
  209. chmod +x /usr/local/bin/composer
  210. ## get pixelfed & set up
  211. git clone https://github.com/pixelfed/pixelfed.git /var/www/pixelfed
  212. cd /var/www/pixelfed
  213. composer install --no-plugins --no-scripts
  214. ### build .env file
  215. cat <<EOF > .env
  216. #
  217. # This is your central config file.
  218. # Press F2 to safe and exit after your edits.
  219. #
  220. # SMTP server setting
  221. MAIL_HOST=smtp.mailtrap.io
  222. MAIL_PORT=2525
  223. MAIL_USERNAME=null
  224. MAIL_PASSWORD=null
  225. MAIL_ENCRYPTION=null
  226. MAIL_FROM_ADDRESS="pixelfed@example.com"
  227. MAIL_FROM_NAME="Pixelfed"
  228. # open registration for new users? Set to true or false
  229. OPEN_REGISTRATION=true
  230. # Enable E-Mail verification when register new account? Set to true or false
  231. ENFORCE_EMAIL_VERIFICATION=true
  232. # use recaptcha? Set to true or false
  233. RECAPTCHA_ENABLED=false
  234. ##### DO NOT EDIT BEHIND THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING #####
  235. APP_KEY=
  236. APP_DEBUG=false
  237. APP_ENV=local
  238. APP_NAME="$instance_name"
  239. ADMIN_DOMAIN="$FULLFQDN"
  240. APP_DOMAIN="$FULLFQDN"
  241. LOG_CHANNEL=stack
  242. APP_URL=https://$FULLFQDN
  243. DB_CONNECTION=mysql
  244. DB_HOST=127.0.0.1
  245. DB_PORT=3306
  246. DB_DATABASE=pixelfed
  247. DB_USERNAME=pixelfed
  248. DB_PASSWORD=$mysql_user_pass
  249. MAIL_DRIVER=log
  250. BROADCAST_DRIVER=log
  251. CACHE_DRIVER=redis
  252. SESSION_DRIVER=redis
  253. SESSION_LIFETIME=120
  254. QUEUE_DRIVER=redis
  255. REDIS_HOST=127.0.0.1
  256. REDIS_PASSWORD=null
  257. REDIS_PORT=6379
  258. SESSION_DOMAIN="\${APP_DOMAIN}"
  259. SESSION_SECURE_COOKIE=true
  260. API_BASE="/api/1/"
  261. API_SEARCH="/api/search"
  262. MAX_PHOTO_SIZE=15000
  263. MAX_CAPTION_LENGTH=150
  264. MAX_ALBUM_LENGTH=4
  265. MIX_PUSHER_APP_KEY="\${PUSHER_APP_KEY}"
  266. MIX_PUSHER_APP_CLUSTER="\${PUSHER_APP_CLUSTER}"
  267. MIX_APP_URL="\${APP_URL}"
  268. MIX_API_BASE="\${API_BASE}"
  269. MIX_API_SEARCH="\${API_SEARCH}"
  270. REMOTE_FOLLOW=false
  271. ACTIVITY_PUB=false
  272. EOF
  273. ## let user edit the config
  274. nano .env
  275. ## set up laravel things
  276. php artisan key:generate
  277. php artisan storage:link
  278. php artisan migrate --force
  279. sed 's/APP_ENV=local/APP_ENV=production/g' .env -i
  280. php artisan config:cache
  281. ## install supervisor to provide horizon deamon
  282. apt -y install supervisor
  283. systemctl enable supervisor
  284. ## write horizon config
  285. cat <<EOF > /etc/supervisor/conf.d/horizon.conf
  286. [program:horizon]
  287. process_name=%(program_name)s
  288. command=php /var/www/pixelfed/artisan horizon
  289. autostart=true
  290. autorestart=true
  291. user=www-data
  292. redirect_stderr=true
  293. stdout_logfile=/var/www/pixelfed/horizon.log
  294. EOF
  295. # configure supervisor & start horizon
  296. supervisorctl reread
  297. supervisorctl update
  298. supervisorctl start horizon
  299. chown -R www-data:www-data /var/www/pixelfed
  300. # build admin user
  301. apt -y install apache2-utils
  302. ## generate admin password
  303. admin_pass=$(cat /dev/urandom | head -c 32 | base64 | cut -c -32)
  304. echo "Pixelfed admin user: $admin_user" >> /root/passwords.txt
  305. echo "Admin E-Mail Address: $admin_mail" >> /root/passwords.txt
  306. echo "Pixelfed admin password: $admin_pass" >> /root/passwords.txt
  307. ### hash admin password for database
  308. hashed_admin_pass=$(htpasswd -bnBC 10 "" $admin_pass | tr -d ':\n')
  309. ### we have to generate a openssl keypair for the admin user
  310. ssh-keygen -b 2048 -t rsa -f sshkey -q -N ""
  311. private_key=`cat sshkey`
  312. public_key=`cat sshkey.pub`
  313. ### insert new user into 'users' database
  314. mysql -uroot pixelfed -e "INSERT INTO users (\`id\`, \`name\`, \`username\`, \`email\`, \`password\`, \`remember_token\`, \`is_admin\`, \`email_verified_at\`, \`created_at\`, \`updated_at\`, \`deleted_at\`, \`2fa_enabled\`, \`2fa_secret\`, \`2fa_backup_codes\`, \`2fa_setup_at\`) VALUES (1, '${admin_user}', '${admin_user}', '${admin_mail}', '${hashed_admin_pass}', NULL, '1', NULL, NOW(), NOW(), NULL, '0', NULL, NULL, NULL);"
  315. ### insert new user into 'profiles' database
  316. mysql -uroot pixelfed -e "INSERT INTO \`profiles\` (\`id\`, \`user_id\`, \`domain\`, \`username\`, \`name\`, \`bio\`, \`location\`, \`website\`, \`keybase_proof\`, \`is_private\`, \`sharedInbox\`, \`inbox_url\`, \`outbox_url\`, \`key_id\`, \`follower_url\`, \`following_url\`, \`verify_token\`, \`secret\`, \`private_key\`, \`public_key\`, \`remote_url\`, \`salmon_url\`, \`hub_url\`, \`created_at\`, \`updated_at\`, \`deleted_at\`) VALUES ('1', '1', NULL, '$admin_user', '$admin_user', NULL, NULL, NULL, NULL, '0', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '$private_key', '$public_key', NULL, NULL, NULL, NOW(), NOW(), NULL);"
  317. # clean up
  318. cd /root
  319. apt -y purge apache2-utils dialog
  320. apt -y autoremove
  321. rm mysql-apt-config_0.8.11-1_all.deb
  322. rm sshkey
  323. rm sshkey.pub
  324. echo ""
  325. echo ""
  326. echo "PixelFed ist installed, go to https://$FULLFQDN and log in."
  327. echo "Your log in email is: $admin_mail"
  328. echo "Your password is: $admin_pass"
  329. echo "All passwords are safed in passwords.txt file in your root directory."
  330. echo ""