Skip to content

Commit 9ae827d

Browse files
acvigueclaude
andcommitted
Initial commit: PostgreSQL 18 slim Docker image
Alpine-based minimal PostgreSQL 18 image with multi-arch support. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
0 parents  commit 9ae827d

4 files changed

Lines changed: 173 additions & 0 deletions

File tree

.github/workflows/docker_image.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Docker Build
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
build:
10+
uses: acvigue/.github/.github/workflows/docker_build.yml@main

Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
FROM alpine:3.23
2+
3+
ENV LANG=en_US.UTF-8 \
4+
PG_MAJOR=18 \
5+
PGDATA=/var/lib/postgresql/data
6+
7+
RUN set -eux; \
8+
addgroup -g 70 -S postgres; \
9+
adduser -u 70 -S -D -G postgres -H -h /var/lib/postgresql -s /bin/sh postgres; \
10+
mkdir -p /var/lib/postgresql; \
11+
chown -R postgres:postgres /var/lib/postgresql
12+
13+
RUN set -eux; \
14+
apk add --no-cache \
15+
postgresql${PG_MAJOR} \
16+
postgresql${PG_MAJOR}-client \
17+
su-exec \
18+
tzdata \
19+
; \
20+
# Remove unnecessary files
21+
rm -rf \
22+
/usr/share/doc \
23+
/usr/share/man \
24+
/var/cache/apk/* \
25+
; \
26+
# Verify installation
27+
postgres --version
28+
29+
# Create required directories
30+
RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgresql && chmod 3777 /var/run/postgresql \
31+
&& mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 1777 "$PGDATA"
32+
33+
COPY docker-entrypoint.sh /usr/local/bin/
34+
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
35+
36+
STOPSIGNAL SIGINT
37+
EXPOSE 5432
38+
39+
ENTRYPOINT ["docker-entrypoint.sh"]
40+
CMD ["postgres"]

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# PostgreSQL 18 Slim (Alpine)
2+
3+
Minimal PostgreSQL 18 image for arm64/amd64. ~50MB uncompressed vs ~250MB official.
4+
5+
## Build
6+
7+
```bash
8+
# Single arch
9+
docker build -t postgres:18-slim .
10+
11+
# Multi-arch
12+
docker buildx build --platform linux/amd64,linux/arm64 -t yourrepo/postgres:18-slim --push .
13+
```
14+
15+
## Usage
16+
17+
```bash
18+
# Basic
19+
docker run -d \
20+
-e POSTGRES_PASSWORD=secret \
21+
-v pgdata:/var/lib/postgresql/data \
22+
postgres:18-slim
23+
24+
# With custom db/user
25+
docker run -d \
26+
-e POSTGRES_PASSWORD=secret \
27+
-e POSTGRES_USER=myuser \
28+
-e POSTGRES_DB=mydb \
29+
-v pgdata:/var/lib/postgresql/data \
30+
postgres:18-slim
31+
32+
# Dev mode (no password)
33+
docker run -d \
34+
-e POSTGRES_HOST_AUTH_METHOD=trust \
35+
postgres:18-slim
36+
```
37+
38+
## Environment Variables
39+
40+
| Variable | Default | Description |
41+
| --------------------------- | -------------------------- | ------------------------------------------ |
42+
| `POSTGRES_PASSWORD` | - | Superuser password (required unless trust) |
43+
| `POSTGRES_USER` | `postgres` | Superuser name |
44+
| `POSTGRES_DB` | `$POSTGRES_USER` | Default database |
45+
| `POSTGRES_HOST_AUTH_METHOD` | - | Set to `trust` for no password |
46+
| `PGDATA` | `/var/lib/postgresql/data` | Data directory |
47+
48+
## Init Scripts
49+
50+
Mount `.sh` or `.sql` files to `/docker-entrypoint-initdb.d/` for first-run initialization.
51+
52+
## What's Removed vs Official
53+
54+
- Locale generation (uses C.UTF-8)
55+
- gosu → su-exec (smaller)
56+
- Extensive bash scripting → sh
57+
- Doc/man pages
58+
- Contrib modules (add if needed: `postgresql18-contrib`)

docker-entrypoint.sh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/sh
2+
set -e
3+
4+
# Run as postgres user if started as root
5+
if [ "$(id -u)" = '0' ]; then
6+
exec su-exec postgres "$0" "$@"
7+
fi
8+
9+
# Initialize database if PGDATA is empty
10+
if [ "$1" = 'postgres' ] && [ -z "$(ls -A "$PGDATA" 2>/dev/null)" ]; then
11+
# Set password file for initdb
12+
if [ -n "$POSTGRES_PASSWORD" ]; then
13+
PWFILE=$(mktemp)
14+
printf '%s' "$POSTGRES_PASSWORD" > "$PWFILE"
15+
INITDB_OPTS="--pwfile=$PWFILE"
16+
AUTH_METHOD="scram-sha-256"
17+
elif [ "${POSTGRES_HOST_AUTH_METHOD:-}" = 'trust' ]; then
18+
AUTH_METHOD="trust"
19+
INITDB_OPTS=""
20+
else
21+
echo "Error: POSTGRES_PASSWORD must be set or POSTGRES_HOST_AUTH_METHOD=trust" >&2
22+
exit 1
23+
fi
24+
25+
initdb \
26+
--username="${POSTGRES_USER:-postgres}" \
27+
--auth-host="$AUTH_METHOD" \
28+
--auth-local="$AUTH_METHOD" \
29+
$INITDB_OPTS \
30+
"$PGDATA"
31+
32+
[ -n "${PWFILE:-}" ] && rm -f "$PWFILE"
33+
34+
# Configure listening
35+
echo "listen_addresses = '*'" >> "$PGDATA/postgresql.conf"
36+
37+
# Allow connections from anywhere (container networking)
38+
echo "host all all all $AUTH_METHOD" >> "$PGDATA/pg_hba.conf"
39+
40+
# Create additional user/database if specified
41+
if [ -n "$POSTGRES_DB" ] || [ -n "$POSTGRES_USER" ]; then
42+
pg_ctl -D "$PGDATA" -o "-c listen_addresses=''" -w start
43+
44+
if [ "$POSTGRES_DB" != 'postgres' ] && [ -n "$POSTGRES_DB" ]; then
45+
psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER:-postgres}" <<-EOSQL
46+
CREATE DATABASE "$POSTGRES_DB";
47+
EOSQL
48+
fi
49+
50+
# Run init scripts if present
51+
for f in /docker-entrypoint-initdb.d/*; do
52+
case "$f" in
53+
*.sh) echo "Running $f"; . "$f" ;;
54+
*.sql) echo "Running $f"; psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER:-postgres}" -f "$f" ;;
55+
*) echo "Ignoring $f" ;;
56+
esac
57+
done 2>/dev/null || true
58+
59+
pg_ctl -D "$PGDATA" -m fast -w stop
60+
fi
61+
62+
echo "PostgreSQL init complete; ready for start up."
63+
fi
64+
65+
exec "$@"

0 commit comments

Comments
 (0)