Open haozi4263 opened 1 year ago
Reproduced in nerdctl in finch VM shell.
$ nerdctl logs mysql57
2022-12-06 00:56:15+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started.
/usr/bin/chown: changing ownership of '/var/lib/mysql/': Permission denied
/usr/bin/chown: changing ownership of '/var/lib/mysql': Permission denied
Database directories such as /var/lib/mysql
have to be on a "proper" filesystem such as ext4 or XFS, so this isn't likely supportable on Lima side.
Workaround: use (finch|nerdctl) volume create
instead of bind mounts
we're running into this while attempting to migrate from docker-compose up
to finch compose up
:
db_1 |chown: /var/lib/postgresql/data/base/13090/2831: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/2690: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/16587: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/2664: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/1249_vm: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/2836: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/16574: Permission denied
db_1 |chown: /var/lib/postgresql/data/base/13090/2663: Permission denied
web_1 |Waiting for database server to start up...
^CINFO[1025] Stopping containers (forcibly)
INFO[1025] Stopping container taproom_web_1
The docker-compose
file is as follows:
services:
db:
image: postgres:10-alpine
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
According to the previous conversation - if I create a volume as part of the compose file - and use that instead of the bind mount it would work so something similar to:
services:
db:
image: postgres:10-alpine
volumes:
- mydata:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
mydata:
could work - but my question is how do I populate the volume with the data from a local path on my host without the bind mount? I keep seeing A new volume’s contents can be pre-populated by a container.
- but im unsure of how to do this with finch
With docker for desktop I wouldn't need to pre-populate a volume, since the bind mount "just works"
You can follow the example in https://github.com/runfinch/finch/issues/131 to create a postgres container and have the volume automatically created for you when you run finch compose db up
. This volume will be persistent across boots. For example, if I were to bring the service up following the example in #131 and then run:
finch exec -it $(finch compose ps --format json | jq -r '.[].ID') psql -U admin_user db_name -c 'create table foo()'
I would be able to create a new table, foo
which would persist across container reboots.
I can see the table was created by running:
finch exec -it $(finch compose ps --format json | jq -r '.[].ID') psql -U admin_user db_name -c '\z'
and it will even work in other services as long as I specify the same volume.
If you want to populate this volume with data from your macOS system, unfortunately it seems like bind mounts will not work properly with reverse-sshfs due to permissions issues (see: https://github.com/docker-library/postgres/issues/939). We are aware of issues with sshfs and were hoping to migrate to 9p as a default, but there are other issues with that (see: https://github.com/lima-vm/lima/issues/971).
One workaround (and honestly this is probably the better way to do it anyway, since it will allow you to export from one version and import on another, and other benefits) is to copy a backup of your existing data into the volume and then restore. An example of how to do this can be seen in this StackOverflow post. The only difference in this case is that you need the backup to be available inside the container, which you can achieve by running
finch cp PATH_TO_SQL_BACKUP_ON_DISK CONTAINER_ID:PATH_TO_SQL_BACKUP_IN_CONTAINER
(I will preface this with saying that I am not an expert at postgresql, so there may be other/better ways to do this but...) A full example with real values will look something like this:
compose.yaml:
services:
db:
image: postgres:14-alpine
environment:
- POSTGRES_USER=admin_user
- POSTGRES_PASSWORD=admin12345
- POSTGRES_DB=db_name
- PGDATA=/var/lib/postgresql/db/pgdata
volumes:
- pgdata:/var/lib/postgresql/db:rw
ports:
- '5432:5432'
volumes:
pgdata:
# create a new db using the example above / from https://github.com/runfinch/finch/issues/131#issuecomment-1384747041
# (you can skip this step if you already have a DB, I'm just including this for completeness)
$ finch compose up db -d
# create a new table
$ finch exec -it $(finch compose ps --format json | jq -r '.[].ID') psql -U admin_user db_name -c 'create table beer()'
# dump the db
$ finch exec -it $(finch compose ps --format json | jq -r '.[].ID') bash -c 'pg_dump -U admin_user db_name > backup.sql'
# copy it out of the container
$ finch cp $(finch compose ps --format json | jq -r '.[].ID'):backup.sql backup.sql
# stop the service, delete the container, and delete the volume
$ yes | finch compose rm db && yes | finch volume prune
# start the new db
$ finch compose up db -d
# list tables, should be empty since this is a new container + volume
$ finch exec -it $(finch compose ps --format json | jq -r '.[].ID') psql -U admin_user db_name -c '\z'
# copy the backup into the new container
$ finch cp backup.sql $(finch compose ps --format json | jq -r '.[].ID'):backup.sql
# import the backup
$ finch exec -it $(finch compose ps --format json | jq -r '.[].ID') bash -c 'psql -U admin_user db_name < backup.sql'
# list tables, should be the same as the first time
$ finch exec -it $(finch compose ps --format json | jq -r '.[].ID') psql -U admin_user db_name -c '\z'
In the example, $(finch compose ps --format json | jq -r '.[].ID')
can be replaced with a container ID from the output of finch container ls
if you are not running the commands from the same directory as you ran the finch compose up db -d
command.
finch --platform=amd64 run --name mysql57 -p 3306:3306 -v /Users/zhanghao/mysql57:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --restart=always -d mysql:5.7
finch logs mysql57 2022-12-02 03:46:02+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started. /usr/bin/chown: changing ownership of '/var/lib/mysql/': Permission denied /usr/bin/chown: changing ownership of '/var/lib/mysql': Permission denied