Skip to content

Commit 0d95279

Browse files
committed
refactor: rename yml to yaml, standardize pkg templates, add Base category
1 parent bcea44d commit 0d95279

7 files changed

Lines changed: 218 additions & 143 deletions

File tree

File renamed without changes.

Containerfile

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,25 @@ ARG PACKAGES="postgresql${PG_VERSION}-server postgresql${PG_VERSION}-client post
88
ARG UPSTREAM_URL="https://www.postgresql.org/docs/release/"
99
ARG HEALTHCHECK_ENDPOINT="pg_isready -q"
1010

11+
ENV HEALTHCHECK_URL="${HEALTHCHECK_ENDPOINT}"
12+
13+
# --- Metadata (Injected by Generator) ---
1114
LABEL org.opencontainers.image.title="PostgreSQL ${PG_VERSION}" \
12-
org.opencontainers.image.description="PostgreSQL ${PG_VERSION} on FreeBSD" \
13-
org.opencontainers.image.source="https://github.com/daemonless/postgres" \
14-
org.opencontainers.image.url="https://www.postgresql.org/" \
15-
org.opencontainers.image.documentation="https://www.postgresql.org/docs/${PG_VERSION}/" \
16-
org.opencontainers.image.licenses="PostgreSQL" \
17-
org.opencontainers.image.vendor="daemonless" \
18-
org.opencontainers.image.authors="daemonless" \
19-
io.daemonless.port="5432" \
20-
io.daemonless.arch="${FREEBSD_ARCH}" \
21-
io.daemonless.category="Databases" \
22-
io.daemonless.upstream-url="${UPSTREAM_URL}" \
23-
io.daemonless.packages="${PACKAGES}" \
24-
org.freebsd.jail.allow.sysvipc="required"
15+
org.opencontainers.image.description="The World's Most Advanced Open Source Relational Database on FreeBSD." \
16+
org.opencontainers.image.source="https://github.com/daemonless/postgres" \
17+
org.opencontainers.image.url="https://www.postgresql.org/" \
18+
org.opencontainers.image.documentation="https://www.postgresql.org/docs/${PG_VERSION}/" \
19+
org.opencontainers.image.licenses="PostgreSQL" \
20+
org.opencontainers.image.vendor="daemonless" \
21+
org.opencontainers.image.authors="daemonless" \
22+
io.daemonless.category="Databases" \
23+
io.daemonless.port="5432" \
24+
io.daemonless.volumes="/var/lib/postgresql/data" \
25+
org.freebsd.jail.allow.sysvipc="required" \
26+
io.daemonless.arch="${FREEBSD_ARCH}" \
27+
io.daemonless.pkg-source="containerfile" \
28+
io.daemonless.upstream-url="${UPSTREAM_URL}" \
29+
io.daemonless.packages="${PACKAGES}"
2530

2631
# Install PostgreSQL
2732
RUN pkg update && \
@@ -38,7 +43,7 @@ RUN mkdir -p /var/lib/postgresql/data /var/run/postgresql /run/secrets /docker-e
3843
COPY root/ /
3944

4045
# Make scripts executable
41-
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* 2>/dev/null || true
46+
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* /healthz 2>/dev/null || true
4247

4348
# Store PG version for scripts
4449
RUN mkdir -p /var/db/postgres && echo "${PG_VERSION}" > /var/db/postgres/pg_version
@@ -55,5 +60,8 @@ ENV PGDATA="/var/lib/postgresql/data" \
5560
POSTGRES_INITDB_ARGS="" \
5661
POSTGRES_HOST_AUTH_METHOD="scram-sha-256"
5762

63+
# --- Expose (Injected by Generator) ---
5864
EXPOSE 5432
59-
VOLUME /var/lib/postgresql/data
65+
66+
# --- Volumes (Injected by Generator) ---
67+
VOLUME /var/lib/postgresql/data

Containerfile.j2

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
ARG BASE_VERSION=15
2+
ARG PG_VERSION=17
3+
FROM ghcr.io/daemonless/base:${BASE_VERSION}
4+
ARG PG_VERSION
5+
6+
ARG FREEBSD_ARCH=amd64
7+
ARG PACKAGES="postgresql${PG_VERSION}-server postgresql${PG_VERSION}-client postgresql${PG_VERSION}-contrib"
8+
ARG UPSTREAM_URL="https://www.postgresql.org/docs/release/"
9+
ARG HEALTHCHECK_ENDPOINT="pg_isready -q"
10+
11+
ENV HEALTHCHECK_URL="${HEALTHCHECK_ENDPOINT}"
12+
13+
# --- Metadata (Injected by Generator) ---
14+
LABEL org.opencontainers.image.title="{{ title }} ${PG_VERSION}" \
15+
org.opencontainers.image.description="{{ description }}" \
16+
org.opencontainers.image.source="{{ repo_url }}" \
17+
org.opencontainers.image.url="{{ web_url }}" \
18+
org.opencontainers.image.documentation="https://www.postgresql.org/docs/${PG_VERSION}/" \
19+
org.opencontainers.image.licenses="PostgreSQL" \
20+
org.opencontainers.image.vendor="daemonless" \
21+
org.opencontainers.image.authors="daemonless" \
22+
io.daemonless.category="{{ category }}" \
23+
{%- if ports %}
24+
io.daemonless.port="{{ ports[0].port }}" \
25+
{%- endif %}
26+
{%- if volumes %}
27+
io.daemonless.volumes="{{ volumes | map(attribute='path') | join(',') }}" \
28+
{%- endif %}
29+
{%- if mlock %}
30+
org.freebsd.jail.allow.mlock="required" \
31+
{%- endif %}
32+
org.freebsd.jail.allow.sysvipc="required" \
33+
io.daemonless.arch="${FREEBSD_ARCH}" \
34+
io.daemonless.pkg-source="containerfile" \
35+
io.daemonless.upstream-url="${UPSTREAM_URL}" \
36+
io.daemonless.packages="${PACKAGES}"
37+
38+
# Install PostgreSQL
39+
RUN pkg update && \
40+
pkg install -y ${PACKAGES} && \
41+
pkg clean -ay && \
42+
rm -rf /var/cache/pkg/* /var/db/pkg/repos/*
43+
44+
# Create directories (use Linux-compatible paths for drop-in replacement)
45+
RUN mkdir -p /var/lib/postgresql/data /var/run/postgresql /run/secrets /docker-entrypoint-initdb.d && \
46+
chmod 755 /var/lib && \
47+
chown -R bsd:bsd /var/lib/postgresql /var/run/postgresql /run/secrets /docker-entrypoint-initdb.d
48+
49+
# Copy service definitions and init scripts
50+
COPY root/ /
51+
52+
# Make scripts executable
53+
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* /healthz 2>/dev/null || true
54+
55+
# Store PG version for scripts
56+
RUN mkdir -p /var/db/postgres && echo "${PG_VERSION}" > /var/db/postgres/pg_version
57+
58+
# Extract package version for tagging (e.g., 17.7 or 14.20)
59+
RUN mkdir -p /app && \
60+
pkg query '%v' postgresql${PG_VERSION}-server | sed 's/_.*$//' > /app/version
61+
62+
ENV PGDATA="/var/lib/postgresql/data" \
63+
PG_VERSION="${PG_VERSION}" \
64+
POSTGRES_USER="postgres" \
65+
POSTGRES_PASSWORD="" \
66+
POSTGRES_DB="postgres" \
67+
POSTGRES_INITDB_ARGS="" \
68+
POSTGRES_HOST_AUTH_METHOD="scram-sha-256"
69+
70+
# --- Expose (Injected by Generator) ---
71+
{%- if ports %}
72+
EXPOSE {{ ports | map(attribute='port') | join(' ') }}
73+
{%- endif %}
74+
75+
# --- Volumes (Injected by Generator) ---
76+
{%- if volumes %}
77+
VOLUME {{ volumes | map(attribute='path') | join(' ') }}
78+
{%- endif %}

README.md

Lines changed: 68 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,101 @@
11
# PostgreSQL
22

3-
PostgreSQL database server on FreeBSD. **Drop-in replacement** for the official `postgres` Docker image.
3+
The World's Most Advanced Open Source Relational Database on FreeBSD.
44

5-
> **Requires [patched ocijail](https://github.com/daemonless/daemonless#ocijail-patch)** for SysV IPC support (`org.freebsd.jail.allow.sysvipc=true`)
5+
| | |
6+
|---|---|
7+
| **Port** | 5432 |
8+
| **Registry** | `ghcr.io/daemonless/postgres` |
9+
| **Source** | [https://www.postgresql.org/](https://www.postgresql.org/) |
10+
| **Website** | [https://www.postgresql.org/](https://www.postgresql.org/) |
611

7-
## Quick Start
12+
## Deployment
813

9-
```bash
10-
podman run -d --name postgres \
11-
-p 5432:5432 \
12-
-e POSTGRES_PASSWORD=mysecretpassword \
13-
-v /path/to/data:/var/lib/postgresql/data \
14-
--annotation 'org.freebsd.jail.allow.sysvipc=true' \
15-
ghcr.io/daemonless/postgres:17
16-
```
17-
18-
## podman-compose
14+
### Podman Compose
1915

2016
```yaml
2117
services:
2218
postgres:
23-
image: ghcr.io/daemonless/postgres:17
19+
image: ghcr.io/daemonless/postgres:latest
2420
container_name: postgres
2521
environment:
2622
- POSTGRES_USER=postgres
27-
- POSTGRES_PASSWORD=mysecretpassword
28-
- POSTGRES_DB=mydb
23+
- POSTGRES_PASSWORD=postgres
24+
- POSTGRES_DB=postgres
25+
- PUID=1000
26+
- PGID=1000
27+
- TZ=UTC
2928
volumes:
30-
- /data/postgres:/var/lib/postgresql/data
29+
- /path/to/containers/postgres/var/lib/postgresql/data:/var/lib/postgresql/data
3130
ports:
3231
- 5432:5432
33-
annotations:
34-
org.freebsd.jail.allow.sysvipc: "true"
3532
restart: unless-stopped
3633
```
3734
38-
## Tags
39-
40-
| Tag | Base | Description |
41-
|-----|------|-------------|
42-
| `:17` | quarterly | PostgreSQL 17 |
43-
| `:17-pkg` | quarterly | Alias for `:17` |
44-
| `:17-pkg-latest` | latest | PostgreSQL 17 (latest packages) |
45-
| `:14` | quarterly | PostgreSQL 14 |
46-
| `:14-pkg` | quarterly | Alias for `:14` |
47-
| `:14-pkg-latest` | latest | PostgreSQL 14 (latest packages) |
48-
| `:latest` | quarterly | Alias for `:17` |
49-
| `:pkg` | quarterly | Alias for `:17` |
50-
| `:pkg-latest` | latest | Alias for `:17-pkg-latest` |
35+
### Podman CLI
5136
52-
## Environment Variables
53-
54-
| Variable | Default | Description |
55-
|----------|---------|-------------|
56-
| `POSTGRES_USER` | `postgres` | Database superuser name |
57-
| `POSTGRES_PASSWORD` | (empty) | Superuser password |
58-
| `POSTGRES_DB` | `postgres` | Default database name |
59-
| `PGDATA` | `/var/lib/postgresql/data` | Data directory |
60-
| `POSTGRES_INITDB_ARGS` | (empty) | Extra args for initdb (e.g., `--data-checksums`) |
61-
| `POSTGRES_HOST_AUTH_METHOD` | `scram-sha-256` | Auth method (`scram-sha-256`, `md5`, `trust`) |
62-
63-
### Docker Secrets
64-
65-
Secrets can be passed via `*_FILE` environment variables:
37+
```bash
38+
podman run -d --name postgres \
39+
-p 5432:5432 \
40+
-e POSTGRES_USER=postgres \
41+
-e POSTGRES_PASSWORD=postgres \
42+
-e POSTGRES_DB=postgres \
43+
-e PUID=@PUID@ \
44+
-e PGID=@PGID@ \
45+
-e TZ=@TZ@ \
46+
-v /path/to/containers/postgres/var/lib/postgresql/data:/var/lib/postgresql/data \
47+
ghcr.io/daemonless/postgres:latest
48+
```
49+
Access at: `http://localhost:5432`
6650

67-
| Variable | Description |
68-
|----------|-------------|
69-
| `POSTGRES_PASSWORD_FILE` | Path to file containing password |
51+
### Ansible
7052

71-
## Initialization Scripts
53+
```yaml
54+
- name: Deploy postgres
55+
containers.podman.podman_container:
56+
name: postgres
57+
image: ghcr.io/daemonless/postgres:latest
58+
state: started
59+
restart_policy: always
60+
env:
61+
POSTGRES_USER: "postgres"
62+
POSTGRES_PASSWORD: "postgres"
63+
POSTGRES_DB: "postgres"
64+
PUID: "1000"
65+
PGID: "1000"
66+
TZ: "UTC"
67+
ports:
68+
- "5432:5432"
69+
volumes:
70+
- "/path/to/containers/postgres/var/lib/postgresql/data:/var/lib/postgresql/data"
71+
```
7272
73-
Place scripts in `/docker-entrypoint-initdb.d/` to run on first startup:
73+
## Configuration
7474
75-
| Extension | Behavior |
76-
|-----------|----------|
77-
| `*.sh` | Executed if executable, sourced otherwise |
78-
| `*.sql` | Run via psql against `$POSTGRES_DB` |
79-
| `*.sql.gz` | Decompressed and run via psql |
75+
### Environment Variables
8076
81-
Scripts run in sorted filename order after database creation.
77+
| Variable | Default | Description |
78+
|----------|---------|-------------|
79+
| `POSTGRES_USER` | `postgres` | Database superuser name (default: postgres) |
80+
| `POSTGRES_PASSWORD` | `postgres` | Database superuser password |
81+
| `POSTGRES_DB` | `postgres` | Default database to create (default: same as user) |
82+
| `PUID` | `1000` | |
83+
| `PGID` | `1000` | |
84+
| `TZ` | `UTC` | |
8285

83-
## Volumes
86+
### Volumes
8487

8588
| Path | Description |
8689
|------|-------------|
87-
| `/var/lib/postgresql/data` | PostgreSQL data directory |
90+
| `/var/lib/postgresql/data` | Database data directory |
8891

89-
## Ports
92+
### Ports
9093

91-
| Port | Description |
92-
|------|-------------|
93-
| 5432 | PostgreSQL |
94+
| Port | Protocol | Description |
95+
|------|----------|-------------|
96+
| `5432` | TCP | PostgreSQL port |
9497

9598
## Notes
9699

97-
- **User:** `bsd` (UID/GID 1000)
98-
99-
## Migrating from Linux
100-
101-
**You cannot copy a Linux postgres data directory directly to FreeBSD.** PostgreSQL stores locale information (`en_US.utf8`) in the database cluster, and FreeBSD uses a different locale format (`en_US.UTF-8`). Attempting to use copied data will fail with:
102-
103-
```
104-
FATAL: database locale is incompatible with operating system
105-
DETAIL: The database was initialized with LC_COLLATE "en_US.utf8", which is not recognized by setlocale().
106-
```
107-
108-
### Migration Steps
109-
110-
1. **Dump from Linux** (while postgres is running):
111-
```bash
112-
podman exec postgres pg_dump -U myuser mydb > mydb.sql
113-
```
114-
115-
2. **Start fresh FreeBSD postgres**:
116-
```bash
117-
podman run -d --name postgres \
118-
-e POSTGRES_USER=myuser \
119-
-e POSTGRES_PASSWORD=mypassword \
120-
-e POSTGRES_DB=mydb \
121-
-v /containers/myapp/pgdata:/var/lib/postgresql/data \
122-
--annotation 'org.freebsd.jail.allow.sysvipc=true' \
123-
ghcr.io/daemonless/postgres:17
124-
```
125-
126-
3. **Restore the dump**:
127-
```bash
128-
cat mydb.sql | podman exec -i postgres psql -U myuser -d mydb
129-
```
130-
131-
### Full Database Cluster Migration
132-
133-
To migrate all databases and roles:
134-
135-
```bash
136-
# On source (Linux or FreeBSD)
137-
podman exec postgres pg_dumpall -U postgres > all_databases.sql
138-
139-
# On target (after starting fresh postgres)
140-
cat all_databases.sql | podman exec -i postgres psql -U postgres
141-
```
142-
143-
## Migrating from FreeBSD to Linux
144-
145-
The same locale incompatibility applies in reverse. FreeBSD uses `C` or `en_US.UTF-8` locales, which Linux postgres may not recognize. Use pg_dump/restore:
146-
147-
```bash
148-
# On FreeBSD
149-
podman exec postgres pg_dump -U myuser mydb > mydb.sql
150-
151-
# On Linux (after starting fresh postgres)
152-
cat mydb.sql | podman exec -i postgres psql -U myuser -d mydb
153-
```
154-
155-
**Bottom line:** Always use `pg_dump`/`pg_restore` when moving postgres data between Linux and FreeBSD, regardless of direction.
156-
157-
## Links
158-
159-
- [PostgreSQL Website](https://www.postgresql.org/)
160-
- [FreshPorts postgresql17-server](https://www.freshports.org/databases/postgresql17-server/)
161-
- [FreshPorts postgresql14-server](https://www.freshports.org/databases/postgresql14-server/)
100+
- **User:** `bsd` (UID/GID set via PUID/PGID)
101+
- **Base:** Built on `ghcr.io/daemonless/base` (FreeBSD)

0 commit comments

Comments
 (0)