Skip to content

Commit 9507e6e

Browse files
committed
2025-10-09 postgres - master branch - PR 1 of 2
Updated service definition to explicitly pull Postgres v18 and remap the persistent store to be v18-friendly. My assumptions are: 1. The adjusted service definition is appropriate for **new** users installing the Postgres container for the first time. 2. Existing users will be running v17 (or earlier) and will not bang into the problem reported in #808 until they do a `pull` from DockerHub. There is no easy way to avoid the migration problem. Users will just have to read the Wiki. Wiki updated to explain how to restore database access by reverting to v17, then performing a controlled migration to v18. Signed-off-by: Phill Kelley <[email protected]>
1 parent e656a8a commit 9507e6e

File tree

2 files changed

+220
-3
lines changed

2 files changed

+220
-3
lines changed

.templates/postgres/service.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
postgres:
22
container_name: postgres
3-
image: postgres
3+
image: postgres:18
4+
x-comment: Please READ the Postgres document in the IOTstack Wiki BEFORE changing the "18"
45
restart: unless-stopped
56
environment:
67
- TZ=${TZ:-Etc/UTC}
@@ -10,6 +11,5 @@ postgres:
1011
ports:
1112
- "5432:5432"
1213
volumes:
13-
- ./volumes/postgres/data:/var/lib/postgresql/data
14+
- ./volumes/postgres/data:/var/lib/postgresql
1415
- ./volumes/postgres/db_backup:/backup
15-

docs/Containers/PostgreSQL.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,223 @@ Notes:
7979
$ docker-compose up -d postgresql
8080
```
8181

82+
## Postgres v17 to v18 migration { #v1718migration }
83+
84+
Prior to Postgres v17, the external path to the persistent store holding the database file structures was at:
85+
86+
```
87+
~/IOTstack/volumes/postgres/data
88+
```
89+
90+
Inside the container, that mapped to the following path, which is also where your database files were located:
91+
92+
```
93+
/var/lib/postgresql/data
94+
```
95+
96+
Prior to October 2025, the service definition for Postgres provided with IOTstack contained:
97+
98+
``` yaml
99+
image: postgres
100+
```
101+
102+
That is a synonym for:
103+
104+
``` yaml
105+
image: postgres:latest
106+
```
107+
108+
Postgres v18 was released on September 26, 2025. If you are running Postgres v17 and "pull" the latest image from DockerHub after that date, you will get v18. When you try to instantiate the v18 image, you will get this error:
109+
110+
```
111+
Error response from daemon: failed to create task for container: failed
112+
to create shim task: OCI runtime create failed: runc create failed:
113+
unable to start container process: error during container init: error
114+
mounting "/home/pi/IOTstack/volumes/postgres/data" to rootfs at
115+
"/var/lib/postgresql/data": change mount propagation through procfd:
116+
open o_path procfd: open
117+
/var/lib/docker/overlay2/«hex string»/merged/var/lib/postgresql/data:
118+
no such file or directory: unknown
119+
```
120+
121+
### Fixing the immediate problem
122+
123+
To resolve that error and restore access to your database, you need to revert to Postgres v17. Proceed like this:
124+
125+
1. Move into the correct directory:
126+
127+
``` console
128+
$ cd ~/IOTstack
129+
```
130+
131+
2. Stop the (broken) container:
132+
133+
``` console
134+
$ docker compose down postgresql
135+
```
136+
137+
3. Use your favourite text editor to open `docker-compose.yml`.
138+
139+
Find the `image` clause and change it to be:
140+
141+
``` yaml
142+
image: postgres:17
143+
```
144+
145+
Save your work.
146+
147+
4. Start the container again:
148+
149+
``` console
150+
$ docker compose up -d postgresql
151+
```
152+
153+
The container should start normally and you regain access to your databases.
154+
155+
### Anonymous volume mounts
156+
157+
One side-effect of upgrading a v17 directory structure to v18 is that Docker creates an anonymous volume mount.
158+
159+
Anonymous volume mounts are the result of:
160+
161+
1. A `VOLUME` declaration in the Dockerfile used to create the image; and
162+
2. Launching the container *without* providing a corresponding volume or bind mount mapping.
163+
164+
As such, and depending on the age of your system and your propensity to experiment with Docker containers, you may find that you have multiple anonymous volume mounts of which you were previously unaware.
165+
166+
Anonymous volume mounts persist on your system until you remove them. They are of use to the containers that created them while those containers are running but they are not re-attached when the container is re-created. They simply occupy disk space, indefinately, for no benefit.
167+
168+
Removing an anonymous volume mount is a two-step process:
169+
170+
1. List the anonymous volume mounts:
171+
172+
``` console
173+
$ docker volume ls --filter "dangling=true"
174+
```
175+
176+
You can expect to see something like this:
177+
178+
```
179+
DRIVER VOLUME NAME
180+
local 6c2862fdbc36187c0e858be7d8ebb81c653b796f2158f450136a00e7c8eca62d
181+
```
182+
183+
A 64-character hexadecimal string in the `VOLUME NAME` column is the signature of an anonymous volume mount.
184+
185+
Note:
186+
187+
* The list may also contain rows where the `VOLUME NAME` is not a 64-character hexadecimal string. Those are *named* volume mounts. By convention, IOTstack does not use named volume mounts so those *may* be the results of previous experiments with Docker containers. If you do not recognise a named volume mount then you can consider removing it along with any anonymous volume mounts.
188+
189+
2. For each anonymous volume mount, remove it by passing the 64-character hexadecimal string. For example:
190+
191+
``` console
192+
$ docker volume rm 6c2862fdbc36187c0e858be7d8ebb81c653b796f2158f450136a00e7c8eca62d
193+
```
194+
195+
### Migrating to v18
196+
197+
When you are ready to migrate to Postgres v18, proceed like this:
198+
199+
1. Move into the correct directory:
200+
201+
``` console
202+
$ cd ~/IOTstack
203+
```
204+
205+
2. Take a backup of your databases:
206+
207+
``` console
208+
$ docker exec postgres bash -c 'pg_dumpall -U $POSTGRES_USER | gzip >/backup/postgres_backup.sql.gz'
209+
```
210+
211+
3. Stop the v17 Postgres container:
212+
213+
```
214+
$ docker compose down postgres
215+
```
216+
217+
4. Use your favourite text editor to open `docker-compose.yml` and make the following changes:
218+
219+
1. Find the `image` clause and change it to be:
220+
221+
``` yaml
222+
image: postgres:18
223+
```
224+
225+
2. The first two lines of the `volumes:` clause look like this:
226+
227+
``` yaml
228+
volumes:
229+
- ./volumes/postgres/data:/var/lib/postgresql/data
230+
```
231+
232+
Change the second line to look like this:
233+
234+
``` yaml
235+
- ./volumes/postgres/data:/var/lib/postgresql
236+
```
237+
238+
3. Save your work.
239+
240+
4. Carefully (repeat **carefully**) remove the `data` portion of the Postgres container's persistent store:
241+
242+
``` console
243+
$ sudo rm -rf ./volumes/postgres/data
244+
```
245+
246+
Key point:
247+
248+
* Do **not** remove `./volumes/postgres` because that will also destroy your backup.
249+
250+
5. Start the container:
251+
252+
``` console
253+
$ docker compose up -d postgres
254+
```
255+
256+
This will instantiate v18 and create a new, empty database structure.
257+
258+
6. Restore your data:
259+
260+
```
261+
$ docker exec postgres bash -c 'gunzip -c /backup/postgres_backup.sql.gz | psql -U $POSTGRES_USER postgres'
262+
```
263+
264+
After the migration, the external path to the persistent store remains unchanged at:
265+
266+
```
267+
~/IOTstack/volumes/postgres/data
268+
```
269+
270+
Within the container, that path maps to:
271+
272+
```
273+
/var/lib/postgresql
274+
```
275+
276+
However, that path is not where your database files are located. Instead, the files are at the internal path:
277+
278+
```
279+
/var/lib/postgresql/18/docker
280+
```
281+
282+
which maps to the external path:
283+
284+
```
285+
~/IOTstack/volumes/postgres/data/18/docker
286+
```
287+
288+
### Postgres v19 and beyond
289+
290+
I recommend leaving `image: postgres:18` in place. That way, you are unlikely to be surprised when Postgres is upgraded to v19. It *may* be that v19 will silently handle the v18-to-v19 upgrade. On the other hand, you *may* need to adopt the approach shown above:
291+
292+
* Take a backup of your data.
293+
* Down the container.
294+
* Hand-edit your compose file to `image: postgres:19`
295+
* Remove the `data` portion of the persistent store.
296+
* Up the container.
297+
* Restore your data.
298+
82299
## Getting a clean slate { #cleanSlate }
83300

84301
If you need to start over, proceed like this:

0 commit comments

Comments
 (0)