{"id":25970560,"url":"https://github.com/ganiyevuz/docker-postgres-backup-tool","last_synced_at":"2026-04-12T18:04:15.456Z","repository":{"id":278765216,"uuid":"936706273","full_name":"GaniyevUz/docker-postgres-backup-tool","owner":"GaniyevUz","description":"Backup PostgreSQL to the local filesystem with periodic backups, automatic rotation, and Telegram bot integration to send the latest backup file.","archived":false,"fork":false,"pushed_at":"2025-02-28T19:48:41.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-04T23:17:43.350Z","etag":null,"topics":["backup","backup-tool","docker","docker-image","postgresql","telegram-bot"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/ganiyevuz/postgres-backup-telegram","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GaniyevUz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-21T14:46:21.000Z","updated_at":"2025-03-01T11:09:03.000Z","dependencies_parsed_at":"2025-02-21T15:43:50.424Z","dependency_job_id":"9ca949a9-48f7-4641-944c-d867d0b47430","html_url":"https://github.com/GaniyevUz/docker-postgres-backup-tool","commit_stats":null,"previous_names":["ganiyevuz/docker-postgres-backup-telegram","ganiyevuz/docker-postgres-backup-tool"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/GaniyevUz/docker-postgres-backup-tool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GaniyevUz%2Fdocker-postgres-backup-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GaniyevUz%2Fdocker-postgres-backup-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GaniyevUz%2Fdocker-postgres-backup-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GaniyevUz%2Fdocker-postgres-backup-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GaniyevUz","download_url":"https://codeload.github.com/GaniyevUz/docker-postgres-backup-tool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GaniyevUz%2Fdocker-postgres-backup-tool/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267644756,"owners_count":24120867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","backup-tool","docker","docker-image","postgresql","telegram-bot"],"created_at":"2025-03-04T23:17:46.538Z","updated_at":"2026-04-12T18:04:15.011Z","avatar_url":"https://github.com/GaniyevUz.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Docker pulls](https://img.shields.io/docker/pulls/ganiyevuz/postgres-backup-telegram)\n![GitHub actions](https://github.com/ganiyevuz/docker-postgres-backup-telegram/actions/workflows/ci.yml/badge.svg?branch=main)\n\n# postgres-backup-telegram\n\nBackup PostgresSQL to the local filesystem with periodic rotating backups, based\non [schickling/postgres-backup-s3](https://hub.docker.com/r/schickling/postgres-backup-s3/).\nAdditionally, it can send the **latest backup file via a Telegram bot**.\nBackup multiple databases from the same host by setting the database names in `POSTGRES_DB` separated by commas or\nspaces.\n\nSupports the following Docker architectures: `linux/amd64`, `linux/arm64`, `linux/arm/v7`, `linux/s390x`,\n`linux/ppc64le`.\n\nPlease consider reading detailed the [How the backups folder works?](#how-the-backups-folder-works).\n\nThis application requires the docker volume `/backups` to be a POSIX-compliant filesystem to store the backups (mainly\nwith support for hardlinks and softlinks). So filesystems like VFAT, EXFAT, SMB/CIFS, ... can't be used with this docker\nimage.\n\n## Usage\n\nDocker:\n\n```sh\ndocker run -u postgres:postgres -e POSTGRES_HOST=postgres -e POSTGRES_DB=dbname -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password  ganiyevuz/postgres-backup-telegram\n```\n\nDocker Compose:\n\n```yaml\nversion: '2'\nservices:\n  postgres:\n    image: postgres\n    restart: always\n    environment:\n      - POSTGRES_DB=database\n      - POSTGRES_USER=username\n      - POSTGRES_PASSWORD=password\n      #  - POSTGRES_PASSWORD_FILE=/run/secrets/db_password \u003c-- alternative for POSTGRES_PASSWORD (to use with docker secrets)\n  pgbackups:\n    image: ganiyevuz/postgres-backup-telegram\n    restart: always\n    user: postgres:postgres # Optional: see below\n    volumes:\n      - /var/opt/pgbackups:/backups\n    links:\n      - postgres\n    depends_on:\n      - postgres\n    environment:\n      - POSTGRES_HOST=postgres\n      - POSTGRES_DB=database\n      - POSTGRES_USER=username\n      - POSTGRES_PASSWORD=password\n      #  - POSTGRES_PASSWORD_FILE=/run/secrets/db_password \u003c-- alternative for POSTGRES_PASSWORD (to use with docker secrets)\n      - POSTGRES_EXTRA_OPTS=-Z1 --schema=public --blobs\n      - SCHEDULE=@daily\n      - BACKUP_ON_START=TRUE\n      - BACKUP_KEEP_DAYS=7\n      - BACKUP_KEEP_WEEKS=4\n      - BACKUP_KEEP_MONTHS=6\n      - HEALTHCHECK_PORT=8080\n      - TELEGRAM_BOT_TOKEN=123456:xxxxx\n      - TELEGRAM_CHAT_ID=123456\n      #  - TELEGRAM_BOT_TOKEN_FILE=/run/secrets/bot_token  \u003c-- alternative for TELEGRAM_BOT_TOKEN (to use with docker secrets)\n      #  - TELEGRAM_CHAT_FILE=/run/secrets/chat_id  \u003c-- alternative for TELEGRAM_CHAT_ID (to use with docker secrets)\n```\n\nFor security reasons it is recommended to run it as user `postgres:postgres`.\n\nIn case of running as `postgres` user, the system administrator must initialize the permission of the destination folder\nas follows:\n\n```sh\n# for default images (debian)\nmkdir -p /var/opt/pgbackups \u0026\u0026 chown -R 999:999 /var/opt/pgbackups\n# for alpine images\nmkdir -p /var/opt/pgbackups \u0026\u0026 chown -R 70:70 /var/opt/pgbackups\n```\n\n### Environment Variables\n\nMost variables are the same as in the [official postgres image](https://hub.docker.com/_/postgres/).\n\n| env variable            | description                                                                                                                                                                                                                                                                     |\n|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| BACKUP_DIR              | Directory to save the backup at. Defaults to `/backups`.                                                                                                                                                                                                                        |\n| BACKUP_SUFFIX           | Filename suffix to save the backup. Defaults to `.sql.gz`.                                                                                                                                                                                                                      |\n| BACKUP_ON_START         | If set to `TRUE` performs an backup on each container start or restart. Defaults to `FALSE`.                                                                                                                                                                                    |\n| BACKUP_KEEP_DAYS        | Number of daily backups to keep before removal. Defaults to `7`.                                                                                                                                                                                                                |\n| BACKUP_KEEP_WEEKS       | Number of weekly backups to keep before removal. Defaults to `4`.                                                                                                                                                                                                               |\n| BACKUP_KEEP_MONTHS      | Number of monthly backups to keep before removal. Defaults to `6`.                                                                                                                                                                                                              |\n| BACKUP_KEEP_MINS        | Number of minutes for `last` folder backups to keep before removal. Defaults to `1440`.                                                                                                                                                                                         |\n| BACKUP_LATEST_TYPE      | Type of `latest` pointer (`symlink`,`hardlink`,`none`). Defaults to `symlink`.                                                                                                                                                                                                  |\n| VALIDATE_ON_START       | If set to `FALSE` does not validate the configuration on start. Disabling this is not recommended. Defaults to `TRUE`.                                                                                                                                                          |\n| HEALTHCHECK_PORT        | Port listening for cron-schedule health check. Defaults to `8080`.                                                                                                                                                                                                              |\n| POSTGRES_DB             | Comma or space separated list of postgres databases to backup. If POSTGRES_CLUSTER is set this refers to the database to connect to for dumping global objects and discovering what other databases should be dumped (typically is either `postgres` or `template1`). Required. |\n| POSTGRES_DB_FILE        | Alternative to POSTGRES_DB, but with one database per line, for usage with docker secrets.                                                                                                                                                                                      |\n| POSTGRES_EXTRA_OPTS     | Additional [options](https://www.postgresql.org/docs/12/app-pgdump.html#PG-DUMP-OPTIONS) for `pg_dump` (or `pg_dumpall` [options](https://www.postgresql.org/docs/12/app-pg-dumpall.html#id-1.9.4.13.6) if POSTGRES_CLUSTER is set). Defaults to `-Z1`.                         |\n| POSTGRES_CLUSTER        | Set to `TRUE` in order to use `pg_dumpall` instead. Also set POSTGRES_EXTRA_OPTS to any value or empty since the default value is not compatible with `pg_dumpall`.                                                                                                             |\n| POSTGRES_HOST           | Postgres connection parameter; postgres host to connect to. Required.                                                                                                                                                                                                           |\n| POSTGRES_PASSWORD       | Postgres connection parameter; postgres password to connect with. Required.                                                                                                                                                                                                     |\n| POSTGRES_PASSWORD_FILE  | Alternative to POSTGRES_PASSWORD, for usage with docker secrets.                                                                                                                                                                                                                |\n| POSTGRES_PASSFILE_STORE | Alternative to POSTGRES_PASSWORD in [passfile format](https://www.postgresql.org/docs/12/libpq-pgpass.html#LIBPQ-PGPASS), for usage with postgres clusters.                                                                                                                     |\n| POSTGRES_PORT           | Postgres connection parameter; postgres port to connect to. Defaults to `5432`.                                                                                                                                                                                                 |\n| POSTGRES_USER           | Postgres connection parameter; postgres user to connect with. Required.                                                                                                                                                                                                         |\n| POSTGRES_USER_FILE      | Alternative to POSTGRES_USER, for usage with docker secrets.                                                                                                                                                                                                                    |\n| SCHEDULE                | [Cron-schedule](http://godoc.org/github.com/robfig/cron#hdr-Predefined_schedules) specifying the interval between postgres backups. Defaults to `@daily`.                                                                                                                       |\n| TZ                      | [POSIX TZ variable](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html) specifying the timezone used to evaluate SCHEDULE cron (example \"Europe/Paris\").                                                                                                       |\n| WEBHOOK_URL             | URL to be called after an error or after a successful backup (POST with a JSON payload, check `hooks/00-webhook` file for more info). Default disabled.                                                                                                                         |\n| WEBHOOK_ERROR_URL       | URL to be called in case backup fails. Default disabled.                                                                                                                                                                                                                        |\n| WEBHOOK_PRE_BACKUP_URL  | URL to be called when backup starts. Default disabled.                                                                                                                                                                                                                          |\n| WEBHOOK_POST_BACKUP_URL | URL to be called when backup completes successfully. Default disabled.                                                                                                                                                                                                          |\n| TELEGRAM_BOT_TOKEN_FILE | Path to a file containing the Telegram bot token. If set, the bot token will be read from this file. If not set, `TELEGRAM_BOT_TOKEN` must be provided. You can create a bot and get a token using [@BotFather](https://t.me/BotFather) on Telegram.                            |\n| TELEGRAM_BOT_TOKEN      | he Telegram bot token used to send backup files to a chat. If `TELEGRAM_BOT_TOKEN_FILE` is set, this value is ignored. Generate a bot token via [@BotFather](https://t.me/BotFather).                                                                                           |\n| TELEGRAM_CHAT_ID_FILE   | Path to a file containing the Telegram chat ID. If set, the chat ID will be read from this file. If not set, `TELEGRAM_CHAT_ID` must be provided. To get your chat ID, send a message to [@userinfobot](https://t.me/userinfobot), and it will return your chat ID.             |\n| TELEGRAM_CHAT_ID        | he Telegram chatID where the bot will send backup files. If `TELEGRAM_CHAT_ID_FILE` is set, this value is ignored. Retrieve your chat ID by messaging [@userinfobot](https://t.me/userinfobot) on Telegram.                                                                     |\n\n#### Special Environment Variables\n\nThis variables are not intended to be used for normal deployment operations:\n\n| env variable                | description                                        |\n|-----------------------------|----------------------------------------------------|\n| POSTGRES_PORT_5432_TCP_ADDR | Sets the POSTGRES_HOST when the latter is not set. |\n| POSTGRES_PORT_5432_TCP_PORT | Sets POSTGRES_PORT when POSTGRES_HOST is not set.  |\n\n### How the backups folder works?\n\nFirst, a new backup is created in the `last` folder with the full timestamp.\n\nOnce this backup is successfully completed, it is **hard-linked** (instead of copying, to save disk space) to the appropriate backup folders: **daily, weekly, and monthly**. This process ensures that only the latest backup is retained for each category.  \n- The **daily folder** keeps the most recent backup for the day.  \n- The **weekly folder** stores the latest backup for the week.  \n- The **monthly folder** retains the latest backup for the month (not the first backup of the month).  \n\nAfter storing the backup, the **Telegram bot automatically sends the latest backup file to the configured chat** as a message, ensuring quick and remote access to your backups.  \n\nSo the backup folder are structured as follows:\n\n* `BACKUP_DIR/last/DB-YYYYMMDD-HHmmss.sql.gz`: all the backups are stored separatly in this folder.\n* `BACKUP_DIR/daily/DB-YYYYMMDD.sql.gz`: always store (hard link) the **latest** backup of that day.\n* `BACKUP_DIR/weekly/DB-YYYYww.sql.gz`: always store (hard link) the **latest** backup of that week (the last day of the\n  week will be Sunday as it uses ISO week numbers).\n* `BACKUP_DIR/monthly/DB-YYYYMM.sql.gz`: always store (hard link) the **latest** backup of that month (normally the ~\n  31st).\n\nAnd the following symlinks are also updated after each successfull backup for simlicity:\n\n```\nBACKUP_DIR/last/DB-latest.sql.gz -\u003e BACKUP_DIR/last/DB-YYYYMMDD-HHmmss.sql.gz\nBACKUP_DIR/daily/DB-latest.sql.gz -\u003e BACKUP_DIR/daily/DB-YYYYMMDD.sql.gz\nBACKUP_DIR/weekly/DB-latest.sql.gz -\u003e BACKUP_DIR/weekly/DB-YYYYww.sql.gz\nBACKUP_DIR/monthly/DB-latest.sql.gz -\u003e BACKUP_DIR/monthly/DB-YYYYMM.sql.gz\n```\n\nFor **cleaning** the script removes the files for each category only if the new backup has been successfull.\nTo do so it is using the following independent variables:\n\n* BACKUP_KEEP_MINS: will remove files from the `last` folder that are older than its value in minutes after a new\n  successfull backup without affecting the rest of the backups (because they are hard links).\n* BACKUP_KEEP_DAYS: will remove files from the `daily` folder that are older than its value in days after a new\n  successfull backup.\n* BACKUP_KEEP_WEEKS: will remove files from the `weekly` folder that are older than its value in weeks after a new\n  successfull backup (remember that it starts counting from the end of each week not the beggining).\n* BACKUP_KEEP_MONTHS: will remove files from the `monthly` folder that are older than its value in months (of 31 days)\n  after a new successfull backup (remember that it starts counting from the end of each month not the beggining).\n\n### Hooks\n\nThe folder `hooks` inside the container can contain hooks/scripts to be run in differrent cases getting the exact\nsituation as a first argument (`error`, `pre-backup` or `post-backup`).\n\nJust create an script in that folder with execution permission so\nthat [run-parts](https://manpages.debian.org/stable/debianutils/run-parts.8.en.html) can execute it on each state\nchange.\n\nPlease, as an example take a look in the script already present there that implements the `WEBHOOK_URL` functionality.\n\n### Manual Backups\n\nBy default this container makes daily backups, but you can start a manual backup by running `/backup.sh`.\n\nThis script as example creates one backup as the running user and saves it the working folder.\n\n```sh\ndocker run --rm -v \"$PWD:/backups\" -u \"$(id -u):$(id -g)\" -e POSTGRES_HOST=postgres -e POSTGRES_DB=dbname -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password  ganiyevuz/postgres-backup-telegram /backup.sh\n```\n\n### Automatic Periodic Backups\n\nYou can change the `SCHEDULE` environment variable in `-e SCHEDULE=\"@daily\"` to alter the default frequency. Default is\n`daily`.\n\nMore information about the scheduling can be\nfound [here](http://godoc.org/github.com/robfig/cron#hdr-Predefined_schedules).\n\nFolders `daily`, `weekly` and `monthly` are created and populated using hard links to save disk space.\n\n## Restore examples\n\nSome examples to restore/apply the backups.\n\n### Restore using the same container\n\nTo restore using the same backup container, replace `$BACKUPFILE`, `$CONTAINER`, `$USERNAME` and `$DBNAME` from the\nfollowing command:\n\n```sh\ndocker exec --tty --interactive $CONTAINER /bin/sh -c \"zcat $BACKUPFILE | psql --username=$USERNAME --dbname=$DBNAME -W\"\n```\n\n### Restore using a new container\n\nReplace `$BACKUPFILE`, `$VERSION`, `$HOSTNAME`, `$PORT`, `$USERNAME` and `$DBNAME` from the following command:\n\n```sh\ndocker run --rm --tty --interactive -v $BACKUPFILE:/tmp/backupfile.sql.gz postgres:$VERSION /bin/sh -c \"zcat /tmp/backupfile.sql.gz | psql --host=$HOSTNAME --port=$PORT --username=$USERNAME --dbname=$DBNAME -W\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fganiyevuz%2Fdocker-postgres-backup-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fganiyevuz%2Fdocker-postgres-backup-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fganiyevuz%2Fdocker-postgres-backup-tool/lists"}