Docker作为综合开发环境

2021-04-04 13:39:04

建立一个便携式的IDE来运行任何地方(只要你有Docker)

许多写代码的人是安装软件(例如Apache Webserver,Nginx,PHP,NodeJS,Java,Scala,(Neo)Vim,Eclipse和许多人,他们需要能够执行开发任务在他们的本地机器上。

这是不可避免的,我会得到一台新机器,我需要se tup并配置它只是习惯的方式。设置新计算机时,我必须记住我需要的东西,请下载所有这些东西,安装它们,配置它们并确保他们工作。毫无疑问,我会忘记一个设置或包裹,它会回来咬我的背后。然而,很多人通过使用像Assible这样的东西自动化这一点。即使通过自动化,这可能需要时间。使用Docker的一个好处是自动化作为过程的一部分。

单个依赖 - Docker。就像在构建软件应用程序时一样,与您的包裹捆绑依赖关系是非常好的。只要我可以访问Docker,我也可以工作 - 即使是其他人的机器也是如此。我可以简单地下载我的IDE映像和OFF I OFF。

开发者体验。在设置成本方面,特别是最初,在本地安装所有内容并不大得多,并且您最终会有所不同(在我看来)更灵活的工作环境。真正的好处来自图像的重复使用。

选择基础图像可能相当令人生畏。我总是是我的应用程序容器的Alpine Linux的粉丝,所以这就是我选择的。阿尔卑斯山也有利于微小的尺寸,使IDE更便携。总共安装并配置了一切,图像是< 400MB,我确定有一些改进我可以制作。在一个新的dockerfile中,从以下开始:

我的环境的核心是为了支持我的工作流程。我是(neo)vim的狂热粉丝,并使用它作为我的编辑器和git(& git-perl)进行源代码管理。我使用TMUX将我的终端窗口拆分为许多窗格,并且为“标签”和ZSH是一个很好的可配置shell。我还需要为Tmux插件管理器安装Bash和Ncurses工作。 openssh客户端才能sshing。卷曲,少和男人是其他有用的实用程序。

run apk添加-u --no-cache \ neovim git git-perl \ zsh tmux openssh-client bash ncurses \卷曲少人

我喜欢用哦,我的zsh!使用zsh,所以我需要安装它:

我不能忘记将我的zshrc,vimrc和tmux.conf复制到我的环境中:

#安装VIM插头用于插件管理运行curl -flo〜/ .config / nvim / autoload / plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim#安装插件运行nvim + pluginstall + qall>> / dev / null#安装tmux插件管理器运行git clone https://github.com/tmux-plugins/tpm .tmux / plugins / tpm#安装插件运行.tmux / plugins / tpm / bin / install_plugins

您可能会想到“但如果我想运行Docker命令,那么我需要主机上的终端”。没有。 Docker非常简洁,因为客户端使用UNIX套接字与守护程序通信。当我启动进入容器时,我可以将该套接字安装到容器中,以便我可以向套接字发出命令,只要我安装了客户端即可。将Docker添加到APK安装命令,并在运行图像时,只需传递-v /var/run/docker.sock:/var/run/docker.sock。然后在容器中,任何Docker命令都应按预期工作。

我还使用Docker-Compose,但这不是可以使用APK安装的包。我必须在dockerfile中添加py-pim到我的apk安装:

run apk添加-u --no-cache \ neovim git git-perl \ zsh tmux openssh-client bash ncurses \卷曲少于人\ docker py-pip运行pip安装docker-compose

由于容器对底层文件系统结构没有了解,因此如果我希望能够共享我的项目目录,我需要了解主机上的出现情况。寄存器的路径需要在主机上绝对,而不是在IDE容器上,因为主机文件系统是守护程序知道的。从IDE中启动新容器时,您只需指定如此:

免责声明:安全&当涉及Docker容器时,用户权限可能是最大主题中的两个,它们并不完全直截了当。我没有专家,我发现并为我做了什么。

我实际上希望能够编辑文件,默认情况下,默认情况下,所有命令都在容器中作为root用户运行。但这还使我能够编辑我当前用户没有(&不应该)的文件有权修改/ etc中的文件。

我所做的是创建一个名为ME的新用户并在该用户主目录中安装了容器中的所有内容,将$ HOME设置为同一目录:

#创建一个名为' me'运行useradd -ms / bin / zsh me#从现在在该用户家庭目录Workdir / home / me env主页/ home / me

这一切都很好,但我需要映射新的用户&将集团ID对我的本地用户。我创建了一个脚本,即将在运行时用作进入点(entrypoint.sh)进入容器中的脚本。有了它,我将创建一个与我的本地组相同的id的组,然后修改创建的用户我拥有本地用户的相同ID(通过将一些环境变量添加到我的情况下docker运行命令):

#!/ bin / sh#get标准cali user_id变量user_id = $ {host_user_id:-9001} group_id = $ {host_group_id:-9001}#更改' me' UID托管用户'如果[! -z" $ user_id" ]&& [" $(id -u me)" !=" $ user_id" ];然后#如果它不存在GroupAdd(Non-upound -g" $ group_id&#34)创建用户组组#设置用户' s uid和gid usermod - non-unique --uid" $ user_id" --gid" $ group_id"我

当我在dockerfile中安装并复制所有内容时,我实际上是root用户。所以我投入/家/我的一切都是由root拥有的。如果我打算在容器中像我一样在容器中运行.zshrc,.vimrc&由于权限问题使用对方程序时,将无法拾取.gitconfig。所以在我的entrintpoint.sh中,我在该目录中正确的所有内容都在正确设置权限(我也需要在/var/run/docker.sock上运行known才能使用docker):

SU-EXEC(Switch User& Execute)是我用作Restnpoint.sh中的最后一件事的程序,以将我推向一个Tmux shell作为ME用户。

将脚本添加到容器中,并将其设置为运行容器时要运行的默认命令:

#ceastpoint脚本可以切换U / G id' s和`chown`s copy entrostpoint.sh /bin/entrypoint.sh #semet worksports workdir / workspace#defaure entrypoint,可以覆盖cmd [&# 34; /bin/entrypoint.sh"]

运行以下运行命令将通过用户/组ID映射和权限设置所需的额外环境变量。

Docker Run-it-rm \ -v / path / to / host / workspace:/ workspace \ -e host_user_id = $(id -u $ user)\ -e host_group_id = $(id-g $ user)\ ls12styler / IDE:最新

我可以刚刚烘焙我的名字和电子邮件地址进入容器中的.gitconfig,但这将是坏的。不仅我的电子邮件地址和名称在我的源代码中公开,而且它也稍后不仅便于便携(稍后无法​​更改这些详细信息)。在entrypoint.sh脚本中,在顶部,我可以使用git设置自己的配置:

#!/ bin / sh#git配置如果[! -Z" $ git_user_name" ]&& [! -z" $ git_user_email" ];然后git config - global user.name" $ git_user_name" git config - global user.email" $ git_user_email" ......

运行容器时,我可以通过更多的环境变量来在运行时设置我的Git用户信息:

Docker Run-it-rm \ -v / path / to / host / workspace:/ workspace \ -e host_user_id = $(id -u $ user)\ -e host_group_id = $(id -g $ user)\ -e git_user_name ="我的名字" \ -e git_user_email =" [email protected]" \ LS12Styler / IDE:最新

秘密管理是构建任何软件的重要组成部分。我想做的一件事要进一步提高我的IDE的可移植性,从Haishicorp拱顶等东西获取我的SSH键和其他安全相关的东西。我可能必须自己运行这样的服务,所以除了这样做,我目前将我的秘密分发到主机上,然后将我的SSH键绑定到容器中:

Docker Run-it-rm \ -v / path / to / host / workspace:/ workspace \ -e host_user_id = $(id -u $ user)\ -e host_group_id = $(id -g $ user)\ -e git_user_name ="我的名字" \ -e git_user_email =" [email protected]" \ -V〜/ .ssh:/ home/me/.ssh \ ls12styler / IDE:最新

您将注意到,在IDE中,我不会安装任何编译/运行时依赖项,例如nodejs或scala本身。这里的诀窍是将这些这样的“环境”分为自己的自包含图像。

有丰富的这些图像可用,但找到合适的图像可能很棘手。此外,开发人员始终拥有自己的首选方式。作为一个例子,我构建了我自己的Scala映像(基于另一个用户'),以便在我的开发环境中使用。原始的差异主要是在图像启动时设置工作目录和默认命令。

当我在Scala应用程序上工作时,我运行一个终端窗口,分为两个终端窗口。 一个拆分,运行Scala / SBT容器,以及运行Vim的拆分。 要运行scala容器,我可以运行: 与任何东西一样,可能有改进的余地。 Linux命名空间中的内容将有助于解决用户权限问题,这意味着我可能不需要创建用户& 组,不必在启动时设置文件权限。 Docker Volumes也可以帮助帮助解决问题。 卷也可能有助于使容器从主机中孤立,从而删除对主机绑定卷的需求。 目前我有什么工作,我在家里和工作中成功运行了这一点。 与654MB拉伸的Intellij Idea相比,由此产生的Docker图像的大小小于400MB。 当我有机会时,我会看看它更加便携。 希望包括秘密管理和更好的权限/用户处理。