Home Explore Blog Models CI



nixpkgs

1st chunk of `nixos/modules/services/databases/postgresql.md`
89cab8c451090aa683a8f77007cc73f1d9151c81600fa61d0000000100000ff9
# PostgreSQL {#module-postgresql}

<!-- FIXME: render nicely -->
<!-- FIXME: source can be added automatically -->

*Source:* {file}`modules/services/databases/postgresql.nix`

*Upstream documentation:* <https://www.postgresql.org/docs/>

<!-- FIXME: more stuff, like maintainer? -->

PostgreSQL is an advanced, free, relational database.
<!-- MORE -->

## Configuring {#module-services-postgres-configuring}

To enable PostgreSQL, add the following to your {file}`configuration.nix`:
```nix
{
  services.postgresql.enable = true;
  services.postgresql.package = pkgs.postgresql_15;
}
```

The default PostgreSQL version is approximately the latest major version available on the NixOS release matching your [`system.stateVersion`](#opt-system.stateVersion).
This is because PostgreSQL upgrades require a manual migration process (see below).
Hence, upgrades must happen by setting [`services.postgresql.package`](#opt-services.postgresql.package) explicitly.

<!--
After running {command}`nixos-rebuild`, you can verify
whether PostgreSQL works by running {command}`psql`:

```ShellSession
$ psql
psql (9.2.9)
Type "help" for help.

alice=>
```
-->

By default, PostgreSQL stores its databases in {file}`/var/lib/postgresql/$psqlSchema`. You can override this using [](#opt-services.postgresql.dataDir), e.g.
```nix
{ services.postgresql.dataDir = "/data/postgresql"; }
```

## Initializing {#module-services-postgres-initializing}

As of NixOS 24.05,
`services.postgresql.ensureUsers.*.ensurePermissions` has been
removed, after a change to default permissions in PostgreSQL 15
invalidated most of its previous use cases:

- In psql < 15, `ALL PRIVILEGES` used to include `CREATE TABLE`, where
  in psql >= 15 that would be a separate permission
- psql >= 15 instead gives only the database owner create permissions
- Even on psql < 15 (or databases migrated to >= 15), it is
  recommended to manually assign permissions along these lines
  - <https://www.postgresql.org/docs/release/15.0/>
  - <https://www.postgresql.org/docs/15/ddl-schemas.html#DDL-SCHEMAS-PRIV>

### Assigning ownership {#module-services-postgres-initializing-ownership}

Usually, the database owner should be a database user of the same
name. This can be done with
`services.postgresql.ensureUsers.*.ensureDBOwnership = true;`.

If the database user name equals the connecting system user name,
postgres by default will accept a passwordless connection via unix
domain socket. This makes it possible to run many postgres-backed
services without creating any database secrets at all.

### Assigning extra permissions {#module-services-postgres-initializing-extra-permissions}

For many cases, it will be enough to have the database user be the
owner. Until `services.postgresql.ensureUsers.*.ensurePermissions` has
been re-thought, if more users need access to the database, please use
one of the following approaches:

**WARNING:** `services.postgresql.initialScript` is not recommended
for `ensurePermissions` replacement, as that is *only run on first
start of PostgreSQL*.

**NOTE:** all of these methods may be obsoleted, when `ensure*` is
reworked, but it is expected that they will stay viable for running
database migrations.

**NOTE:** please make sure that any added migrations are idempotent (re-runnable).

#### in database's setup `postStart` {#module-services-postgres-initializing-extra-permissions-superuser-post-start}

`ensureUsers` is run in `postgresql-setup`, so this is where `postStart` must be added to:

```nix
{
  systemd.services.postgresql-setup.postStart = ''
    psql service1 -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"'
    psql service1 -c 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "extraUser1"'
    # ....
  '';
}
```

#### in intermediate oneshot service {#module-services-postgres-initializing-extra-permissions-superuser-oneshot}

Make sure to run this service after `postgresql.target`, not `postgresql.service`.

They differ in two aspects:
- `postgresql.target` includes `postgresql-setup`, so users managed via `ensureUsers` are already created.

Title: NixOS PostgreSQL Module: Configuration and Initialization
Summary
This document outlines how to configure and initialize PostgreSQL within NixOS. It covers enabling PostgreSQL, setting its package version (noting that upgrades require manual migration), and customizing the data directory. A significant section details changes in PostgreSQL 15 and NixOS 24.05 regarding permissions, specifically the removal of `ensureUsers.*.ensurePermissions`. It explains how to assign database ownership and provides methods for assigning extra permissions, such as using `postStart` in `postgresql-setup` or an intermediate oneshot service, emphasizing the importance of running these after `postgresql.target` to ensure users are created.