You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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]>
Copy file name to clipboardExpand all lines: docs/Containers/PostgreSQL.md
+217Lines changed: 217 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,6 +79,223 @@ Notes:
79
79
$ docker-compose up -d postgresql
80
80
```
81
81
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
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:
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.
0 commit comments