psql access
This commit is contained in:
@ -17,6 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libffi-dev \
|
libffi-dev \
|
||||||
libyaml-dev \
|
libyaml-dev \
|
||||||
libpq-dev \
|
libpq-dev \
|
||||||
|
socat \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# --- rbenv (installed into home volume on first run, via entrypoint) ---
|
# --- rbenv (installed into home volume on first run, via entrypoint) ---
|
||||||
|
|||||||
81
README.md
81
README.md
@ -56,7 +56,7 @@ claude doctor # diagnose installation issues
|
|||||||
## Volumes
|
## Volumes
|
||||||
|
|
||||||
| Volume | Purpose |
|
| Volume | Purpose |
|
||||||
|---|---|
|
| --------------------- | --------------------------------------------------------- |
|
||||||
| `claude-home` (named) | Persists Claude Code binary, config, and auth credentials |
|
| `claude-home` (named) | Persists Claude Code binary, config, and auth credentials |
|
||||||
| `$PROJECT_DIR` (bind) | Your project code — swap freely between sessions |
|
| `$PROJECT_DIR` (bind) | Your project code — swap freely between sessions |
|
||||||
|
|
||||||
@ -68,9 +68,84 @@ docker compose down -v # removes the claude-home volume
|
|||||||
|
|
||||||
## Security notes
|
## Security notes
|
||||||
|
|
||||||
- Runs as a non-root user (`coder`, uid 1000)
|
- Runs as a non-root user (`coder`, uid 1001)
|
||||||
- All Linux capabilities are dropped (`cap_drop: ALL`)
|
- All Linux capabilities are dropped except `NET_BIND_SERVICE`
|
||||||
- Privilege escalation is disabled (`no-new-privileges`)
|
- Privilege escalation is disabled (`no-new-privileges`)
|
||||||
- The container has no network restrictions beyond what Docker provides —
|
- The container has no network restrictions beyond what Docker provides —
|
||||||
add a custom network or `--network none` with `--add-host` if you want
|
add a custom network or `--network none` with `--add-host` if you want
|
||||||
to lock that down further
|
to lock that down further
|
||||||
|
|
||||||
|
## Connecting to a host PostgreSQL database
|
||||||
|
|
||||||
|
The container can reach a PostgreSQL server running on the host, but
|
||||||
|
`127.0.0.1` inside the container refers to the container itself, not the
|
||||||
|
host. The solution is to connect via the Docker bridge gateway IP instead,
|
||||||
|
which both the host and the container can see.
|
||||||
|
|
||||||
|
### 1. Find the gateway IP
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network inspect bridge | grep Gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
This is typically `172.17.0.1`. Use the value specific to your machine
|
||||||
|
in all steps below.
|
||||||
|
|
||||||
|
### 2. Configure PostgreSQL on the host
|
||||||
|
|
||||||
|
Edit `/etc/postgresql/<version>/main/postgresql.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
listen_addresses = 'localhost,172.17.0.1'
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `/etc/postgresql/<version>/main/pg_hba.conf` and add:
|
||||||
|
|
||||||
|
```
|
||||||
|
host all all 172.17.0.0/16 scram-sha-256
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart PostgreSQL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart postgresql
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure your app
|
||||||
|
|
||||||
|
Use the gateway IP as the database host. Since it is reachable from both
|
||||||
|
the host and the container, a single `DATABASE_URL` works in both contexts:
|
||||||
|
|
||||||
|
```
|
||||||
|
DATABASE_URL=postgresql://user:password@172.17.0.1:5432/mydb
|
||||||
|
```
|
||||||
|
|
||||||
|
Set this in your `.env` file or shell profile on the host, and pass it
|
||||||
|
through in `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Collation version warning
|
||||||
|
|
||||||
|
If you see a warning like:
|
||||||
|
|
||||||
|
```
|
||||||
|
WARNING: database "mydb" has a collation version mismatch
|
||||||
|
DETAIL: The database was created using collation version 2.41, but the
|
||||||
|
operating system provides version 2.42.
|
||||||
|
```
|
||||||
|
|
||||||
|
This is caused by the container's glibc version differing from the host's.
|
||||||
|
It is a warning only and will not break anything. To silence it, run once
|
||||||
|
on the host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -d mydb -c "ALTER DATABASE mydb REFRESH COLLATION VERSION;"
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: the warning will reappear inside the container because its glibc
|
||||||
|
version differs from the host. The long-term fix is to rebase the Docker
|
||||||
|
image on the same Ubuntu release as the host so glibc versions match.
|
||||||
|
|||||||
@ -4,11 +4,6 @@ services:
|
|||||||
image: claude-code:local
|
image: claude-code:local
|
||||||
container_name: claude-code
|
container_name: claude-code
|
||||||
|
|
||||||
# Pass your Anthropic API key in from the host environment,
|
|
||||||
# or drop it into a .env file alongside this compose file.
|
|
||||||
# environment:
|
|
||||||
# - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?Set ANTHROPIC_API_KEY in your environment or .env file}
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# Fixed home volume — persists Claude Code install, config, and credentials
|
# Fixed home volume — persists Claude Code install, config, and credentials
|
||||||
# across container restarts and image rebuilds.
|
# across container restarts and image rebuilds.
|
||||||
@ -18,13 +13,21 @@ services:
|
|||||||
# PROJECT_DIR=/path/to/myproject docker compose run --rm claude-code
|
# PROJECT_DIR=/path/to/myproject docker compose run --rm claude-code
|
||||||
- ${PROJECT_DIR:-./code}:/code
|
- ${PROJECT_DIR:-./code}:/code
|
||||||
|
|
||||||
# Drop all Linux capabilities and disable privilege escalation —
|
# Drop all Linux capabilities except NET_BIND_SERVICE, which socat needs
|
||||||
# Claude Code doesn't need any of them.
|
# to proxy port 5432 on 127.0.0.1 inside the container.
|
||||||
cap_drop:
|
cap_drop:
|
||||||
- ALL
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
security_opt:
|
security_opt:
|
||||||
- no-new-privileges:true
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
# Allow the container to reach the host's network (e.g. a local postgres).
|
||||||
|
# On Linux, host.docker.internal isn't automatic — this creates it.
|
||||||
|
# On Mac/Windows Docker Desktop it's already available but this is harmless.
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
|
||||||
# Interactive terminal so `claude` works properly
|
# Interactive terminal so `claude` works properly
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: true
|
tty: true
|
||||||
|
|||||||
@ -39,4 +39,12 @@ else
|
|||||||
echo "Claude Code $(claude --version 2>/dev/null || echo '(version unknown)') ready."
|
echo "Claude Code $(claude --version 2>/dev/null || echo '(version unknown)') ready."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Proxy host postgres to 127.0.0.1:5432 inside the container so the app can
|
||||||
|
# use the same DATABASE_URL whether running inside or outside Docker.
|
||||||
|
if ! ss -tlnp 2>/dev/null | grep -q ':5432'; then
|
||||||
|
echo "Starting postgres proxy 127.0.0.1:5432 -> host.docker.internal:5432"
|
||||||
|
socat TCP-LISTEN:5432,bind=127.0.0.1,fork,reuseaddr \
|
||||||
|
TCP:host.docker.internal:5432 &
|
||||||
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user