Postgres Setup
Installing Postgres
Option 1: System
First, install Postgres for your OS if you haven't already done so.
On Debian/Ubuntu/WSL you can run apt install postgresql, for other distros or operating systems, you can download it from here.
You should now have access to the psql CLI tool, and you can verify that the postgresql service is running with systemctl status postgresql.
Option 2: Docker
You can also run Postgres in a Docker container, instead of directly on your host system
docker run -d \
--name domain-locker-db \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=your-password \
-e POSTGRES_DB=domain_locker \
-p 5432:5432 \
postgres:15Where POSTGRES_USER is the username (e.g. postgres), POSTGRES_PASSWORD is your preferred password, POSTGRES_DB is the default database name that will be created, and postgres:15 is the Docker image (version 15).
You can then connect to the database from Domain Locker by setting your env vars (in .env or wherever):
DL_PG_HOST=localhost
DL_PG_PORT=5432
DL_PG_NAME=domain_locker
DL_PG_USER=postgres
DL_PG_PASSWORD=your-passwordOption 3: Managed
If you prefer cloud-managed solutions, popular providers include:
- Amazon RDS
- Google Cloud SQL
- Azure Database for PostgreSQL
- Neon
In each case, you’d retrieve the connection details (hostname, port, credentials) from the provider’s console and set your Domain Locker environment variables accordingly.
Configuring the Schema
We've got a Bash script in ./db/setup-postgres.sh which will take care of creating your database and applying the Domain Locker schema.
Schema
The schema can be found in db/schema.sql.
classDiagram
class users {
uuid id
text email
timestamp created_at
timestamp updated_at
}
class domains {
uuid id
uuid user_id
text domain_name
date expiry_date
text notes
timestamp created_at
timestamp updated_at
uuid registrar_id
timestamp registration_date
timestamp updated_date
}
class registrars {
uuid id
text name
text url
uuid user_id
}
class tags {
uuid id
text name
text color
text description
text icon
uuid user_id
}
class domain_tags {
uuid domain_id
uuid tag_id
}
class notifications {
uuid id
uuid user_id
uuid domain_id
text change_type
text message
boolean sent
boolean read
timestamp created_at
}
class billing {
uuid id
uuid user_id
text current_plan
timestamp next_payment_due
text billing_method
timestamp created_at
timestamp updated_at
jsonb meta
}
class dns_records {
uuid id
uuid domain_id
text record_type
text record_value
timestamp created_at
timestamp updated_at
}
class domain_costings {
uuid id
uuid domain_id
numeric purchase_price
numeric current_value
numeric renewal_cost
boolean auto_renew
timestamp created_at
timestamp updated_at
}
class domain_hosts {
uuid domain_id
uuid host_id
}
class domain_links {
uuid id
uuid domain_id
text link_name
text link_url
timestamp created_at
timestamp updated_at
text link_description
}
class domain_statuses {
uuid id
uuid domain_id
text status_code
timestamp created_at
}
class domain_updates {
uuid id
uuid domain_id
uuid user_id
text change
text change_type
text old_value
text new_value
timestamp date
}
class uptime {
uuid id
uuid domain_id
timestamp checked_at
boolean is_up
integer response_code
numeric response_time_ms
numeric dns_lookup_time_ms
numeric ssl_handshake_time_ms
timestamp created_at
}
class ssl_certificates {
uuid id
uuid domain_id
text issuer
text issuer_country
text subject
date valid_from
date valid_to
text fingerprint
integer key_size
text signature_algorithm
timestamp created_at
timestamp updated_at
}
class whois_info {
uuid id
uuid domain_id
text country
text state
text name
text organization
text street
text city
text postal_code
}
class user_info {
uuid id
uuid user_id
jsonb notification_channels
timestamp created_at
timestamp updated_at
text current_plan
}
class hosts {
uuid id
inet ip
numeric lat
numeric lon
text isp
text org
text as_number
text city
text region
text country
uuid user_id
}
class ip_addresses {
uuid id
uuid domain_id
inet ip_address
boolean is_ipv6
timestamp created_at
timestamp updated_at
}
class notification_preferences {
uuid id
uuid domain_id
text notification_type
boolean is_enabled
timestamp created_at
timestamp updated_at
}
class sub_domains {
uuid id
uuid domain_id
text name
timestamp created_at
timestamp updated_at
jsonb sd_info
}
users --> domains : user_id
registrars --> domains : registrar_id
users --> registrars : user_id
users --> tags : user_id
domains --> domain_tags : domain_id
tags --> domain_tags : tag_id
users --> notifications : user_id
domains --> notifications : domain_id
users --> billing : user_id
domains --> dns_records : domain_id
domains --> domain_costings : domain_id
domains --> domain_hosts : domain_id
hosts --> domain_hosts : host_id
domains --> domain_links : domain_id
domains --> domain_statuses : domain_id
domains --> domain_updates : domain_id
users --> domain_updates : user_id
domains --> uptime : domain_id
domains --> ssl_certificates : domain_id
domains --> whois_info : domain_id
users --> user_info : user_id
users --> hosts : user_id
domains --> ip_addresses : domain_id
domains --> notification_preferences : domain_id
domains --> sub_domains : domain_idAdvanced
Secure External Connections
If your database is exposed to the internet, look into:
- Firewall Rules: Limit which IPs can connect on port 5432.
- SSL/TLS: Configure Postgres to only accept encrypted connections.
Performance Tuning
For heavy usage, consider tuning:
shared_buffers,work_mem,checkpoint_segments,
and other parameters inpostgresql.conf.
Backup and Restore
To create a backup:
pg_dump -U postgres -h localhost -F c -b -v -f domain_locker_backup.sqlRestore it with:
pg_restore -U postgres -h localhost -d domain_locker -v domain_locker_backup.sqlEnable Password Authentication
During development, on locally running Postgres instance, you will likely want to use password authentication setup.
Edit the pg_hba.conf file to use md5 authentication
sudo nano /etc/postgresql/<version>/main/pg_hba.confAnd make the following edit:
- local all postgres peer
+ local all postgres md5Also, don't forget to ensure md5 is set for any host entries:
host all all 127.0.0.1/32 md5
host all all ::1/128 md5Then restart Postgres
sudo systemctl restart postgresqlAnd finally, set a (secure) password for the postgres user
sudo -u postgres psql -c "\password postgres"Troubleshooting
- Check logs in
/var/log/postgresql/(for Debian-based systems). - Verify running processes:
sudo systemctl status postgresql - Connection errors: Confirm your env vars are correct (host, port, user, password).