Skip to content

Commit ec3d614

Browse files
committed
first commit
0 parents  commit ec3d614

7 files changed

Lines changed: 326 additions & 0 deletions

File tree

.daemonless.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
icon: ':material-database:'

.github/workflows/build.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Build PostgreSQL Container
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths-ignore: ['*.md', 'LICENSE', '.gitignore']
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
jobs:
12+
build:
13+
strategy:
14+
matrix:
15+
pg_version: [14, 17]
16+
uses: daemonless/daemonless/.github/workflows/build-app.yml@main
17+
with:
18+
image_name: postgres
19+
image_tag: ${{ matrix.pg_version }}
20+
build_args: PG_VERSION=${{ matrix.pg_version }}
21+
secrets: inherit

.woodpecker.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Woodpecker CI configuration for PostgreSQL
2+
3+
steps:
4+
- name: build-14
5+
image: /bin/sh
6+
environment:
7+
GITHUB_TOKEN:
8+
from_secret: GITHUB_TOKEN
9+
GITHUB_ACTOR:
10+
from_secret: GITHUB_USER
11+
commands:
12+
- |
13+
mkdir -p scripts
14+
fetch -qo scripts/build.sh \
15+
"https://raw.githubusercontent.com/daemonless/daemonless/build-v1.2.0/scripts/build.sh"
16+
chmod +x scripts/build.sh
17+
./scripts/build.sh \
18+
--doas \
19+
--registry ghcr.io \
20+
--image ghcr.io/daemonless/postgres \
21+
--tag 14 \
22+
--build-arg PG_VERSION=14 \
23+
--skip-wip \
24+
--login --push
25+
26+
- name: build-17
27+
image: /bin/sh
28+
environment:
29+
GITHUB_TOKEN:
30+
from_secret: GITHUB_TOKEN
31+
GITHUB_ACTOR:
32+
from_secret: GITHUB_USER
33+
commands:
34+
- |
35+
mkdir -p scripts
36+
fetch -qo scripts/build.sh \
37+
"https://raw.githubusercontent.com/daemonless/daemonless/build-v1.2.0/scripts/build.sh"
38+
chmod +x scripts/build.sh
39+
./scripts/build.sh \
40+
--doas \
41+
--registry ghcr.io \
42+
--image ghcr.io/daemonless/postgres \
43+
--tag 17 \
44+
--tag latest \
45+
--build-arg PG_VERSION=17 \
46+
--skip-wip \
47+
--login --push
48+
49+
when:
50+
- event: push
51+
branch: main
52+
path:
53+
exclude: ["*.md", "docs/**", "LICENSE", ".gitignore"]
54+
- event: manual

Containerfile

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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"
8+
ARG UPSTREAM_URL="https://www.postgresql.org/docs/release/"
9+
ARG HEALTHCHECK_ENDPOINT="pg_isready -q"
10+
11+
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+
25+
# Install PostgreSQL
26+
RUN pkg update && \
27+
pkg install -y ${PACKAGES} && \
28+
pkg clean -ay && \
29+
rm -rf /var/cache/pkg/* /var/db/pkg/repos/*
30+
31+
# Create directories
32+
RUN mkdir -p /var/db/postgres/data${PG_VERSION} /var/run/postgresql /run/secrets /docker-entrypoint-initdb.d && \
33+
chown -R bsd:bsd /var/db/postgres /var/run/postgresql /run/secrets /docker-entrypoint-initdb.d
34+
35+
# Copy service definitions and init scripts
36+
COPY root/ /
37+
38+
# Make scripts executable
39+
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* 2>/dev/null || true
40+
41+
# Store PG version for scripts
42+
RUN echo "${PG_VERSION}" > /var/db/postgres/pg_version
43+
44+
ENV PGDATA="/var/db/postgres/data${PG_VERSION}" \
45+
PG_VERSION="${PG_VERSION}" \
46+
POSTGRES_USER="postgres" \
47+
POSTGRES_PASSWORD="" \
48+
POSTGRES_DB="postgres" \
49+
POSTGRES_INITDB_ARGS="" \
50+
POSTGRES_HOST_AUTH_METHOD="scram-sha-256"
51+
52+
EXPOSE 5432
53+
VOLUME /var/db/postgres

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# PostgreSQL
2+
3+
PostgreSQL database server on FreeBSD.
4+
5+
## Quick Start
6+
7+
```bash
8+
podman run -d --name postgres \
9+
-p 5432:5432 \
10+
-e POSTGRES_PASSWORD=mysecretpassword \
11+
-v /path/to/data:/var/db/postgres \
12+
--annotation 'org.freebsd.jail.allow.sysvipc=true' \
13+
ghcr.io/daemonless/postgres:17
14+
```
15+
16+
## podman-compose
17+
18+
```yaml
19+
services:
20+
postgres:
21+
image: ghcr.io/daemonless/postgres:17
22+
container_name: postgres
23+
environment:
24+
- POSTGRES_USER=postgres
25+
- POSTGRES_PASSWORD=mysecretpassword
26+
- POSTGRES_DB=mydb
27+
volumes:
28+
- /data/postgres:/var/db/postgres
29+
ports:
30+
- 5432:5432
31+
annotations:
32+
org.freebsd.jail.allow.sysvipc: "true"
33+
restart: unless-stopped
34+
```
35+
36+
## Tags
37+
38+
| Tag | Description |
39+
|-----|-------------|
40+
| `:17` | PostgreSQL 17 (latest) |
41+
| `:14` | PostgreSQL 14 |
42+
| `:latest` | Alias for `:17` |
43+
44+
## Environment Variables
45+
46+
| Variable | Default | Description |
47+
|----------|---------|-------------|
48+
| `POSTGRES_USER` | `postgres` | Database superuser name |
49+
| `POSTGRES_PASSWORD` | (empty) | Superuser password |
50+
| `POSTGRES_DB` | `postgres` | Default database name |
51+
| `PGDATA` | `/var/db/postgres/dataXX` | Data directory (XX = version) |
52+
| `POSTGRES_INITDB_ARGS` | (empty) | Extra args for initdb (e.g., `--data-checksums`) |
53+
| `POSTGRES_HOST_AUTH_METHOD` | `scram-sha-256` | Auth method (`scram-sha-256`, `md5`, `trust`) |
54+
55+
### Docker Secrets
56+
57+
Secrets can be passed via `*_FILE` environment variables:
58+
59+
| Variable | Description |
60+
|----------|-------------|
61+
| `POSTGRES_PASSWORD_FILE` | Path to file containing password |
62+
63+
## Initialization Scripts
64+
65+
Place scripts in `/docker-entrypoint-initdb.d/` to run on first startup:
66+
67+
| Extension | Behavior |
68+
|-----------|----------|
69+
| `*.sh` | Executed if executable, sourced otherwise |
70+
| `*.sql` | Run via psql against `$POSTGRES_DB` |
71+
| `*.sql.gz` | Decompressed and run via psql |
72+
73+
Scripts run in sorted filename order after database creation.
74+
75+
## Volumes
76+
77+
| Path | Description |
78+
|------|-------------|
79+
| `/var/db/postgres` | PostgreSQL data directory |
80+
81+
## Ports
82+
83+
| Port | Description |
84+
|------|-------------|
85+
| 5432 | PostgreSQL |
86+
87+
## Notes
88+
89+
- **User:** `bsd` (UID/GID 1000)
90+
- **SysV IPC:** Requires `--annotation 'org.freebsd.jail.allow.sysvipc=true'`
91+
92+
## Links
93+
94+
- [PostgreSQL Website](https://www.postgresql.org/)
95+
- [FreshPorts postgresql17-server](https://www.freshports.org/databases/postgresql17-server/)
96+
- [FreshPorts postgresql14-server](https://www.freshports.org/databases/postgresql14-server/)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/sh
2+
# PostgreSQL configuration setup
3+
4+
# Load secrets from *_FILE environment variables (Docker secrets pattern)
5+
for var in $(env | grep '_FILE=' | cut -d= -f1); do
6+
base_var="${var%_FILE}"
7+
file_path="$(eval echo \"\$$var\")"
8+
if [ -f "$file_path" ]; then
9+
value="$(cat "$file_path")"
10+
export "$base_var"="$value"
11+
echo "Loaded secret for $base_var from $file_path"
12+
else
13+
echo "Warning: Secret file $file_path not found for $var"
14+
fi
15+
done
16+
17+
PG_VERSION=$(cat /var/db/postgres/pg_version 2>/dev/null || echo "17")
18+
PGDATA="/var/db/postgres/data${PG_VERSION}"
19+
20+
echo "Setting up PostgreSQL ${PG_VERSION}..."
21+
22+
# Create required directories
23+
mkdir -p "$PGDATA" /var/run/postgresql
24+
25+
# Set ownership (bsd:bsd is UID/GID 1000:1000)
26+
chown -R bsd:bsd /var/db/postgres /var/run/postgresql
27+
28+
echo "PostgreSQL configuration complete"

root/etc/services.d/postgresql/run

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/sh
2+
# PostgreSQL s6 service
3+
4+
PG_VERSION=$(cat /var/db/postgres/pg_version 2>/dev/null || echo "17")
5+
PGDATA="/var/db/postgres/data${PG_VERSION}"
6+
7+
# Initialize database if needed
8+
if [ ! -f "$PGDATA/PG_VERSION" ]; then
9+
echo "Initializing PostgreSQL ${PG_VERSION} database..."
10+
11+
# Build initdb command with optional args
12+
INITDB_CMD="/usr/local/bin/initdb -D $PGDATA -E UTF8 --locale=C"
13+
if [ -n "$POSTGRES_INITDB_ARGS" ]; then
14+
INITDB_CMD="$INITDB_CMD $POSTGRES_INITDB_ARGS"
15+
fi
16+
/usr/local/bin/s6-setuidgid bsd sh -c "$INITDB_CMD"
17+
18+
# Configure authentication method (default: scram-sha-256)
19+
AUTH_METHOD="${POSTGRES_HOST_AUTH_METHOD:-scram-sha-256}"
20+
echo "host all all 0.0.0.0/0 $AUTH_METHOD" >> "$PGDATA/pg_hba.conf"
21+
echo "host all all ::/0 $AUTH_METHOD" >> "$PGDATA/pg_hba.conf"
22+
echo "local all all trust" >> "$PGDATA/pg_hba.conf"
23+
24+
# Listen on all interfaces
25+
echo "listen_addresses = '*'" >> "$PGDATA/postgresql.conf"
26+
27+
# Start temporarily to create user/database and run init scripts
28+
/usr/local/bin/s6-setuidgid bsd /usr/local/bin/pg_ctl -D "$PGDATA" -w start
29+
30+
# Create user and database if specified
31+
if [ -n "$POSTGRES_PASSWORD" ]; then
32+
/usr/local/bin/s6-setuidgid bsd /usr/local/bin/psql -c "ALTER USER $POSTGRES_USER PASSWORD '$POSTGRES_PASSWORD'" 2>/dev/null
33+
fi
34+
35+
if [ -n "$POSTGRES_DB" ] && [ "$POSTGRES_DB" != "postgres" ]; then
36+
/usr/local/bin/s6-setuidgid bsd /usr/local/bin/createdb "$POSTGRES_DB" 2>/dev/null
37+
fi
38+
39+
# Run init scripts from /docker-entrypoint-initdb.d/
40+
if [ -d /docker-entrypoint-initdb.d ]; then
41+
for f in /docker-entrypoint-initdb.d/*; do
42+
[ -e "$f" ] || continue
43+
case "$f" in
44+
*.sh)
45+
if [ -x "$f" ]; then
46+
echo "Running $f"
47+
"$f"
48+
else
49+
echo "Sourcing $f"
50+
. "$f"
51+
fi
52+
;;
53+
*.sql)
54+
echo "Running $f"
55+
/usr/local/bin/s6-setuidgid bsd /usr/local/bin/psql -d "${POSTGRES_DB:-postgres}" -f "$f"
56+
;;
57+
*.sql.gz)
58+
echo "Running $f"
59+
gunzip -c "$f" | /usr/local/bin/s6-setuidgid bsd /usr/local/bin/psql -d "${POSTGRES_DB:-postgres}"
60+
;;
61+
*)
62+
echo "Ignoring $f"
63+
;;
64+
esac
65+
done
66+
fi
67+
68+
# Stop PostgreSQL (s6 will start it properly)
69+
/usr/local/bin/s6-setuidgid bsd /usr/local/bin/pg_ctl -D "$PGDATA" -w stop
70+
fi
71+
72+
echo "Starting PostgreSQL ${PG_VERSION}..."
73+
exec /usr/local/bin/s6-setuidgid bsd /usr/local/bin/postgres -D "$PGDATA"

0 commit comments

Comments
 (0)