Skip to content

【M1 Mac】lima + DockerでMySQLを起動する

はじめに

limaを使って立ち上げたVMにdockerのmysqlを立ち上げようとした際に、以下のエラーでハマったので備忘録として残します。

  • read-only file system
  • permission denied
  • exec format error
  • [ERROR] [MY-010259] [Server] Another process with pid 63 is using unix socket file

環境

 名前  バージョン 
PCMacBook Pro (13-inch, M1, 2020)
lima0.14.2
Docker20.10.12

結論

compose.yaml
services:
db:
image: mysql/mysql-server:latest
user: mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- db-data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
db-data:

limaのdocker exampleから大きく変更していません。
変更しているのは、mountsの部分です。

lima.yaml
lima.yaml
# Example to use Docker instead of containerd & nerdctl
# $ limactl start ./docker.yaml
# $ limactl shell docker docker run -it -v $HOME:$HOME --rm alpine
# To run `docker` on the host (assumes docker-cli is installed):
# $ export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
# $ docker ...
# This example requires Lima v0.8.0 or later
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20221201/ubuntu-22.04-server-cloudimg-amd64.img"
arch: "x86_64"
digest: "sha256:8a814737df484d9e2f4cb2c04c91629aea2fced6799fc36f77376f0da91dba65"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20221201/ubuntu-22.04-server-cloudimg-arm64.img"
arch: "aarch64"
digest: "sha256:8a0477adcbdadefd58ae5c0625b53bbe618aedfe69983b824da8d02be0a8c961"
# Fallback to the latest release image.
# Hint: run `limactl prune` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
arch: "aarch64"
# CPUs: if you see performance issues, try limiting cpus to 1.
# 🟢 Builtin default: 4
# cpus: null
# Memory size
# 🟢 Builtin default: "4GiB"
# memory: null
# Disk size
# 🟢 Builtin default: "100GiB"
# disk: null
mounts:
- # - location: "~"
- location: "~/Project"
writable: true
- location: "/tmp/lima"
writable: true
# containerd is managed by Docker, not by Lima, so the values are set to false here.
containerd:
system: false
user: false
provision:
- mode: system
# This script defines the host.docker.internal hostname when hostResolver is disabled.
# It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts.
# Names defined in /etc/hosts inside the VM are not resolved inside containers when
# using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later).
script: |
#!/bin/sh
sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts
- mode: system
script: |
#!/bin/bash
set -eux -o pipefail
command -v docker >/dev/null 2>&1 && exit 0
export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://get.docker.com | sh
# NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless
systemctl disable --now docker
apt-get install -y uidmap dbus-user-session
- mode: user
script: |
#!/bin/bash
set -eux -o pipefail
systemctl --user start dbus
dockerd-rootless-setuptool.sh install
docker context use rootless
probes:
- script: |
#!/bin/bash
set -eux -o pipefail
if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then
echo >&2 "docker is not installed yet"
exit 1
fi
if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then
echo >&2 "rootlesskit (used by rootless docker) is not running"
exit 1
fi
hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
# hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also
# resolve inside containers, and not just inside the VM itself.
hosts:
host.docker.internal: host.lima.internal
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
hostSocket: "{{.Dir}}/sock/docker.sock"
message: |
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima-{{.Name}} --docker "host=unix://{{.Dir}}/sock/docker.sock"
docker context use lima-{{.Name}}
docker run hello-world
------

調査

はじめにlimaのGitHubからテンプレートを取ってきます

Terminal window
$ curl -o lima.yaml https://raw.githubusercontent.com/lima-vm/lima/master/examples/docker.yaml

このときのファイルは以下の通りです

lima.yaml
# Example to use Docker instead of containerd & nerdctl
# $ limactl start ./docker.yaml
# $ limactl shell docker docker run -it -v $HOME:$HOME --rm alpine
# To run `docker` on the host (assumes docker-cli is installed):
# $ export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
# $ docker ...
# This example requires Lima v0.8.0 or later
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20221201/ubuntu-22.04-server-cloudimg-amd64.img"
arch: "x86_64"
digest: "sha256:8a814737df484d9e2f4cb2c04c91629aea2fced6799fc36f77376f0da91dba65"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release-20221201/ubuntu-22.04-server-cloudimg-arm64.img"
arch: "aarch64"
digest: "sha256:8a0477adcbdadefd58ae5c0625b53bbe618aedfe69983b824da8d02be0a8c961"
# Fallback to the latest release image.
# Hint: run `limactl prune` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
arch: "aarch64"
mounts:
- location: "~"
- location: "/tmp/lima"
writable: true
# containerd is managed by Docker, not by Lima, so the values are set to false here.
containerd:
system: false
user: false
provision:
- mode: system
# This script defines the host.docker.internal hostname when hostResolver is disabled.
# It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts.
# Names defined in /etc/hosts inside the VM are not resolved inside containers when
# using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later).
script: |
#!/bin/sh
sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts
- mode: system
script: |
#!/bin/bash
set -eux -o pipefail
command -v docker >/dev/null 2>&1 && exit 0
export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://get.docker.com | sh
# NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless
systemctl disable --now docker
apt-get install -y uidmap dbus-user-session
- mode: user
script: |
#!/bin/bash
set -eux -o pipefail
systemctl --user start dbus
dockerd-rootless-setuptool.sh install
docker context use rootless
probes:
- script: |
#!/bin/bash
set -eux -o pipefail
if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then
echo >&2 "docker is not installed yet"
exit 1
fi
if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then
echo >&2 "rootlesskit (used by rootless docker) is not running"
exit 1
fi
hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
# hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also
# resolve inside containers, and not just inside the VM itself.
hosts:
host.docker.internal: host.lima.internal
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
hostSocket: "{{.Dir}}/sock/docker.sock"
message: |
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima-{{.Name}} --docker "host=unix://{{.Dir}}/sock/docker.sock"
docker context use lima-{{.Name}}
docker run hello-world
------

read-only file system

Linuxインスタンスを立ち上げます

Terminal window
$ limactl start --name docker --tty=false lima.yaml
出力結果
Terminal window
INFO[0000] Terminal is not available, proceeding without opening an editor
INFO[0000] Attempting to download the image from "https://cloud-images.ubuntu.com/releases/22.04/release-20221201/ubuntu-22.04-server-cloudimg-arm64.img" digest="sha256:8a0477adcbdadefd58ae5c0625b53bbe618aedfe69983b824da8d02be0a8c961"
INFO[0000] Using cache "/Users/hoge/Library/Caches/lima/download/by-url-sha256/26ec58a84d273e5b19eebe2a555e5a63172532f1a7f8b0d6f0aaf5edc83ce1b3/data"
WARN[0001] [hostagent] Reducing the guest memory from 4GiB to 3GiB, to avoid host kernel panic on macOS <= 12.3 with QEMU >= 7.0; Please update macOS to 12.4 or later, or downgrade QEMU to 6.2; See https://github.com/lima-vm/lima/issues/795 for the further background.
INFO[0001] [hostagent] Starting QEMU (hint: to watch the boot progress, see "/Users/hoge/.lima/docker/serial.log")
INFO[0001] SSH Local Port: 58370
INFO[0001] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
cINFO[0022] [hostagent] The essential requirement 1 of 5 is satisfied
INFO[0022] [hostagent] Waiting for the essential requirement 2 of 5: "user session is ready for ssh"
INFO[0022] [hostagent] The essential requirement 2 of 5 is satisfied
INFO[0022] [hostagent] Waiting for the essential requirement 3 of 5: "sshfs binary to be installed"
INFO[0041] [hostagent] The essential requirement 3 of 5 is satisfied
INFO[0041] [hostagent] Waiting for the essential requirement 4 of 5: "/etc/fuse.conf (/etc/fuse3.conf) to contain \"user_allow_other\""
INFO[0045] [hostagent] The essential requirement 4 of 5 is satisfied
INFO[0045] [hostagent] Waiting for the essential requirement 5 of 5: "the guest agent to be running"
INFO[0045] [hostagent] The essential requirement 5 of 5 is satisfied
INFO[0045] [hostagent] Mounting "/Users/hoge" on "/Users/hoge"
INFO[0046] [hostagent] Mounting "/tmp/lima" on "/tmp/lima"
INFO[0046] [hostagent] Waiting for the optional requirement 1 of 1: "user probe 1/1"
INFO[0046] [hostagent] Forwarding "/run/user/501/docker.sock" (guest) to "/Users/hoge/.lima/docker/sock/docker.sock" (host)
INFO[0047] [hostagent] Forwarding "/run/lima-guestagent.sock" (guest) to "/Users/hoge/.lima/docker/ga.sock" (host)
INFO[0047] [hostagent] Not forwarding TCP 0.0.0.0:22
INFO[0047] [hostagent] Not forwarding TCP 127.0.0.53:53
INFO[0047] [hostagent] Not forwarding TCP [::]:22
INFO[0083] [hostagent] The optional requirement 1 of 1 is satisfied
INFO[0083] [hostagent] Waiting for the final requirement 1 of 1: "boot scripts must have finished"
INFO[0086] [hostagent] The final requirement 1 of 1 is satisfied
INFO[0086] READY. Run `limactl shell docker` to open the shell.
INFO[0086] Message from the instance "docker":
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima-docker --docker "host=unix:///Users/hoge/.lima/docker/sock/docker.sock"
docker context use lima-docker
docker run hello-world
------

ちゃんと起動していますね。

Terminal window
$ limactl ls
NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR
docker Running 127.0.0.1:58370 qemu aarch64 4 4GiB 100GiB ~/.lima/docker

完了したらdocker cliの向け先を先ほど作成したインスタンスに向けます

Terminal window
$ docker context create lima-docker --docker "host=unix:///Users/xxxxxx/.lima/docker/sock/docker.sock"
$ docker context use lima-docker

info: コンテキストやdocker cliの情報を表示できます

Terminal window
$ docker context ls
$ docker info

info: 環境変数DOCKER_HOSTを使うことで、docker contextを使うことなく、向け先を切り替えることもできます。
Docker デーモンソケットの保護

このときのcomposeファイルは以下の通りです。

compose.yaml
services:
db:
image: mysql:latest
platform: linux/amd64
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- ./mysql/data:/var/lib/mysql
ports:
- "3306:3306"

docker compose upしてみると・・

Terminal window
$ docker compose up
[+] Running 12/12
db Pulled 10.7s
b4ddc423e046 Pull complete 3.3s
b338d8e4ffd1 Pull complete 3.5s
b2b1b06949ab Pull complete 3.6s
daf393284da9 Pull complete 3.8s
1cb8337ae65d Pull complete 3.8s
f6c2cc79221c Pull complete 3.9s
4cec461351e0 Pull complete 5.2s
ab6bf0cba08e Pull complete 5.3s
8df43cafbd11 Pull complete 7.4s
c6d0aac53df5 Pull complete 7.5s
b24148c7c251 Pull complete 7.5s
[+] Running 1/0
Container docker-lima-db-1 Created 0.0s
Attaching to docker-lima-db-1
Error response from daemon: error while creating mount source path '/path/to/mysql/data': mkdir /path/to/mysql/data: read-only file system

mkdir /path/to/mysql/data: read-only file systemで拒否されました。

解決-1

- location: "~" は消して、特定のディレクトリのみwritable: trueにします。

mounts:
# - location: "~"
- location: "~/Project"
writable: true
- location: "/tmp/lima"
writable: true

Attempting to mount a writable directory under a read-only directory doesn’t work #873 - GitHub issues

補足

ホームディレクトリへの書き込み権限はdefaultでfalseなので、lima.yamlのmountsにwritable: trueを入れれば解消します。

mounts:
- location: "~"
writable: true

Filesystem is not writable - GitHub lima README

しかし、公式ではtrueにすべきではないと書いているので、ホームディレクトリに対してwritableの設定するのは避けたほうが良いでしょう。

# CAUTION: `writable` SHOULD be false for the home directory.
# Setting `writable` to true is possible, but untested and dangerous.
# 🟢 Builtin default: false
writable: null

lima/examples/default.yaml

私のPCでは、ホームディレクトリ配下にProjectディレクトリを作成しているので、以下のように追記し、インスタンスを作り直しました。

mounts:
- location: "~"
- location: "~/Project"
writable: true
- location: "/tmp/lima"
writable: true
Terminal window
$ limactl stop docker
$ limactl delete docker

しかし、結局エラーは変わらず、read-only file systemでした。

limaのissueを探してみると、どうやらホームディレクトリはwritable:falseで、その配下のディレクトリをwritable:trueにするようなことはできないそうです。
Overlapping mounts don’t work correctly #302 - GitHub issues

permission denied

lima.yamlのmountsを修正してもう一度インスタンスを作成します。

Terminal window
$ limactl stop docker
$ limactl delete docker
$ limactl start --name docker --tty=false lima.yaml

compose.yamlはそのままです。

compose.yaml
services:
db:
image: mysql:latest
platform: linux/amd64
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- ./mysql/data:/var/lib/mysql
ports:
- "3306:3306"

今度はpermission deniedで止まりました。

Terminal window
$ docker compose up
[+] Running 12/12
db Pulled 10.8s
b4ddc423e046 Pull complete 3.3s
b338d8e4ffd1 Pull complete 3.6s
b2b1b06949ab Pull complete 3.6s
daf393284da9 Pull complete 3.8s
1cb8337ae65d Pull complete 3.9s
f6c2cc79221c Pull complete 3.9s
4cec461351e0 Pull complete 5.2s
ab6bf0cba08e Pull complete 5.3s
8df43cafbd11 Pull complete 7.4s
c6d0aac53df5 Pull complete 7.4s
b24148c7c251 Pull complete 7.5s
[+] Running 2/1
Network docker-lima_default Created 0.0s
Container docker-lima-db-1 Created 0.0s
Attaching to docker-lima-db-1
Error response from daemon: error while creating mount source path '/path/to/mysql/data': mkdir /path/to/Project: permission denied

解決-2

MySQLコンテナをlimaで起動するとPermission Deniedになる - Scrapboxの記事を参考にしました。

以下のようにuser: mysqlを入れます。

compose.yaml
services:
db:
image: mysql:latest
platform: linux/amd64
user: mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- ./mysql/data:/var/lib/mysql
ports:
- "3306:3306"

exec format error

user:mysqlを入れて実行してみると、今度は、exec format errorが出ました。

Terminal window
$ docker compose up
[+] Running 1/0
Container docker-lima-db-1 Created 0.0s
Attaching to docker-lima-db-1
docker-lima-db-1 | exec /usr/local/bin/docker-entrypoint.sh: exec format error
docker-lima-db-1 exited with code 1

解決-3

mysql/mysql-serverはarm64をサポートしているようなので、dockerイメージを代えます。

MySQL Server 8.0, the latest GA, for both x86 and AArch64(ARM64) architectures (tag: 8.0, latest) (mysql-server/8.0/Dockerfile)

mysql/mysql-server - DockerHub

compose.yaml
services:
db:
image: mysql/mysql-server:latest
# platform: linux/amd64
user: mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- ./mysql/data:/var/lib/mysql
ports:
- "3306:3306"

[ERROR] [MY-010259] [Server] Another process with pid 63 is using unix socket file.

今度はunix socket fileでエラーが出ました。

Terminal window
$ docker compose up
[+] Running 1/1
Container docker-lima-db-1 Recreated 0.4s
Attaching to docker-lima-db-1
docker-lima-db-1 | [Entrypoint] MySQL Docker Image 8.0.32-1.2.11-server
docker-lima-db-1 | [Entrypoint] Starting MySQL 8.0.32-1.2.11-server
docker-lima-db-1 | 2023-02-25T06:37:28.446867Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
docker-lima-db-1 | 2023-02-25T06:37:28.446977Z 0 [Warning] [MY-010143] [Server] Ignoring user change to '27' because the user was set to 'mysql' earlier on the command line
docker-lima-db-1 | 2023-02-25T06:37:28.467339Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.32) starting as process 1
docker-lima-db-1 | 2023-02-25T06:37:28.492378Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
docker-lima-db-1 | 2023-02-25T06:37:28.732651Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
docker-lima-db-1 | 2023-02-25T06:37:42.332168Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
docker-lima-db-1 | 2023-02-25T06:37:42.590346Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...
docker-lima-db-1 | 2023-02-25T06:37:42.685470Z 0 [System] [MY-010232] [Server] XA crash recovery finished.
docker-lima-db-1 | 2023-02-25T06:37:42.736262Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
docker-lima-db-1 | 2023-02-25T06:37:42.736357Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
docker-lima-db-1 | 2023-02-25T06:37:42.743300Z 0 [ERROR] [MY-010259] [Server] Another process with pid 63 is using unix socket file.
docker-lima-db-1 | 2023-02-25T06:37:42.743316Z 0 [ERROR] [MY-010268] [Server] Unable to setup unix socket lock file.
docker-lima-db-1 | 2023-02-25T06:37:42.743325Z 0 [ERROR] [MY-010119] [Server] Aborting
docker-lima-db-1 | 2023-02-25T06:37:44.374095Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.32) MySQL Community Server - GPL.
docker-lima-db-1 exited with code 1

解決-4

[Error] [Server] Do you already have another mysqld server running on socket ? でMySQLがDockerで立ち上がらない現象 - Qiitaの記事を参考にしました!

名前付きボリュームをつけることで回避ができるそうです。

compose.yaml
services:
db:
image: mysql/mysql-server:latest
# platform: linux/amd64
user: mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
volumes:
- db-data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
db-data:

やってみましょう。

Terminal window
$ docker compose up
$ docker compose exec db mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.32 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

無事mysqlに繋げることができました