Enabling Translations in your Mastodon Node with LibreTranslate
Out-of-the-box, Mastodon supports post translation using an external service. But to take advantage of it, you have to set up the services and bind your Mastodon instance to them.
It turns out this is a relatively simple process with only a few sharp edges. I’ve documented my walk to a working configuration here. This process was supported by the Mastodon documentation and this delightful tutorial for setting up LibreTranslate in Docker.
Set up storage and Docker configs for LibreTranslate
For our translation service, we’ll use LibreTranslate, which can be locally installed as a web service. To start, we’ll go ahead and create some new storage and configure it. We’ll run this all as a user with Docker permissions
sudo mkdir /media/squire/libretranslate
sudo chown $USER:$USER /media/squire/libretranslate
cd /media/squire/libretranslate
mkdir admin
mkdir docker
mkdir data/{keys,local}
With that all set up, we’ll build out our Docker compose rule and an environment file to prep up the LibreTranslate project.
docker/docker-compose.yml
version: "3"
services:
libretranslate:
container_name: libretranslate
image: libretranslate/libretranslate:v1.3.11
restart: unless-stopped
dns:
- 1.1.1.1
- 8.8.8.8
ports:
- "5000:5000"
healthcheck:
test: ['CMD-SHELL', './venv/bin/python scripts/healthcheck.py']
env_file:
- libretranslate.env
volumes:
- libretranslate_api_keys:/app/db
- libretranslate_local:/home/libretranslate/.local
volumes:
libretranslate_api_keys:
driver_opts:
type: none
device: /media/squire/libretranslate/data/keys
o: bind
libretranslate_local:
driver_opts:
type: none
device: /media/squire/libretranslate/data/local
o: bind
Worth noting here is the volume bindings from our local directories to the Docker volumes. You’ll want to adjust those to the correct directory names on your setup.
Our libretranslate.env
file configures our instance. The meaning of these keys is documented in LibreTranslate’s GitHub project
LT_DEBUG=true
#LT_UPDATE_MODELS=true
#LT_SSL=true
LT_SUGGESTIONS=false
LT_METRICS=true
#LT_API_KEYS=YES
LT_THREADS=12
LT_FRONTEND_TIMEOUT=2000
#LT_REQ_LIMIT=400
#LT_CHAR_LIMIT=1200
LT_API_KEYS_DB_PATH=/app/db/api_keys.db
Worth noting here:
- I’ve disabled
LT_SSL
because I’m only accepting local connections. For similar reason, I’m not usingLT_API_KEYS
and commented that out as well. If you do use API keys, I found it necesary totouch keys/api_keys.db
to prime the file and then to chmod the file to the corect user (which is1203:1203
for reasons I’m not entirely sure of). - I’ve also disabled
LT_UPDATE_MODELS
. When the Docker image comes up, the first thing the server tries to do is update its models, which takes an awful long time (my server knows about 60 models). While it’s doing that, the server will reject all API queries. If you getconnection reset by peer
errors while trying to connect, that may be what it’s attempting to do. I’ll come back later and enable this, but for testing purposes I left it off and will let my models go stale.
With these pieces configured, we can fire up the server. From the docker
directory:
docker compose up
Once the Docker image has loaded, we’ll want to use utility scripts in the image to pull the initial dataset. Connect to the Docker instance with
docker exec -it libretranslate bash
… and then run the initial download script for the translation data.
for i in `/app/venv/bin/argospm list`;do /app/venv/bin/argospm install $i;done
This will take awhile (about 10 minutes in my case); take a break.
Once that’s done, you should be able to see the core argos-translate
packages
that LibreTranslate uses as its language model. Exit your Docker shell and do
ls -1 /media/squire/libretranslate/data/local/share/argos-translate/packages
You should see several that look like
ar_en
de_en
en_ar
en_de
en_es
en_fi
translate-az_en-1_5
translate-ca_en-1_7
translate-cs_en-1_5
translate-da_en-1_3
translate-el_en-1_5
… etc.
At this point, if you want to configure an API key you can, but I skipped that step.
You should be able now to test the server:
curl -XPOST -H "Content-type: application/json" -d '{
"q": "Bolha.io is the most cool project in the fediverso",
"source": "en",
"target": "pt"
}' 'http://localhost:5000/translate'
You should get a response like {"translatedText":"Bolha.io é o projeto mais legal no fediverso"}
. If you do, congrats! LibreTranslate is live on your machine!
Bind your Mastodon node to your LibreTranslate instance
With the server up and running, binding to it is extremely straightforward. In
your Mastodon installation, find the .env.production
file and configure
# translation config
DEFAULT_LOCALE=en
ALLOWED_PRIVATE_ADDRESSES=127.0.0.1
LIBRE_TRANSLATE_ENDPOINT=http://127.0.0.1:5000
Now reboot mastodon (sudo systemctl restart mastodon-web
). When it comes back up, posts
in languages other than your configured native language should offer you a translation option!
Click Translate
under the post to do the thing.
Register translate as a service
Just one more step: Let’s go ahead and set up LibreTranslate as a systemd
service it comes up automatically on boot. Add the file /media/squire/libretranslate/admin/libretranslate.service
:
# Copy this file to /etc/systemd/system/libretranslate.service
[Unit]
Description=LibreTranslate
After=network.target
[Service]
# Set User and WorkingDirectory to the correct values
User=your-libretranslate-user
WorkingDirectory=/media/squire/libretranslate/docker
Type=oneshot
RemainAfterExit=true
ExecStart=docker compose up -d --remove-orphans
ExecStop=docker compose down
[Install]
WantedBy=multi-user.target
All set! As the first comment says, copy it to /etc/systemd/system/libretranslate.service
, chown it to root:root
, and systemctl start libretranslate
. Make sure to set the correct values for WorkingDirectory
and User
for your installation, of course.
Comments