bash - Dockerfile 中需要冗余 eval $(opam env)

标签 bash docker dockerfile coq opam

我成功安装了coqcDockerfile 。为什么我需要运行eval $(opam env) 再次当我执行docker时?

##############
#            #
# image name #
#            #
##############
FROM ubuntu:22.04

#################
#               #
# bash > sh ... #
#               #
#################
SHELL ["/bin/bash", "-c"]

##########
#        #
# update #
#        #
##########
RUN apt-get update -y

############################
#                          #
# minimal set of utilities #
#                          #
############################
RUN apt-get install curl -y
RUN apt-get install libgmp-dev -y

###########################################
#                                         #
# opam is the easiest way to install coqc #
#                                         #
###########################################
RUN apt-get install opam -y
RUN opam init --disable-sandboxing
RUN eval $(opam env)

#########################################
#                                       #
# install coqc, takes around 10 minutes #
#                                       #
#########################################
RUN opam pin add coq 8.15.2 -y

这是我的使用方法:

$ docker build --tag host --file .\Dockerfile.txt .
$ docker run -d -t --name my_lovely_docker host
$ docker exec -it my_lovely_docker bash

当我在 docker 内时:

root@3055f16a1d78:/# coqc --version
bash: coqc: command not found
root@3055f16a1d78:/# eval $(opam env)
[WARNING] Running as root is not recommended
root@3055f16a1d78:/# coqc --version
The Coq Proof Assistant, version 8.15.2
compiled with OCaml 4.13.1

最佳答案

Coq 的预构建版本(Debian 内)

如上所述in the commentsDocker-Coq存储库收集 Coq 的预构建版本,例如:

docker pull coqorg/coq:8.15.2

所有标签的列表可在以下 URL 中找到:

https://hub.docker.com/r/coqorg/coq#supported-tags

相关文档位于此 Wiki 中:

https://github.com/coq-community/docker-coq/wiki

一个独立的 Dockerfile 作为 Ubuntu 的“安装教程”

发送至地址the specific use case OP提到的,这里是一个全面的Dockerfile,它解决了问题中提到的主要问题(为什么当我执行docker时需要再次运行eval $(opam env)),以及遵守标准 Dockerfile 和 opam 指南所必需的几个修复(尽管不会妨碍所涉及的用例):

##############
#            #
# image name #
#            #
##############
FROM ubuntu:22.04

#################
#               #
# bash > sh ... #
#               #
#################
SHELL ["/bin/bash", "--login", "-c"]

############################
#                          #
# minimal set of utilities #
#                          #
############################
# Run the following as root:
RUN apt-get update -y -q \
 && apt-get install -y -q --no-install-recommends \
    # alphabetical order advised for long package lists to ease review & update
    ca-certificates \
    curl \
    libgmp-dev \
    m4 \
    ocaml \
    opam \
    rsync \
    sudo \
#########################################
#                                       #
# Docker-specific cleanup to earn space #
#                                       #
#########################################
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

#####################
#                   #
# add non-root user #
# (with sudo perms) #
#                   #
#####################
ARG coq_uid=1000
ARG coq_gid=${coq_uid}
RUN groupadd -g ${coq_gid} coq \
 && useradd --no-log-init -m -s /bin/bash -g coq -G sudo -p '' -u ${coq_uid} coq \
 && mkdir -p -v /home/coq/bin /home/coq/.local/bin \
 && chown coq:coq /home/coq/bin /home/coq/.local /home/coq/.local/bin

###########################################
#                                         #
# opam is the easiest way to install coqc #
#                                         #
###########################################
USER coq
WORKDIR /home/coq
RUN opam init --auto-setup --yes --bare --disable-sandboxing \
 && opam switch create system ocaml-system \
 && eval $(opam env) \
 && opam repo add --all-switches --set-default coq-released https://coq.inria.fr/opam/released \
#########################################
#                                       #
# install coqc, takes around 10 minutes #
#                                       #
#########################################
 && opam pin add -y -k version -j "$(nproc)" coq 8.15.2 \
#########################################
#                                       #
# Docker-specific cleanup to earn space #
#                                       #
#########################################
 && opam clean -a -c -s --logs

###################################
#                                 #
# Automate the 'eval $(opam env)' #
#                                 #
###################################
ENTRYPOINT ["opam", "exec", "--"]
CMD ["/bin/bash", "--login"]

两个 Dockerfile 之间的变化摘要/相关备注

在上面的 Dockerfile 中,已应用以下修复:

  • 将连续的 RUN 命令与 && 合并,以避免此 SO 问题中提出的问题:Purpose of specifying several UNIX commands in a single RUN instruction in Dockerfile .
  • 将 CLI 标志 -q--no-install-recommends 添加到 apt-get 命令,以便输出更加简洁,并且安装的软件包仅包含那些指定的(和强制依赖项)。
  • 将 APT 软件包按字母顺序排列,以便于审核和更新。
  • 添加一个非 root 用户(此处名为 coq),以便 opam 不再提示通常的情况[警告] 不建议以 root 身份运行
    当然,在非 Docker 安装中可以跳过此步骤,因为我们总是在标准工作站上安装一些常规的 $USER...
  • opam init 命令替换为:
    opam init --auto-setup --yes --bare --disable-sandboxing \
    && opam switch create system ocaml-system
    
    因此 ~/.profile 脚本会自动更新(感谢 --auto-setup)以及交换机的名称 (system) 和其内容 (ocaml-system) 是明确的。
  • 添加 opam repo add --all-switches --set-default coq-released https://coq.inria.fr/opam/released 以便在需要时可以安装社区软件包是,例如:
    opam install -y -v -j "$(nproc)" coq-mathcomp-ssreflect
    
  • 传递 -j "$(nproc)" 选项以并行化并加速安装,具体取决于环境系统的核心数量。
  • 添加可选的、Docker 特定命令apt-get clean && rm -rf/var/lib/apt/lists/*opam clean -a -c -s --logs 减少 Docker 层的大小。

回答问题中提出的主要问题

  • 每次启动新的 shell(或 RUN 命令等)时,都需要使用 eval $(opam env) 命令来更新路径

  • 有两种方法可以确保此命令eval $(opam env)自动完成:

    • opam exec -- ... 包装命令
    • 或者运行/bin/bash --login,以便获取~/.profile初始化脚本(事实上,这要归功于opam init -- auto-setup 是负责使用适当的环境变量等初始化环境 shell 的行,在此脚本中由 opam 附加)。
  • 为了完整起见,这两种解决方案都已在这个提议的 Dockerfile 中实现(我们可以保留这两种解决方案,而没有任何特定的缺点)。

测试这一切

$ docker build -t coq-image .
# or better $ docker build -t coq-image --build-arg=coq_uid="$(id -u)" --build-arg=coq_gid="$(id -g)" .

$ docker run --name=coq -it coq-image
# or to mount the current directory
# $ docker run --name=coq -it -v "$PWD:$PWD" -w "$PWD" coq-image

  # Ctrl+D

$ docker start -ai coq  # to restart the container

  # Ctrl+D

$ docker rm coq         # to remove the container

关于bash - Dockerfile 中需要冗余 eval $(opam env),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72583938/

相关文章:

linux - 作业完成时执行命令

bash - 通过 ID 在文本中查找单词并替换同一行中的其他单词

docker - 在不受信任的主机上运行的Docker容器

如果目录中的所有文件不存在重新编码文件,则重新编码文件的 Bash 脚本

java - 使用 "> filename"时不打印到文件的 System.out.println

docker - 无法从 Postman 的 k8s-Skaffold 中的 Express API 获得响应

scala - 如何使用Docker将参数传递给Spark-Submit

angularjs - docker compose 中的 Angular 不会重新加载更改

docker-compose - Docker Compose 端口问题。无法在 localhost 上启动 docker 项目

docker - 如何在 docker 容器中安装 docker?