#!/bin/bash # Copyright 2023 aqz/tamaina, joinmisskey # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice # shall be included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # version="3.2.3"; NODE_MAJOR="22"; tput setaf 4; echo ""; echo "Misskey auto setup for Ubuntu"; echo " v$version"; echo ""; #region initial check tput setaf 2; echo "Check: Linux;" if [ "$(command -v uname)" ]; then if [ "$(uname -s)" == "Linux" ]; then tput setaf 7; echo " OK."; if ! [ -f "/etc/lsb-release" ]; then echo " Warning: This script has been tested on Ubuntu and may not work on other distributions."; fi else tput setaf 1; echo " NG."; exit 1; fi else tput setaf 1; echo " NG."; exit 1; fi tput setaf 2; echo "Check: root user;"; if [ "$(whoami)" != 'root' ]; then tput setaf 1; echo " NG. This script must be run as root."; exit 1; else tput setaf 7; echo " OK. I am root user."; fi tput setaf 2; echo "Check: arch;"; case $(uname -m) in x86_64) tput setaf 7; echo " x86_64 (amd64)"; arch=amd64; ;; aarch64) tput setaf 7; echo " aarch64 (arm64)"; arch=arm64; ;; *) tput setaf 1; echo " NG. $(uname -m) is unsupported architecture."; exit 1; ;; esac #endregion #region user input #region method tput setaf 3; echo ""; echo "Install Method"; tput setaf 7; echo "Do you use systemd to run Misskey?:"; echo "Y = To use systemd / n = To use docker" read -r -p "[Y/n] > " yn case "$yn" in [Nn]|[Nn][Oo]) echo "Use Docker."; method=docker; echo "Determine the local IP of this computer as docker host."; echo "The IPs that are supposed to be available are as follows (the result of hostname -I)"; echo " $(hostname -I)" read -r -p "> " -e -i "$(hostname -I | cut -f1 -d' ')" docker_host_ip; echo "The host name of docker host to bind with 'docker run --add-host='."; read -r -p "> " -e -i "docker_host" misskey_localhost; ;; *) echo "Use Systemd."; method=systemd; misskey_localhost=localhost ;; esac #endregion if [ $method == "docker" ]; then echo "Do you use image from Docker Hub?:"; echo "Y = To use Docker Hub image / N = To build Docker image in this machine" read -r -p "[Y/n] > " yn case "$yn" in [Nn]|[Nn][Oo]) echo "Build docker image (local/misskey:latest)."; method=docker; docker_repository="local/misskey:latest" ;; *) echo "Use Docker Hub image."; method=docker_hub; echo "Enter repository:tag of Docker Hub image:" read -r -p "> " -e -i "misskey/misskey:latest" docker_repository; ;; esac fi tput setaf 3; echo "Misskey setting"; tput setaf 7; misskey_directory=misskey if [ $method != "docker_hub" ]; then echo "Repository url where you want to install:" read -r -p "> " -e -i "https://github.com/misskey-dev/misskey.git" repository; echo "The name of a new directory to clone:" read -r -p "> " -e -i "misskey" misskey_directory; echo "Branch or Tag" read -r -p "> " -e -i "master" branch; fi tput setaf 3; echo ""; echo "Enter the name of user with which you want to execute Misskey:"; tput setaf 7; read -r -p "> " -e -i "misskey" misskey_user; tput setaf 3; echo ""; echo "Enter host where you want to install Misskey:"; tput setaf 7; read -r -p "> " -e -i "example.com" host; tput setaf 7; hostarr=(${host//./ }); echo "OK, let's install $host!"; #region nginx tput setaf 3; echo ""; echo "Nginx setting"; tput setaf 7; echo "Do you want to setup nginx?:"; read -r -p "[Y/n] > " yn case "$yn" in [Nn]|[Nn][Oo]) echo "Nginx and Let's encrypt certificate will not be installed."; echo "You should open ports manually."; nginx_local=false; cloudflare=false; certbot=false; echo "Misskey port: "; read -r -p "> " -e -i "3000" misskey_port; ;; *) echo "Nginx will be installed on this computer."; echo "Port 80 and 443 will be opened by modifying iptables."; nginx_local=true; tput setaf 3; echo ""; tput setaf 7; echo "Do you want it to open ports, to setup ufw or iptables?:"; echo "u = To setup ufw / i = To setup iptables / N = Not to open ports"; read -r -p "[u/i/N] > " yn2 case "$yn2" in [Uu]) echo "OK, it will use ufw."; ufw=true iptables=false echo "SSH port: "; read -r -p "> " -e -i "22" ssh_port; ;; [Ii]) echo "OK, it will use iptables."; ufw=false iptables=true echo "SSH port: "; read -r -p "> " -e -i "22" ssh_port; ;; *) echo "OK, you should open ports manually."; ufw=false iptables=false ;; esac #region certbot tput setaf 3; echo ""; echo "Certbot setting"; tput setaf 7; echo "Do you want it to setup certbot to connect with https?:"; read -r -p "[Y/n] > " yn2 case "$yn2" in [Nn]|[Nn][Oo]) certbot=false echo "OK, you don't setup certbot."; ;; *) certbot=true echo "OK, you want to setup certbot."; #endregion ;; esac #region cloudflare tput setaf 3; echo ""; echo "Cloudflare setting"; tput setaf 7; echo "Do you use Cloudflare?:"; read -r -p "[Y/n] > " yn2 case "$yn2" in [Nn]|[Nn][Oo]) echo "OK, you don't use Cloudflare."; echo "Let's encrypt certificate will be installed using the method without Cloudflare."; echo ""; echo "Make sure that your DNS is configured to this machine."; cloudflare=false if $certbot; then echo ""; echo "Enter Email address to register Let's Encrypt certificate"; read -r -p "> " cf_mail; fi ;; *) cloudflare=true echo "OK, you want to use Cloudflare. Let's set up Cloudflare."; echo ""; echo "Make sure that Cloudflare DNS is configured and is in proxy mode."; echo ""; echo "Enter Email address you registered to Cloudflare:"; read -r -p "> " cf_mail; echo "Open https://dash.cloudflare.com/profile/api-tokens to get Global API Key and enter here it."; echo "Cloudflare API Key: "; read -r -p "> " cf_key; mkdir -p /etc/cloudflare; cat > /etc/cloudflare/cloudflare.ini <<-_EOF dns_cloudflare_email = $cf_mail dns_cloudflare_api_key = $cf_key _EOF chmod 600 /etc/cloudflare/cloudflare.ini; #endregion ;; esac echo "Tell me which port Misskey will watch: "; echo "Misskey port: "; read -r -p "> " -e -i "3000" misskey_port; ;; esac #endregion #region postgres tput setaf 3; echo ""; echo "Database (PostgreSQL) setting"; tput setaf 7; echo "Do you want to install postgres locally?:"; echo "(If you have run this script before in this computer, choose n and enter values you have set.)" read -r -p "[Y/n] > " yn case "$yn" in [Nn]|[Nn][Oo]) echo "You should prepare postgres manually until database is created."; db_local=false; echo "Database host: "; read -r -p "> " -e -i "$misskey_localhost" db_host; echo "Database port:"; read -r -p "> " -e -i "5432" db_port; ;; *) echo "PostgreSQL will be installed on this computer at $misskey_localhost:5432."; db_local=true; db_host=$misskey_localhost; db_port=5432; ;; esac echo "Database user name: "; read -r -p "> " -e -i "misskey" db_user; echo "Database user password: "; read -r -p "> " db_pass; echo "Database name:"; read -r -p "> " -e -i "mk1" db_name; #endregion #region redis tput setaf 3; echo ""; echo "Redis setting"; tput setaf 7; echo "Do you want to install redis locally?:"; echo "(If you have run this script before in this computer, choose n and enter values you have set.)" read -r -p "[Y/n] > " yn case "$yn" in [Nn]|[Nn][Oo]) echo "You should prepare Redis manually."; redis_local=false; echo "Redis host:"; read -r -p "> " -e -i "$misskey_localhost" redis_host; echo "Redis port:"; read -r -p "> " -e -i "6379" redis_port; ;; *) echo "Redis will be installed on this computer at $misskey_localhost:6379."; redis_local=true; redis_host=$misskey_localhost; redis_port=6379; ;; esac echo "Redis password:"; read -r -p "> " redis_pass; #endregion tput setaf 7; echo ""; echo "OK. It will automatically install what you need. This will take some time."; echo ""; #endregion set -eu; tput setaf 2; echo "Check: Memory;" mem_all=$(free -t --si -g | tail -n 1); mem_allarr=(${mem_all//\\t/ }); if [ "${mem_allarr[1]}" -ge 3 ]; then tput setaf 7; echo " OK. This computer has ${mem_allarr[1]}GB RAM."; else tput setaf 1; echo " NG. This computer doesn't have enough RAM (>= 2GB, Current ${mem_allarr[1]}GB)."; tput setaf 7; mem_swap=$(free | tail -n 1); mem_swaparr=(${mem_swap//\\t/ }); if [ "${mem_swaparr[1]}" -eq 0 ]; then if [ "${mem_allarr[1]}" -ge 2 ]; then echo " Swap will be made (1M x 1024)."; dd if=/dev/zero of=/swap bs=1M count=1024; else echo " Swap will be made (1M x 2048)."; dd if=/dev/zero of=/swap bs=1M count=2048; fi mkswap /swap; swapon /swap; echo "/swap none swap sw 0" >> /etc/fstab; free -t; else echo " Add more swaps!"; exit 1; fi fi tput setaf 3; echo "Process: mkdir -p /usr/share/keyrings;"; tput setaf 7; sudo mkdir -p /usr/share/keyrings; tput setaf 3; echo "Process: add misskey user ($misskey_user);"; tput setaf 7; if cut -d: -f1 /etc/passwd | grep -q -x "$misskey_user"; then echo "$misskey_user exists already. No user will be created."; else useradd -m -U -s /bin/bash "$misskey_user"; fi echo "misskey_user=\"$misskey_user\"" > /root/.misskey.env echo "version=\"$version\"" >> /root/.misskey.env m_uid=$(id -u "$misskey_user") tput setaf 3; echo "Process: apt install #1;"; tput setaf 7; apt -qq update -y; apt -qq install -y curl nano jq gnupg2 apt-transport-https ca-certificates lsb-release software-properties-common uidmap$($nginx_local && echo " certbot")$($nginx_local && ($ufw && echo " ufw" || $iptables && echo " iptables-persistent"))$($cloudflare && echo " python3-certbot-dns-cloudflare")$([ $method != "docker_hub" ] && echo " git")$([ $method == "systemd" ] && echo " ffmpeg build-essential"); if [ $method != "docker_hub" ]; then #region work with misskey user su "$misskey_user" << MKEOF set -eu; cd ~; tput setaf 3; echo "Process: git clone;"; tput setaf 7; if [ -e "./$misskey_directory" ]; then if [ -f "./$misskey_directory" ]; then rm "./$misskey_directory"; else rm -rf "./$misskey_directory"; fi fi git clone -b "$branch" --depth 1 --recursive "$repository" "$misskey_directory"; MKEOF #endregion else #region work with misskey user su "$misskey_user" << MKEOF set -eu; cd ~; if [ -e "./$misskey_directory" ]; then if [ -f "./$misskey_directory" ]; then rm "./$misskey_directory"; fi else mkdir "./$misskey_directory" fi if [ -e "./$misskey_directory/.config" ]; then if [ -f "./$misskey_directory/.config" ]; then rm "./$misskey_directory/.config"; fi else mkdir "./$misskey_directory/.config" fi MKEOF #endregion fi tput setaf 3; echo "Process: write default.yml;"; tput setaf 7; #region work with misskey user su "$misskey_user" << MKEOF set -eu; cd ~; tput setaf 3; echo "Process: create default.yml;" tput setaf 7; cat > "$misskey_directory/.config/default.yml" << _EOF url: https://$host port: $misskey_port # PostgreSQL db: host: '$db_host' port: $db_port db : '$db_name' user: '$db_user' pass: '$db_pass' # Redis redis: host: '$redis_host' port: $redis_port pass: '$redis_pass' # ID type id: 'aid' # Proxy remote files (default: true) # Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains. proxyRemoteFiles: true # Sign to ActivityPub GET request (default: true) signToActivityPubGet: true proxyBypassHosts: - api.deepl.com - api-free.deepl.com - www.recaptcha.net - hcaptcha.com - challenges.cloudflare.com - summaly.arkjp.net _EOF MKEOF #endregion if $nginx_local; then if $ufw; then tput setaf 3; echo "Process: port open by ufw;" tput setaf 7; ufw limit $ssh_port/tcp; ufw default deny; ufw allow 80; ufw allow 443; ufw --force enable; ufw status; elif $iptables; then tput setaf 3; echo "Process: port open by iptables;" tput setaf 7; grep -q -x -e "-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT" /etc/iptables/rules.v4 || iptables -I INPUT -p tcp --dport 80 -j ACCEPT; grep -q -x -e "-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT" /etc/iptables/rules.v4 || iptables -I INPUT -p tcp --dport 443 -j ACCEPT; grep -q -x -e "-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT" /etc/iptables/rules.v6 || ip6tables -I INPUT -p tcp --dport 80 -j ACCEPT; grep -q -x -e "-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT" /etc/iptables/rules.v6 || ip6tables -I INPUT -p tcp --dport 443 -j ACCEPT; netfilter-persistent save; netfilter-persistent reload; fi tput setaf 3; echo "Process: prepare nginx;" tput setaf 7; curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null; tput setaf 2; echo "Check: nginx gpg key;"; tput setaf 7; if gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg | grep -q 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; then echo " OK."; else tput setaf 1; echo " NG."; exit 1; fi echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list; echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx; fi if [ $method == "systemd" ]; then tput setaf 3; echo "Process: prepare node.js;" tput setaf 7; curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg; echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list; else tput setaf 3; echo "Process: prepare docker;" tput setaf 7; if ! [ -e /usr/share/keyrings/docker-archive-keyring.gpg ]; then curl -sL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg fi echo "deb [arch=$arch signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null fi if $redis_local; then tput setaf 3; echo "Process: prepare redis;" tput setaf 7; curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg; echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list; fi tput setaf 3; echo "Process: apt install #2;" tput setaf 7; apt -qq update -y; apt -qq install -y$([ $method == "systemd" ] && echo " nodejs libjemalloc-dev" || echo " docker-ce docker-ce-cli containerd.io")$($redis_local && echo " redis")$($nginx_local && echo " nginx"); if [ $method == "systemd" ]; then tput setaf 3; echo "Process: corepack enable;" tput setaf 7; corepack enable; fi echo "Display: Versions;" if [ $method == "systemd" ]; then echo "node"; node -v; echo "corepack"; corepack -v; else echo "docker"; docker --version; fi if $redis_local; then echo "redis"; redis-server --version; fi if $nginx_local; then echo "nginx"; nginx -v; fi if $redis_local; then tput setaf 3; echo "Process: daemon activate: redis;" tput setaf 7; systemctl start redis-server; systemctl enable redis-server; fi #region nginx_setup if $nginx_local; then tput setaf 3; echo "Process: create nginx config;" tput setaf 7; cat > "/etc/nginx/conf.d/$host.conf" << NGEOF # nginx configuration for Misskey # Created by joinmisskey/bash-install v$version # For WebSocket map \$http_upgrade \$connection_upgrade { default upgrade; '' close; } proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off; server { listen 80; listen [::]:80; server_name $host; # For SSL domain validation root /var/www/html; location /.well-known/acme-challenge/ { allow all; } location /.well-known/pki-validation/ { allow all; } NGEOF #region certbot_setup if $certbot; then tput setaf 3; echo "Process: add nginx config (certbot-1);" tput setaf 7; cat >> "/etc/nginx/conf.d/$host.conf" << NGEOF # with https location / { return 301 https://\$server_name\$request_uri; } } NGEOF tput setaf 3; echo "Process: prepare certificate;" tput setaf 7; nginx -t; systemctl restart nginx; if $cloudflare; then certbot certonly -t -n --agree-tos --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare/cloudflare.ini --dns-cloudflare-propagation-seconds 60 --server https://acme-v02.api.letsencrypt.org/directory $([ ${#hostarr[*]} -eq 2 ] && echo " -d $host -d *.$host" || echo " -d $host") -m "$cf_mail"; else mkdir -p /var/www/html; certbot certonly -t -n --agree-tos --webroot --webroot-path /var/www/html $([ ${#hostarr[*]} -eq 2 ] && echo " -d $host" || echo " -d $host") -m "$cf_mail"; fi tput setaf 3; echo "Process: add nginx config (certbot-2);" tput setaf 7; cat >> "/etc/nginx/conf.d/$host.conf" << NGEOF server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name $host; ssl_session_timeout 1d; ssl_session_cache shared:ssl_session_cache:10m; ssl_session_tickets off; # To use Let's Encrypt certificate ssl_certificate /etc/letsencrypt/live/$host/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$host/privkey.pem; # SSL protocol settings ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_stapling on; ssl_stapling_verify on; NGEOF fi #endregion tput setaf 3; echo "Process: add nginx config;" tput setaf 7; cat >> "/etc/nginx/conf.d/$host.conf" << NGEOF # Change to your upload limit client_max_body_size 250m; # Proxy to Node location / { proxy_pass http://127.0.0.1:$misskey_port; proxy_set_header Host \$host; proxy_http_version 1.1; proxy_redirect off; $($cloudflare || echo " # If it's behind another reverse proxy or CDN, remove the following.") $($cloudflare || echo " proxy_set_header X-Real-IP \$remote_addr;") $($cloudflare || echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;") $($cloudflare || echo " proxy_set_header X-Forwarded-Proto https;") # For WebSocket proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection \$connection_upgrade; # Cache settings proxy_cache cache1; proxy_cache_lock on; proxy_cache_use_stale updating; proxy_force_ranges on; add_header X-Cache \$upstream_cache_status; } } NGEOF nginx -t; tput setaf 3; echo "Process: daemon activate: nginx;" tput setaf 7; systemctl restart nginx; systemctl enable nginx; tput setaf 2; echo "Check: localhost returns nginx;"; tput setaf 7; if curl http://localhost | grep -q nginx; then echo " OK."; else tput setaf 1; echo " NG."; exit 1; fi fi #endregion if $db_local; then tput setaf 3; echo "Process: install postgres;" tput setaf 7; apt -qq install -y postgresql-common; sh /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -i -v 15; tput setaf 3; echo "Process: create user and database on postgres;" tput setaf 7; sudo -iu postgres psql -c "CREATE ROLE $db_user LOGIN PASSWORD '$db_pass';" -c "CREATE DATABASE $db_name OWNER $db_user;" fi #region docker setting if [ $method != "systemd" ]; then #region enable rootless docker tput setaf 3; echo "Process: use rootless docker;" tput setaf 7; systemctl disable --now docker.service docker.socket loginctl enable-linger "$misskey_user" sleep 5 su "$misskey_user" <<-MKEOF set -eu; cd ~; export XDG_RUNTIME_DIR=/run/user/$m_uid; export DOCKER_HOST=unix:///run/user/$m_uid/docker.sock; systemctl --user --no-pager dockerd-rootless-setuptool.sh install tput setaf 2; echo "Check: docker setup;"; tput setaf 7; docker ps; MKEOF #endregion #region modify postgres confs if $db_local; then tput setaf 3; echo "Process: modify postgres confs;" tput setaf 7; pg_hba=$(sudo -iu postgres psql -t -P format=unaligned -c 'show hba_file') pg_conf=$(sudo -iu postgres psql -t -P format=unaligned -c 'show config_file') [[ $(ip addr | grep "$docker_host_ip") =~ /([0-9]+) ]] && subnet=${BASH_REMATCH[1]}; hba_text="host $db_name $db_user $docker_host_ip/$subnet md5" if ! grep "$hba_text" "$pg_hba"; then echo "$hba_text" >> "$pg_hba"; fi pgconf_search="#listen_addresses = 'localhost'" pgconf_text="listen_addresses = '$docker_host_ip'" if grep "$pgconf_search" "$pg_conf"; then sed -i'.mkmoded' -e "s/$pgconf_search/$pgconf_text/g" "$pg_conf"; elif grep "$pgconf_text" "$pg_conf"; then echo " skip" else echo "Please edit postgresql.conf to set [listen_addresses = '$docker_host_ip'] by your hand." read -r -p "Enter the editor command and press Enter key > " -e -i "nano" editorcmd $editorcmd "$pg_conf"; fi systemctl restart postgresql; fi #endregion fi #endregion #region modify redis conf if $redis_local; then tput setaf 3; echo "Process: modify redis confs;" tput setaf 7; if [ -f /etc/redis/redis.conf ]; then echo "requirepass $redis_pass" > /etc/redis/misskey.conf [ $method != "systemd" ] && echo "bind $docker_host_ip" >> /etc/redis/misskey.conf if ! grep "include /etc/redis/misskey.conf" /etc/redis/redis.conf; then echo "include /etc/redis/misskey.conf" >> /etc/redis/redis.conf; else echo " skip" fi else echo "Couldn't find /etc/redis/redis.conf." echo "Please modify redis config in another shell like following." echo "" echo "requirepass $redis_pass" [ $method != "systemd" ] && echo "bind $docker_host_ip" echo "" read -r -p "Press Enter key to continue> " fi systemctl restart redis-server; fi #endregion if [ $method == "systemd" ]; then #region systemd #region work with misskey user su "$misskey_user" << MKEOF; set -eu; cd ~ cd "$misskey_directory"; tput setaf 3; echo "Process: install npm packages;" tput setaf 7; NODE_ENV=production pnpm install --frozen-lockfile; tput setaf 3; echo "Process: build misskey;" tput setaf 7; NODE_OPTIONS=--max_old_space_size=3072 NODE_ENV=production pnpm run build; tput setaf 3; echo "Process: initialize database;" tput setaf 7; NODE_OPTIONS=--max_old_space_size=3072 pnpm run init; tput setaf 3; echo "Check: If Misskey starts correctly;" tput setaf 7; if NODE_ENV=production timeout 40 npm start 2> /dev/null | grep -q "Now listening on port"; then echo " OK."; else tput setaf 1; echo " NG."; fi MKEOF #endregion tput setaf 3; echo "Process: create misskey daemon;" tput setaf 7; cat > "/etc/systemd/system/$host.service" << _EOF [Unit] Description=Misskey daemon [Service] Type=simple User=$misskey_user ExecStart=$(command -v npm) start WorkingDirectory=/home/$misskey_user/$misskey_directory Environment="NODE_ENV=production" Environment="LD_PRELOAD=/usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2" TimeoutSec=60 StandardOutput=journal StandardError=journal SyslogIdentifier="$host" Restart=always [Install] WantedBy=multi-user.target _EOF systemctl daemon-reload; systemctl enable "$host"; systemctl start "$host"; systemctl status "$host" --no-pager; #endregion elif [ $method == "docker" ]; then #region docker build tput setaf 3; echo "Process: build docker image;" tput setaf 7; sudo -iu "$misskey_user" XDG_RUNTIME_DIR=/run/user/$m_uid DOCKER_HOST=unix:///run/user/$m_uid/docker.sock docker build -t $docker_repository "/home/$misskey_user/$misskey_directory"; #endregion fi echo ""; if [ $method != "systemd" ]; then tput setaf 2; tput bold; echo "ALL MISSKEY INSTALLATION PROCESSES ARE COMPLETE!"; echo "Now all we need to do is run docker run." tput setaf 7; echo "Watch the screen." echo "When it shows \"Now listening on port $misskey_port on https://$host\"," echo "press Ctrl+C to exit logs and jump to https://$host/ and continue setting up your instance."; echo "" echo "This script version is v$version."; echo "Please follow @joinmisskey@misskey.io to address bugs and updates."; echo "" read -r -p "Press Enter key to execute docker run> "; echo "" tput setaf 3; echo "Process: docker run;" tput setaf 7; docker_container=$(sudo -iu "$misskey_user" XDG_RUNTIME_DIR=/run/user/$m_uid DOCKER_HOST=unix:///run/user/$m_uid/docker.sock docker run -d -p $misskey_port:$misskey_port --add-host=$misskey_localhost:$docker_host_ip -v "/home/$misskey_user/$misskey_directory/files":/misskey/files -v "/home/$misskey_user/$misskey_directory/.config/default.yml":/misskey/.config/default.yml:ro --restart unless-stopped -t "$docker_repository"); echo "$docker_container"; su "$misskey_user" << MKEOF set -eu; cd ~; tput setaf 3; echo "Process: create .misskey-docker.env;" tput setaf 7; cat > ".misskey-docker.env" << _EOF method="$method" host="$host" misskey_port=$misskey_port misskey_directory="$misskey_directory" misskey_localhost="$misskey_localhost" docker_host_ip=$docker_host_ip docker_repository="$docker_repository" docker_container="$docker_container" version="$version" _EOF MKEOF sudo -iu "$misskey_user" XDG_RUNTIME_DIR=/run/user/$m_uid DOCKER_HOST=unix:///run/user/$m_uid/docker.sock docker logs -f $docker_container; else su "$misskey_user" << MKEOF set -eu; cd ~; tput setaf 3; echo "Process: create .misskey.env;" tput setaf 7; cat > ".misskey.env" << _EOF host="$host" misskey_port=$misskey_port misskey_directory="$misskey_directory" misskey_localhost="$misskey_localhost" version="$version" _EOF MKEOF tput setaf 2; tput bold; echo "ALL MISSKEY INSTALLATION PROCESSES ARE COMPLETE!"; echo "Jump to https://$host/ and continue setting up your instance."; tput setaf 7; echo "This script version is v$version."; echo "Please follow @joinmisskey@misskey.io to address bugs and updates."; fi