Skip to content

Instantly share code, notes, and snippets.

@mbreese
Last active February 4, 2025 20:31
Show Gist options
  • Save mbreese/10d31e5734c46f8be9448192296f4711 to your computer and use it in GitHub Desktop.
Save mbreese/10d31e5734c46f8be9448192296f4711 to your computer and use it in GitHub Desktop.
Running Postgres as a user account

db.sh

This script will manage a user-run postgres database. The main idea here is to run Postgres on a system where you don't have root access (and don't want root access). If you can not install Postgres through the system (or docker), then this is one way to still be able to use the database, even if you can't start it as a service.

  1. Create a database and initialize it with a user login

    ./db.sh initdb dbname username userpass

  2. Start/stop the database

    ./db.sh start|stop

  3. Connect to database

    ./db.sh psql dbname {-U myuser -W}

How does this work?

This works by creating a Postgres database in the main directory of this script in data/. A run/ directory is also created to store log files and the unix socket. Connections are then made via this unix socket, so you don't have to open a TCP socket.

Security

This isn't the best way of doing this with usernames and passwords sent in via command line arguments. If you want a more secure method, think of this as a place to get started.

But, the database itself will be owned by the user (not the system postgres user). The unix socket used to connect to the database also will belong to that user. Because of this, you can use Postgres on a multi-user system, start and stop the db at will, and keep the connections secure.

#!/bin/bash
cd $(dirname $0)
DBDIR=$(abspath data/)
RUNDIR=$(abspath run/)
startdb(){
pg_ctl -D $DBDIR -l $RUNDIR/logfile start
}
stopdb(){
pg_ctl -D $DBDIR stop
}
init_db() {
ERR=0
if [ "$1" = "" ]; then
echo "Missing dbname"
ERR=1
fi
ERR=0
if [ "$1" = "" ]; then
echo "Missing dbname"
ERR=1
fi
if [ "$2" = "" ]; then
echo "Missing username"
ERR=1
fi
if [ "$3" = "" ]; then
echo "Missing user password"
ERR=1
fi
if [ $ERR -ne 0 ]; then
echo "Usage: db.sh initdb dbname username passwd"
exit $ERR
fi
if [ -e $DBDIR ]; then
echo "$DBDIR exists!"
exit 1
fi
echo "Initializing database in $DBDIR"
mkdir -p $DBDIR $RUNDIR
initdb -D $DBDIR
echo "listen_addresses = ''" >> $DBDIR/postgresql.conf
echo "unix_socket_directories = '$RUNDIR'" >> $DBDIR/postgresql.conf
startdb
create__db $1 $2 $3
stopdb
}
create__db() {
cat <<EOF | psql -a -h $(abspath $RUNDIR) -p 5432 postgres
CREATE DATABASE $1;
CREATE USER $2 WITH ENCRYPTED PASSWORD '$3';
GRANT ALL PRIVILEGES ON DATABASE $1 TO $2;
\c $1
GRANT ALL ON SCHEMA public TO $2;
EOF
}
dump() {
if [ "$1" = "" ]; then
echo "Missing dbname"
exit 1
fi
pg_dump -h $(abspath $RUNDIR) -p 5432 $1
}
psql__db() {
if [ "$1" = "" ]; then
echo "Missing dbname"
exit 1
fi
dbname=$1
shift
psql -h $(abspath $RUNDIR) -p 5432 $@ $dbname
}
cmd=$1
shift
case "$cmd" in
start)
startdb
exit
;;
stop)
stopdb
exit
;;
initdb)
init_db $@
exit
;;
dump)
dump $@
exit
;;
psql)
psql__db $@
exit
;;
createdb)
create__db $@
exit
;;
*)
echo "db.sh [start|stop|initdb]"
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment