Skip to content

Litellm Docker Compose Stack

This Docker Compose stack consists of three containers: litellm, database, prometheus.

I'm going to create a tree folder only for this backup:

backups:
    litellm:
        litellm
        database
        prometheus

Litellm

From this container we only want to backup the config.yml, to see if it's a volume or a bind see inside the docker-compose.yaml file:

volumes:
      - type: bind
        source: /home/sysadmin/repositories/Apps/litellm-stack/config.yaml
        target: /app/config.yaml
        bind: {}

Postgres

This stack uses PG as a database, for database backups we dump the database in this case to be extra cautious I will also backup the volume:

volumes:
      - type: volume
        source: postgres_data
        target: /var/lib/postgresql/data
        volume: {}

Prometheus

Prometheus has a config.yml file and a named volume where it stores TSDB data, we will backup both:

volumes:
      - type: volume
        source: prometheus_data
        target: /prometheus
        volume: {}
      - type: bind
        source: /home/sysadmin/repositories/Apps/litellm-stack/prometheus.yml
        target: /etc/prometheus/prometheus.yml
        bind: {}

Backup

Create the backup directory layout in the host:

mkdir -p /home/sysadmin/backups/litellm/{postgres,prometheus,litellm}

For the Litellm config file, since is a bind mount we compress it directly in the host. From the docker-compose-yml we know where it is located:

sudo tar czf /home/sysadmin/backups/litellm/litellm/litellm_config_$(date +%F).tar.gz -C /home/sysadmin/repositories/Apps/litellm-stack/ config.yaml

For the Database backup, we dump the pg database, this would be the primary backup (In order to prevent corrupt data it might be a good idea stop the litellm app temporarily while we create the dump sudo docker stop litellm-litellm-1):

cd /home/sysadmin/repositories/Apps/litellm-stack/
sudo docker compose exec -T db pg_dump -U llmproxy litellm > /home/sysadmin/backups/litellm/postgres/litellm_pg_dump_$(date +%F).sql

NOTE: the database user and name we get from the docker-compose.yml

It might be a good idea to check the contents of this dump, sometimes it fails because a wrong username or db name.

Now the volume:

sudo docker run --rm \
-v litellm_postgres_data:/data \
-v /home/sysadmin/backups/litellm/postgres/:/backup \
alpine \
tar czf /backup/litellm_pg_volume_$(date +%F).tar.gz -C /data .

Now for Prometheus we stop the container:

sudo docker compose stop prometheus 
# OR
sudo docker stop litellm-prometheus-1

Backup Volume: Create a temporary container, mount the volume that prometheus uses, create the .tar.gz file and copy to the host (through the bind mount):

sudo docker run --rm -v litellm_prometheus_data:/data -v /home/sysadmin/backups/litellm/prometheus:/backup alpine tar czf /backup/litellm_prometheus_$(date +%F).tar.gz -C /data .

Backup config file: Since the config file lives also in the host (because of the bind mount), we simply compress it and locate it in the right place:

sudo tar czf \
/home/sysadmin/backups/litellm/prometheus/litellm_prometheus_config_$(date +%F).tar.gz \
-C /home/sysadmin/repositories/Apps/litellm-stack/ prometheus.yml

Now you could start again everything with sudo docker compose up or start the specific containers that were stopped.

Restic

To make a backup of all those files we just created we can simply backup the litellm folder inside backups. To make things easier and not create extra folders in this backup we cd to the exact location:

cd /home/sysadmin/backups
sudo restic -r <path/to/restic/repo> backup ./litellm --tag full_litellm_bk

This tag will help us restore the specific backup that we want later on.

Restore

Stop everything:

sudo docker compose down

Delete volumes:

sudo docker volume rm litellm_postgres litellm_prometheus_data

To simulate a fresh installation of the stack maybe also delete the contents of the litellm config.yml file.

Restore files from Restic:

sudo restic -r <path/to/restic/repo> restore --tag full_litellm_bk latest --target <where/ever/>

If we check sudo ls <where/ever/> we will see a litellm folder created.

Then copy the litellm config compressed file to outside the folder and extract it and put the extracted files inside the actual litellm folder app:

sudo cp <where/ever/>litellm/litellm/litellm_config_2026-01-13.tar.gz /tmp
tar xzf /tmp/litellm_config_2026-01-13.tar.gz  -C /home/sysadmin/repositories/Apps/litellm/

Restore Postgres: Create the respecive volume, start only the database container and go inside the container and execute the dump from inside the container (other way would be copying the dump inside the container and executing again from inside it):

sudo docker volume create litellm_postgres_data
sudo docker compose up -d db
sudo docker compose exec -T db psql -U llmproxy litellm < <where/ever>/litellm/postgres/litellm_pg_dump_2026-01-13.sql

NOTE: We could've also restored the volume, but for databases really the main thing is the dump.

Restore Prometheus: Create the respective volume, run a light weight container to put the volume data in there:

sudo docker volume create litellm_prometheus_data
sudo docker run --rm -v litellm_prometheus_data:/data -v <where/ever/>litellm/prometheus:/backup alpine tar xzf /backup/litellm_prometheus_2026-01-13.tar.gz -C /data

Now also restore the config file for Prometheus, since this is a bind mount we can just extract the file and locate it in the litellm app folder:

sudo tar xzf <where/ever/>litellm/prometheus/litellm_prometheus_config_2026-01-13.tar.gz -C /home/sysadmin/repositories/Apps/litellm/

Now start everything with sudo docker compose up -d. Check that everything works correctly and that for example the virtual keys still the same ones as before.

ls -l /etc/nginx/sites-enabled/default