{"id":20779079,"url":"https://github.com/jjwizardmp/bash-script-postgresql-backup-db","last_synced_at":"2026-04-11T16:07:07.345Z","repository":{"id":156560387,"uuid":"595934768","full_name":"JJWizardMP/Bash-Script-PostgreSQL-Backup-DB","owner":"JJWizardMP","description":"Generates database backups from time to time ","archived":false,"fork":false,"pushed_at":"2023-02-01T05:38:56.000Z","size":192,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-18T08:37:21.845Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JJWizardMP.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":"2023-02-01T05:26:34.000Z","updated_at":"2023-02-01T05:33:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"38759758-d23b-4190-81ed-3fc09482457b","html_url":"https://github.com/JJWizardMP/Bash-Script-PostgreSQL-Backup-DB","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JJWizardMP%2FBash-Script-PostgreSQL-Backup-DB","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JJWizardMP%2FBash-Script-PostgreSQL-Backup-DB/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JJWizardMP%2FBash-Script-PostgreSQL-Backup-DB/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JJWizardMP%2FBash-Script-PostgreSQL-Backup-DB/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JJWizardMP","download_url":"https://codeload.github.com/JJWizardMP/Bash-Script-PostgreSQL-Backup-DB/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243119537,"owners_count":20239321,"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","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":[],"created_at":"2024-11-17T13:25:54.716Z","updated_at":"2025-12-24T16:46:40.493Z","avatar_url":"https://github.com/JJWizardMP.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"## PostgreSQL Back Up\r\n[//]: ![](https://cdn.travelpulse.com/images/99999999-9999-9999-9999-999999999999/9ad39357-0a71-33e2-023b-939625f6847b/500x309.jpg)\r\n![](https://i.ytimg.com/vi/PPQ8m8xQAs8/maxresdefault.jpg)\r\n\r\n## Introduction\r\n\r\nCreate a bash script for create a backup of database every 20 minutes.\r\n\r\n- psql: psql is a terminal-based front-end to PostgreSQL. It enables you to type in queries interactively, issue them to PostgreSQL, and see the query results. \r\n- pg_dump: pg_dump is a utility for backing up a PostgreSQL database. It makes consistent backups even if the database is being used concurrently. pg_dump does not block other users accessing the database (readers or writers).\r\n- pg_restore: pg_restore is a utility for restoring a PostgreSQL database from an archive created by pg_dump in one of the non-plain-text formats. It will issue the commands necessary to reconstruct the database to the state it was in at the time it was saved.\r\n\r\n## Requeriments\r\n\r\n- Write a bash script that allows create a backup of database every 20 minutes.\r\n\r\n## Technologies\r\n\r\n#### Command line\r\n\r\n| [psql](https://www.postgresql.org/docs/current/app-psql.html) | [pg_dump](https://www.postgresql.org/docs/current/app-pgdump.html) | [pg_restore](https://www.postgresql.org/docs/current/app-pgrestore.html) |\r\n| :----------------------------------: | :-------------------------: | :-------------------------: |\r\n\r\n## Bash Script Configuration\r\n\r\n### Postgresql installation:\r\n\r\nWe need to go to the next web page for copy the installation script [postgresql](https://www.postgresql.org/docs/current/app-pgrestore.html) on ubuntu. We add the script in the following block of code, but it is a good idea always copy from the source page because it might change in a near future.\r\n\r\n```sh\r\n# Create the file repository configuration:\r\nsudo sh -c 'echo \"deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\" \u003e /etc/apt/sources.list.d/pgdg.list'\r\n\r\n# Import the repository signing key:\r\nwget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -\r\n\r\n# Update the package lists:\r\nsudo apt-get update\r\n\r\n# Install the latest version of PostgreSQL.\r\n# If you want a specific version, use 'postgresql-12' or similar instead of 'postgresql':\r\nsudo apt-get -y install postgresql\r\n```\r\n\r\n### Posgresql configuration:\r\n\r\nThe next step is configure the auth login for \"postgres\" user, this is neccesary for the perfect perfomance of the script. In this version We use the same password of the .env file, the reason behind this is because the family postgres's commands (psql, pg_dump and pg_restore) use a global variable named \"$PGPASSWORD\", this global variable allow us run the previous commands without set the password in the terminal. Thanks to this option, We can execute the script in automatic mode every certain time.\r\n\r\n#### Locating **hba.conf**:\r\n\r\nNote that the location of this file isn't very consistent.\r\n\r\nYou can use \r\n```sh\r\nlocate pg_hba.conf \r\n```\r\nInstall the command \"locate\" if is necessary or ask PostgreSQL SHOW hba_file; to discover the file location.\r\n\r\n#### Edit **pg_hba.conf** file:\r\n\r\nYou have to edit (with sudo, if is necessary) the file called pg_hba.conf located in:\r\n\r\n```sh\r\n/etc/postgresql/[your_version]/main\r\n```\r\n\r\nFor example:\r\n\r\n![Located](./assets/images/locate-pg_hba.png)\r\n\r\nInside the file, look for the following line (it's almost at the end, there are 4 almost identical lines but it's the first):\r\n\r\n```sh\r\nlocal   all   postgres   peer\r\n```\r\n\r\n(It will be separated with more spaces)\r\n\r\nAnd change **peer** to **trust** so that it looks like this:\r\n\r\n```sh\r\nlocal   all   postgres   trust\r\n```\r\n\r\nSave changes and restart the server with:\r\n\r\n```sh\r\nsudo service postgresql restart\r\n```\r\n\r\nNow log in with the user postgres (later, you will be able to log in with another user after doing this).\r\n\r\n```sh\r\npsql -U postgres\r\n```\r\n\r\nChange your password with:\r\n\r\n```sh\r\nalter user postgres with password 'yourpasswordhere';\r\n```\r\n\r\nThe password set for this script is the same used in the .env file. In the case that if is necessary set a different password, the script must be update with a new feature that satisfy that functionality. Close **psql** and edit the **pg_hba.conf** file again. Now edit the following line:\r\n\r\n```sh\r\nlocal   all   postgres   trust\r\n```\r\n\r\nIt should look like this:\r\n\r\n```sh\r\nlocal   all   postgres   md5\r\n```\r\n\r\nRestart the server again:\r\n\r\n```sh\r\nsudo service postgresql restart\r\n```\r\n\r\nTry to login again. If this method doesn't work, specify the host.\r\n\r\n### Contrab Configuration:\r\n\r\n**Crontab** is a text file, it is a file with a special content and specifically designed so that it is read correctly by Cron and proceeds with the execution that we have programmed.\r\n\r\nUsing cron is through directly manipulating the */etc/crontab* file. On the default installation of various Linux distributions, this file will look something like the following:\r\n\r\n```sh\r\n# /etc/crontab: system-wide crontab\r\n# Unlike any other crontab you don't have to run the `crontab'\r\n# command to install the new version when you edit this file\r\n# and files in /etc/cron.d. These files also have username fields,\r\n# that none of the other crontabs do.\r\n\r\nSHELL=/bin/sh\r\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\r\nMAILTO=root\r\nHOME=/\r\n\r\n# Example of job definition:\r\n# .---------------- minute (0 - 59)\r\n# |  .------------- hour (0 - 23)\r\n# |  |  .---------- day of month (1 - 31)\r\n# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...\r\n# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,\u003e\r\n# |  |  |  |  |\r\n# *  *  *  *  * user-name command to be executed\r\n17 *    * * *   root    cd / \u0026\u0026 run-parts --report /etc/cron.hourly\r\n25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / \u0026\u0026 run-parts --repo\u003e\r\n47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / \u0026\u0026 run-parts --repo\u003e\r\n52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / \u0026\u0026 run-parts --repo\u003e\r\n#\r\n```\r\nThe first four lines are variables that indicate the following:\r\n\r\n- **SHELL**: It is the 'shell' under which the cron is executed. If not specified, the one indicated in the /etc/passwd line corresponding to the user who terminated cron will be taken by default.\r\n\r\n- **PATH**: Contains or indicates the path to the directories in which cron will look for the command to execute. This path is different from the global system or user path.\r\n\r\n- **MAIL TO**: It is who the output of the command is sent to (if it has any output). Cron sent a mail to whoever is specified in this variable, that is, it must be a valid user of the system or some other system. If not specified, then cron will provide the mail to the user who owns the command being executed.\r\n\r\n- **HOME**: It is the root or main directory of the cron command, if it is not indicated then the root will be the one indicated in the /etc/passwd file corresponding to the user that executes cron.\r\n\r\nWe need to edit the file that owns the tasks. For this we are going to help ourselves with the *crontab -e* command. We have the following structure:\r\n\r\n![crontab](./assets/images/crontab_structure.png)\r\n\r\n5 asterisks and the command to execute. Each of the 5 asterisks means:\r\n\r\n- m: minute\r\n- h: hour\r\n- dom: day of the month\r\n- mon: month\r\n- dow: day of the week\r\n\r\nWe open the */etc/crontab* file with the next command:\r\n\r\n```sh\r\ncrontab -e\r\n```\r\n\r\nWe have the following file:\r\n\r\n```sh\r\n# To define the time you can provide concrete values for\r\n# minute (m), hour (h), day of month (dom), month (mon),\r\n# and day of week (dow) or use '*' in these fields (for 'any').\r\n# \r\n# Notice that tasks will be started based on the cron's system\r\n# daemon's notion of time and timezones.\r\n# \r\n# Output of the crontab jobs (including errors) is sent through\r\n# email to the user the crontab file belongs to (unless redirected).\r\n# \r\n# For example, you can run a backup of all your user accounts\r\n# at 5 a.m every week with:\r\n# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/\r\n# \r\n# For more information see the manual pages of crontab(5) and cron(8)\r\n# \r\n# m h  dom mon dow   command\r\n```\r\nWe add to the end of file the script We want to execute every 20 minutes, Additionally we add another task to delete old back up's directories each day:\r\n\r\n```sh\r\n*/20 * * * * /home/joan/scriptSshBdVcm/script.sh export remote \u003e /dev/null 2\u003e /tmp/crontab_script_log.txt 2\u003e\u00261\r\n\r\n0 0 * * * /home/joan/scriptSshBdVcm/script.sh directory \u003e /dev/null 2\u003e /tmp/crontab_script_log.txt 2\u003e\u00261\r\n```\r\n\r\nSave and close, if is necessary restart *cron* service:\r\n\r\n```sh\r\nsudo service cron reload\r\n```\r\n\r\n### VCM BackUp Script:\r\n\r\nThis script export *Postgres Database* in a *.tar*. \r\n\r\nWe have to assign execute permissions to be able to execute it correctly by Cron, otherwise it will not have execute permissions (Do not forget config your .env and add your database credentials):\r\n\r\n```sh\r\nchmod ugo+x script.sh \r\n```\r\n\r\nRun the main script but first we need to specify 2 arguments.\r\n\r\nArguments:\r\n- task: \"import\", \"export\" or \"directory\".\r\n- method: For the first case \"export\", we need to pass \"local\" or \"remote\".\r\n- dbflag: if send \"import\" as second argument. We only need to pass \"1\" if you want to create the database and role before import the *.tar* file. Pass any other number if this is not neccesary.\r\n- filename_backup: If you want to import a specific backup file, you need to pass this argument with the absolute path of the .tar file. \r\n\r\nFor export database:\r\n\r\nCase 1: Export database task in local method.\r\n\r\n```sh\r\n./script.sh export local\r\n```\r\n\r\nCase 2: Export database task in remote method.\r\n\r\n```sh\r\n./script.sh export remote\r\n```\r\n\r\nFor import database:\r\n\r\ncase 3: Import the last backup created.\r\n\r\n```sh\r\n./script.sh import remote 1\r\n```\r\n\r\ncase 4: Import a specific backup (You need to pass absolute path of the backup file)\r\n\r\n```sh\r\n./script.sh import 1 remote /absolutepathtobackup/filename\r\n```\r\n\r\nRemove old backups directories:\r\n\r\ncase 5: Clear old backup directories.\r\n\r\n```sh\r\n./script.sh directory\r\n```\r\n## Contributors\r\n\r\nThis project was written by:\r\n\r\n- Programmer :\r\n  - [Joan de Jesús Méndez Pool](https://github.com/JJWizardMP)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjwizardmp%2Fbash-script-postgresql-backup-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjjwizardmp%2Fbash-script-postgresql-backup-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjwizardmp%2Fbash-script-postgresql-backup-db/lists"}