如何搭建mac下的linux运行环境

有时需要在 linux 环境下测试一些程序,比如测试基于 epoll 或 io_uring 的程序,这对于使用 mac 的用户来说是个问题。一种方式是另外备一台 linux 电脑,然后通过 ssh 命令进行远程操作,但是这并不方便。另一种方式是在 virtual box虚拟机上安装一个 linux 系统,但是这个占用资源太多了,毕竟我只是想运行一下 linux 程序,不希望动辄占用几个G的内存空间和几十个G的硬盘空间。考虑到 docker 占用资源比较少,使用起来也比较方便,因此选择通过 docker 打造一个 linux 运行环境。

安装 docker

首先要 docker 运行环境,可以直接从官网下载安装包进行安装。当然如果你是 brew 用户,也可以通过 brew cask install docker 命令安装。

安装 ubuntu latest

对于 linux 发行版,我选择的是 ubuntu latest,当前对应的具体版本是 Ubuntu 20.04.3 LTS

拉取远程镜像

将远程 docker 仓库的镜像拉取到本地。如果没有执行该操作,则在启动容器的时候会先从远程仓库拉取镜像。

1
docker pull ubuntu:latest

启动容器

启动一个基于 ubuntu:latest 镜像构建,并且名字为 gorden5566 的容器,加上名字是为了以后查看或操作方便。

1
docker run -itd --name gorden5566 ubuntu:latest

查看容器是否启动成功

可通过如下命令查看是否启动成功

1
docker ps

输出的内容格式如下

1
ded0f1381e6c   2bf9cad791e7             "bash"                   28 hours ago    Up 28 hours                             gorden5566

连接到容器

执行如下命令连接到刚创建的容器

1
docker exec -it gorden5566 /bin/bash

由于 bash 使用上不够便捷,我选择安装了 fish,之所以不选择 zsh 是因为还要安装 oh-my-zsh,比较麻烦

1
apt install fish

这样后续就可以使用 fish 作为默认 shell

1
docker exec -it gorden5566 /usr/bin/fish

挂载本地目录

配置共享目录

接下来是配置共享目录。例如我需要配置的路径是 /User/gorden5566/github,首先需要在 Docker Desktop 中配置可共享目录,具体路径如下

Settings -> Resources -> FILE SHARING

点击➕选择 /User/gorden5566/github 目录并保存。

接下来需要为容器中的 ubuntu 挂载该目录,这需要重新启动容器并指定参数。在操作前需要先删除原容器,否则会报如下错误

1
2
docker: Error response from daemon: Conflict. The container name "/gorden5566" is already in use by container "ded0f1381e6cd949afb6c5a1e2527cb7dcfdd714b3ddddd62bcc4dd27fecba76". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

删除容器

删除容器的操作步骤如下:

  1. 停止容器
1
docker stop gorden5566
  1. 删除容器
1
docker rm gorden5566

启动时指定挂载目录

指定将本地的 /User/gorden5566/github 目录挂载到容器的 /github 目录下

1
docker run -itd --mount type=bind,src=/Users/gorden5566/github,dst=/github --name gorden5566 ubuntu:latest

指定 ulimit

1
docker run -itd --ulimit memlock=-1 --mount type=bind,src=/Users/gorden5566/github,dst=/github --name gorden5566 ubuntu:latest

赋予root权限

使用 --privileged 命令赋予容器真正的 root 权限

1
docker run -itd --privileged --ulimit memlock=-1 --mount type=bind,src=/Users/gorden5566/github,dst=/github --name gorden5566 gubuntu

安装常用命令

默认安装的 ubuntu 是经过精简的

1
2
3
4
5
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, including manpages, you can run the 'unminimize'
command. You will still need to ensure the 'man-db' package is installed.

可以通过执行 unminimize 恢复部分依赖。对于其他缺少的命令,则可以通过 apt install 命令进行安装

打包镜像

经过一系列操作后,容器中安装了所需命令,并且按照个人习惯进行了设置,此时可以打包一个镜像,后续可根据这个镜像创建新容器。

1
docker commit -m "first commit" -a "gorden5566" gorden5566 gubuntu

-m "first commit" 表示本次提交的注释为 first commit

-a "gorden5566" 表示作者为 gorden5566

后面一个 gorden5566 表示要打包的镜像名,这里也可以使用 docker ps 看到的容器 id

gubuntu 表示新镜像的名字,此时生成的版本为 gubuntu:latest,也可以在生成时指定版本号,例如 gubuntu:0.0.1

后续的启动容器命令

1
2
3
4
5
docker stop gorden5566

docker rm gorden5566

docker run -itd --privileged --ulimit memlock=-1 --mount type=bind,src=/Users/gorden5566/github,dst=/github --name gorden5566 gubuntu

快速连接到容器

每次执行 docker exec 命令比较麻烦,可以配置为 alias 以简化操作。如下是在本地主机的 .zshrc 中新增的配置

1
alias gubuntu="docker exec -it gorden5566 /usr/bin/fish"

这样每次只需要执行 gubuntu 就可以连接到容器了

参考

https://www.runoob.com/docker/docker-install-ubuntu.html