我有一台新的笔记本电脑。一台带M1处理器的MacbookPro。电池性能令人印象深刻,性能非常好,但并非都是好东西。M1处理器有一个不同的架构。现在我们使用arm64而不是x86_64。
问题是当我们需要编译的时候。我们需要考虑到这一点。对于python,我通常使用pyenv来管理我笔记本电脑中不同的python版本,我为每个项目创建一个virtualenv来隔离我的环境。它工作得很好,但现在我面临着由于M1架构带来的问题。例如,为了用pyenv安装一个特定的python版本,我需要对它进行编译。另外,当我安装一个pip包并且它提供了一个二进制文件时,它必须是可用的M1版本。
这种问题有点让人沮丧。苹果公司为我们提供了rosetta来使用x86二进制文件,但简单的pip安装xxx却变成了一场噩梦。对我来说,这是不可能的。我想把项目部署到生产中,而不是成为一个低级架构的专家。所以,Docker是我的朋友。
我的解决方案是用Docker来避免这种问题。现在我没有使用pyenv。如果我需要一个python解释器,我会建立一个Docker镜像。我不使用virtualenv,而是创建一个容器。
PyCharm也允许我使用docker解释器,没有任何问题。
这就是我的python Dockerfile。
FROM python:3.9.6 AS base
ENV APP_HOME=/src
ENV APP_USER=appuser
RUN groupadd -r $APP_USER && \
useradd -r -g $APP_USER -d $APP_HOME -s /sbin/nologin -c "Docker image user" $APP_USER
WORKDIR $APP_HOME
ENV TZ 'Europe/Madrid'
RUN echo $TZ > /etc/timezone && \
apt-get update && apt-get install --no-install-recommends \
-y tzdata && \
rm /etc/localtime && \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
apt-get clean
RUN pip install --upgrade pip
FROM base
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR $APP_HOME
COPY requirements.txt .
RUN pip install -r requirements.txt
ADD src .
RUN chown -R $APP_USER:$APP_USER $APP_HOME
USER $APP_USER
我可以建立我的容器。
docker build -t demo .
现在我可以在pycharm中使用我的demo:最新镜像添加解释器了。
如果我需要添加一个pip依赖项,我不能用pip安装在本地来完成。我有两个选择。在requirements.txt中添加依赖项,然后重新构建镜像,或者在docker容器中运行pip("用docker run -it -rm ...")。为了组织这些脚本,我们可以轻松地创建一个package.json文件。
{
"name": "flaskdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"docker_local_build": "docker build -t $npm_package_name .",
"freeze": "docker run -it --rm -v \"$PWD\"/src:/src $npm_package_name python -m pip freeze > requirements.txt",
"local": "npm run docker_local_build && npm run freeze",
"python": "docker run -it --rm -v $PWD/src:/src $npm_package_name:latest",
"bash": "docker run -it --rm -v $PWD/src:/src $npm_package_name:latest bash"
},
"author": {
"name": "Gonzalo Ayuso",
"email": "gonzalo123@gmail.com",
"url": "https://gonzalo123.com"
},
"license": "MIT"
}
题外话
M1还有一个问题。也许你不需要面对这个问题,但如果你用M1笔记本构建了一个docker容器,并试图将这个容器部署到linux服务器上(不是arm64服务器),你的容器就无法工作。为了解决这个问题,你需要用正确的架构来构建你的容器。Docker允许我们这样做。比如说:
docker buildx build --platform linux/amd64 -t gonzalo123/demo:prodution .