Skip to content

Instantly share code, notes, and snippets.

@killerbees19
Last active December 11, 2025 02:13
Show Gist options
  • Select an option

  • Save killerbees19/9b0fb9358b1570d7ef17684aa7754259 to your computer and use it in GitHub Desktop.

Select an option

Save killerbees19/9b0fb9358b1570d7ef17684aa7754259 to your computer and use it in GitHub Desktop.
Mastodon @ Debian (with OpenSearch & LibreTranslate)

LAN TEST INSTALLATION (NOT FOR PRODUCTION!)

  • CPU: 2 vCores
  • RAM: 4 GiB (+ 1 GiB Swap)
  • HDD/SSD: minimum 40 GiB (recommended 80 GiB)

https://docs.joinmastodon.org/admin/install/ (Git Log & Wayback Machine)

See file Update.md for upgrade notes!

Mastodon 3.5.x (Debian 11)

Caution

EOL warning: This version is end of life and not supported anymore. Scroll down for newer instructions.

TODO (extract from old commits!)

Mastodon 3.5.x (Debian 12)

Caution

EOL warning: This version is end of life and not supported anymore. Scroll down for newer instructions.

TODO (extract from old commits!)

Mastodon 4.1.x (Debian 12)

Caution

EOL warning: This version is end of life and not supported anymore. Scroll down for newer instructions.

  • Re-tested at 2025-04-06
  • Debian Bookworm (12.10.0; amd64)
  • rbenv: Commit cd29bcc6e0ef8b04ff0abbc8d27ccf48a720f4f2
  • ruby-build: Commit bc1a47dac2a611a276ec705923bd16e0385e8f28
  • bundler: Version 2.5.23
  • mastodon: Tag v4.1.25
# ln -s /usr/bin/yarnpkg /usr/local/bin/yarn
# apt install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev \
              git g++ libprotobuf-dev protobuf-compiler pkg-config \
              nodejs gcc autoconf bison build-essential libssl-dev \
              libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev \
              libffi-dev libgdbm-dev nginx redis-server redis-tools \
              postgresql postgresql-contrib libidn11-dev libicu-dev \
              libjemalloc-dev yarnpkg curl gnupg postfix bsd-mailx

# su -c psql postgres
> CREATE USER mastodon CREATEDB;
> \q

# useradd -m -s /bin/bash -u 7007 -U mastodon
# su -l mastodon
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec bash
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.6
$ rbenv global 3.0.6
$ gem install bundler --no-document
$ git clone https://github.com/mastodon/mastodon.git ~/live && cd ~/live
$ git checkout "$(git tag -l | grep -v 'rc[0-9]*$' | grep '^v4\.1\.' | sort -V | tail -n 1)"
$ bundle config deployment 'true'
$ bundle config without 'development test'
$ bundle install -j"$(nproc)"
$ yarnpkg set version 1
$ yarnpkg install --pure-lockfile
$ RAILS_ENV=production bundle exec rake mastodon:setup
$ NODE_OPTIONS=--openssl-legacy-provider RAILS_ENV=production bundle exec rails assets:precompile
$ exit

# cp ~mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
# ln -s ../sites-available/mastodon /etc/nginx/sites-enabled/mastodon

# editor /etc/nginx/sites-available/mastodon
> Replace example.com and disable HSTS header!
> ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
> ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

# service nginx reload
# cp ~mastodon/live/dist/mastodon-*.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming

Mastodon 4.3.x (Debian 12)

Tip

This is the recommended and tested version.

  • Re-tested at 2025-04-06
  • Debian Bookworm (12.10.0; amd64)
  • rbenv: Commit cd29bcc6e0ef8b04ff0abbc8d27ccf48a720f4f2
  • ruby-build: Commit bc1a47dac2a611a276ec705923bd16e0385e8f28
  • bundler: Version 2.6.7
  • mastodon: Tag v4.3.7
# apt install imagemagick ffmpeg libvips-tools libpq-dev libxml2-dev libxslt1-dev git \
              g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf \
              bison build-essential libssl-dev libyaml-dev libreadline-dev \
              zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev \
              nginx nodejs redis-server redis-tools postgresql postgresql-contrib \
              libidn11-dev libicu-dev libjemalloc-dev \
              npm curl gnupg postfix bsd-mailx

# su -c psql postgres
> CREATE USER mastodon CREATEDB;
> \q

# useradd -m -s /bin/bash -u 7007 -U mastodon
# su -l mastodon
$ npm install corepack
$ echo 'export PATH="$HOME/node_modules/.bin:$PATH"' >> ~/.bashrc
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec bash
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.3.5
$ rbenv global 3.3.5
$ gem install bundler --no-document
$ git clone https://github.com/mastodon/mastodon.git ~/live && cd ~/live
$ git checkout "$(git tag -l | grep -v 'rc[0-9]*$' | grep '^v4\.3\.' | sort -V | tail -n 1)"
$ corepack enable
$ corepack prepare
$ bundle config deployment 'true'
$ bundle config without 'development test'
$ bundle install -j"$(nproc)"
$ yarn config set --home enableTelemetry 0
$ yarn install --immutable
$ RAILS_ENV=production bundle exec rake mastodon:setup
$ echo -e '\nMASTODON_USE_LIBVIPS=true' >> .env.production
$ exit

# cp ~mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
# ln -s ../sites-available/mastodon /etc/nginx/sites-enabled/mastodon

# editor /etc/nginx/sites-available/mastodon
> Replace example.com and disable HSTS header!
> ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
> ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

# service nginx reload
# cp ~mastodon/live/dist/mastodon-*.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming

Mastodon 4.4.x (Debian 12)

Warning

Abandoned! Don't use this version.

  • ✅ Redis (≥ v6.2)
  • ✅ PostgreSQL (≥ v13)
  • ❓ Node.js (≥ v20)
  • ✅ Ruby (≥ v3.2)

Mastodon 4.4.x (Debian 13)

Warning

Abandoned! Don't use this version.

  • ✅ Redis (≥ v6.2)
  • ✅ PostgreSQL (≥ v13)
  • ✅ Node.js (≥ v20)
  • ✅ Ruby (≥ v3.2)

Mastodon 4.5.x (Debian 13)

Note

Work in progress! Don't use this version.

  • ✅ Redis (≥ v7.0)
  • ✅ PostgreSQL (≥ v14)
  • ✅ Node.js (≥ v20.19)
  • ✅ Ruby (≥ v3.2)

TODO

WIP! USE AT YOUR OWN RISK!

  • Re-tested at 2025-08-16
  • Debian Bookworm (12.11.0; amd64)
  • libretranslate: Version 1.7.2 (with numpy 1.26.4)
  • Python: Version 3.11.2
# apt install pipx cmake python3-dev
# useradd -m -s /bin/bash -u 7177 -U libretranslate
# su -l libretranslate

$ pipx install libretranslate
$ pipx ensurepath
$ libretranslate --this-is-expected-to-fail
$ exit

# editor /etc/systemd/system/libretranslate.service
# systemctl daemon-reload
# systemctl enable --now libretranslate

# editor ~mastodon/live/.env.production
> LIBRE_TRANSLATE_ENDPOINT=http://127.0.0.1:5000
> LIBRE_TRANSLATE_API_KEY=

# systemctl reload mastodon-web
# systemctl restart mastodon-sidekiq

WIP! USE AT YOUR OWN RISK!

  • Re-tested at 2025-12-11
  • Debian Bookworm (12.11.0; amd64)
  • opensearch: Version 3.3.2
# tee -a /etc/sysctl.d/50-opensearch.conf <<< 'vm.max_map_count=262144' | sysctl -p -
# useradd -m -s /bin/bash -u 7997 -U opensearch
# su -l opensearch
$ wget 'https://artifacts.opensearch.org/releases/core/opensearch/3.3.2/opensearch-min-3.3.2-linux-x64.tar.gz'
$ tar xfva opensearch-min-3.3.2-linux-x64.tar.gz
$ rm -v opensearch-min-3.3.2-linux-x64.tar.gz
$ ln -s opensearch-3.3.2 opensearch.latest
$ cp -avn opensearch.latest/config config
$ echo -e '-Xms256m\n-Xmx256m' >> config/jvm.options.d/memory.options
$ echo '-XX:HeapDumpPath=/home/opensearch/data' >> config/jvm.options.d/misc.options
$ sed -i -r 's|^#path.data: .+|path.data: /home/opensearch/data|' config/opensearch.yml
$ mkdir data
$ chmod 0750 config data
$ exit
# editor /etc/systemd/system/opensearch.service
# systemctl daemon-reload
# systemctl enable --now opensearch

# editor ~mastodon/live/.env.production
> ES_ENABLED=true
> ES_HOST=localhost
> ES_PORT=9200

# systemctl reload mastodon-web
# systemctl restart mastodon-sidekiq
# su -l mastodon
$ cd ~/live
$ RAILS_ENV=production bin/tootctl search deploy
$ exit

# ### OPTIONAL? Initially no success after index deployment...
# systemctl restart mastodon-sidekiq mastodon-streaming mastodon-web
#!/bin/bash
###
# !!! EXPERIMENTAL !!!
###
set -eu -o pipefail
filename="/tmp/$(hostname -s)-$(date --utc +%Y%m%d-%H%M%S).tar.xz"
export XZ_OPT=-9
if [[ ! -x /usr/local/sbin/postgres-backup.sh ]]
then
(
echo "ERROR: postgres-backup.sh not found! Please setup postgres-backup script:"
echo
echo " https://github.com/froonix/misc-stuff/blob/master/scripts/postgres-backup"
echo
) >&2
exit 1
fi
shopt -s nullglob
dumps=( /var/lib/postgresqlbackups/{.globals,*}/"$(date --utc +%Y%m%d)"-*.sql.* )
shopt -s failglob
if [[ -z "${dumps[*]}" ]]
then
(
echo "Notice: Executing postgres-backup.sh"
/usr/local/sbin/postgres-backup.sh
echo "Done!"
echo
) >&2
fi
dpkg="/tmp/dpkg.selections"
dpkg --get-selections > "$dpkg"
touch "$filename"
chgrp sudo "$filename"
chmod 0640 "$filename"
cd /
tar cfa "$filename" \
home/USERNAME \
home/opensearch/config \
home/mastodon/live/.env.production \
home/mastodon/live/public/system/{media_attachments,accounts} \
var/lib/postgresqlbackups/{.globals,*}/"$(date --utc +%Y%m%d)"-*.sql.* \
var/cache/debconf \
var/spool/cron \
"${dpkg:1}" \
usr/local \
root \
etc
rm -f "$dpkg"
echo "$filename"
[Unit]
Description=LibreTranslate
Documentation=https://github.com/LibreTranslate/LibreTranslate
Wants=network-online.target
After=network-online.target
[Service]
Type=exec
User=libretranslate
Group=libretranslate
WorkingDirectory=/home/libretranslate
ExecStart=/home/libretranslate/.local/bin/libretranslate --disable-web-ui
ReadWritePaths=/home/libretranslate/.local/share/
ProtectSystem=strict
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# Credits: elasticsearch.service
# Apache License 2.0
[Unit]
Description=OpenSearch
Documentation=https://opensearch.org/
Wants=network-online.target
After=network-online.target
[Service]
Type=exec
RuntimeDirectory=opensearch
PrivateTmp=true
Environment=OPENSEARCH_HOME=/home/opensearch/opensearch.latest
Environment=OPENSEARCH_PATH_CONF=/home/opensearch/config
#Environment=OPENSEARCH_JAVA_OPTS=""
WorkingDirectory=/home/opensearch/opensearch.latest
User=opensearch
Group=opensearch
ExecStart=/home/opensearch/opensearch.latest/bin/opensearch
StandardOutput=journal
StandardError=inherit
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65535
# Specifies the maximum number of processes
LimitNPROC=4096
# Specifies the maximum size of virtual memory
LimitAS=infinity
# Specifies the maximum file size
LimitFSIZE=infinity
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=0
# SIGTERM signal is used to stop the Java process
KillSignal=SIGTERM
# Send the signal only to the JVM rather than its control group
KillMode=process
# Java process is never killed
SendSIGKILL=no
# When a JVM receives a SIGTERM signal it exits with code 143
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target

Debian Upgrade: Bullseye (11) » Bookworm (12)

# sed -i s/bullseye/bookworm/ /etc/apt/sources.list
# apt update
# apt upgrade --without-new-pkgs
# apt full-upgrade
# shutdown -r now

Repair Mastodon (3.5.8)

# cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
# apt purge ruby ruby-dev bundler
# apt autoremove --purge
# su -l mastodon

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv && cd ~/.rbenv
$ src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec bash
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.6
$ rbenv global 3.0.6
$ gem install bundler --no-document
$ cd ~/live
$ bundle install -j"$(nproc)"
$ yarn install
$ exit

# systemctl daemon-reload
# systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming

Update PostgreSQL: 13 » 15

# systemctl stop mastodon-web mastodon-sidekiq mastodon-streaming
# pg_dropcluster --stop 15 main
# pg_upgradecluster 13 main
# pg_dropcluster 13 main
# apt purge postgresql-13 postgresql-client-13
# apt autoremove --purge
# systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming

Final cleanup

# apt purge '~c'
# apt purge '~o'
# apt autoremove --purge
# apt autoclean

Mastodon Upgrade (Debian 12)

3.5.8 » 4.1.2

# systemctl stop mastodon-web mastodon-sidekiq mastodon-streaming
# su -l mastodon

$ cd ~/live
$ git fetch && git checkout v4.1.2
$ bundle install -j"$(nproc)"
$ yarn install
$ NODE_OPTIONS=--openssl-legacy-provider RAILS_ENV=production bundle exec rails assets:precompile
$ RAILS_ENV=production bundle exec rails db:migrate
$ exit

# cp -vf /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming

4.1.24 » 4.3.6

# apt update
# apt purge yarnpkg
# unlink /usr/local/bin/yarn
# apt install npm libvips-tools
# apt autoremove --purge
# su -l mastodon

$ npm install corepack
$ echo 'export PATH="$HOME/node_modules/.bin:$PATH"' >> ~/.bashrc

$ (cd ~/.rbenv && git pull)
$ (cd ~/.rbenv/plugins/ruby-build && git pull)
$ RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.3.5
$ exit

# systemctl stop mastodon-web mastodon-sidekiq mastodon-streaming
# su -l mastodon

$ cd ~/live
$ git fetch && git checkout v4.3.6
$ echo -e '\nMASTODON_USE_LIBVIPS=true' >> .env.production
$ rbenv global 3.3.5
$ corepack enable
$ corepack prepare
$ bundle install
$ yarn config set --home enableTelemetry 0
$ yarn install --immutable

$ RAILS_ENV=production bin/rails db:encryption:init
$ editor .env.production

$ RAILS_ENV=production bundle exec rails assets:precompile
$ RAILS_ENV=production bundle exec rails db:migrate
$ exit

# cp -vf ~mastodon/live/dist/mastodon-streaming*.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl restart mastodon-sidekiq.service mastodon-streaming.service mastodon-web.service
# su -l mastodon

$ cd ~/live
$ RAILS_ENV=production bin/tootctl search deploy --reset-chewy

Debian Upgrade: Bookworm (12) » Trixie (13)

TODO

  • Remove npm/corepack/yarn quirks and install native node-corepack package.

Mastodon Upgrade (Debian 13)

4.3.x » 4.4.x

TODO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment