使用 Docker 维护开发环境
您是否会考虑使用一个容器化的环境,您可以随时将其销毁,然后又重新创建,使其与之前一模一样?我最近开始这样做。这极大地提升了我的工作流程和生产力。
您是否会考虑使用一个容器化的环境,您可以随时将其销毁,然后又重新创建,使其与之前一模一样?
我最近开始这样做。这极大地提升了我的工作流程和生产力。下面我将尝试描述如何以及为何这样做。
当我们想到 Docker 时,我们通常会想到相对轻量级的容器实例,我们可以将它们组装起来构成各种应用程序。每个容器通常提供一个特定且高度独立的 خدمة,例如 REST API、数据库实例、内存缓存或任何其他服务,然后我们可以将它们编译成松耦合的解决方案。并且还具有可扩展性、低开销和成本效益,因为我们只在工作负载期间保持容器运行。这是常态。但实际上,使用 Docker 的基本方面之一在于我们可以创建任何我们想要的映像,以及其简洁性——在其他条件相同的情况下——Docker 映像配方使得根据 Dockerfile 的详细规范轻松构建出完全相同的环境。现在,我正在 Docker 容器中运行多个只有细微差别的基于 Ubuntu 的开发环境,我可以通过远程访问它们。它基于 Ubuntu 17.10,安装了 Visual Studio Code、一些扩展、浏览器、git。Postman,我推荐用于 API 测试。
为什么有人想这样做,去“Docker 化”一个完整、几 GB 大小的 Ubuntu 呢?我可以想到几个推广的论点:
- 环境的透明性。设置一台开发机器可能很繁琐,而且随着时间的推移,它不可避免地会被更新和旧安装的残留物等弄得杂乱不堪。Docker 启动的容器不会出现这种情况;任何更改都在 Dockerfile 中进行,我们很快就会养成销毁机器并重建的习惯。Docker 容器永远不会随着时间的推移而污染;它不会存在太久。
- Dockerfile 的版本控制成为一个主要因素。我们可以拥有多个不同的 Dockerfile,每个都适合其独特的项目。有些将包含与其他人不同的工具集。此外,重要的是,它不会包含解决您正在处理的特定问题所不需要的应用程序;如果不需要,就没有电子邮件应用程序、聊天应用程序或办公应用程序。当可能分散注意力的应用程序未安装时,很容易保持专注。
- 共享即关怀。我可以和我的同事在完全相同的开发环境上工作,因为我们都使用相同的开发设置。过去我曾为此遭受痛苦,因为出于某种原因我无法访问与同事相同的资源或安装相同的应用程序。一切都一样;它缩小了对项目的关注。当我需要将项目移交给旁边的开发人员时,我可以确信环境将按照我期望的方式运行。
- 我无需担心我的机器崩溃。并非在我职业生涯中发生了很多次,但确实有过几次无法恢复的崩溃。使用 Docker 环境,我只需要一台能运行 Docker 的机器。拉取 Docker 映像,启动容器,就可以开始工作了。
当然,也有其他选择。我经常使用虚拟机,我通过脚本进行配置和增强,无论是 Linux 上的 apt-get 还是 Windows 上的 Choco。但它们对我来说从未像 Docker 容器那样有效。它们也会随着时间的推移而污染,或者随身携带它们很不方便。Docker 容器更简单;“即时可用”的性质吸引了我。虚拟机占用大量空间,只有停止使用后才能收回;Docker 容器仅在使用时占用空间——尽管我们确实需要记得在使用后进行清理。
并非全是优点,当然也有一些缺点。如果我没有足够自律地将开发更改提交到源代码控制,那么,嗯,可以说 Docker 容器的注意力持续时间不长!但这真的就是我能提出的所有反对意见了。
我可以证明,将开发环境与项目特定的软件和配置相结合的潜力可以极大地提高生产力——我个人不会再回到维护自己的开发机器了。
说够了,让我们试试吧。如果您还没有安装 Docker 社区版,请先安装。然后,看看我下面的 Ubuntu 17.10 模板 Dockerfile,它安装了 VS Code 和一些相关扩展,以及 Firefox 浏览器、Postman API 开发工具以及我个人喜欢的一些其他工具。它被大量注释了,所以我想让注释自己来说明问题。
# Get the distro:
FROM ubuntu:17.10
ENV DEBIAN_FRONTEND=noninteractive
# Do some general updates.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* && apt-get clean && apt-get update -y && apt-get upgrade -y
RUN apt-get install -y software-properties-common
RUN add-apt-repository universe
RUN apt-get install -y cups curl sudo libgconf2-4 iputils-ping libxss1 wget xdg-utils libpango1.0-0 fonts-liberation
RUN apt-get update -y && apt-get install -y software-properties-common && apt-get install -y locales
# Let's add a user, so we have a chance to, well, actually use the machine.
ENV USER='thecoder'
ENV PASSWORD='password'
RUN groupadd -r $USER -g 433 \
&& useradd -u 431 -r -g $USER -d /home/$USER -s /bin/bash -c "$USER" $USER \
&& adduser $USER sudo \
&& mkdir /home/$USER \
&& chown -R $USER:$USER /home/$USER \
&& echo $USER':'$PASSWORD | chpasswd
# Let's add a super user, too. Same password
ENV SUDOUSER='theadmin'
ENV PASSWORD='password'
RUN groupadd $SUDOUSER \
&& useradd -r -g $SUDOUSER -d /home/$SUDOUSER -s /bin/bash -c "$SUDOUSER" $SUDOUSER \
&& adduser $SUDOUSER sudo \
&& mkdir /home/$SUDOUSER \
&& chown -R $SUDOUSER:$SUDOUSER /home/$SUDOUSER \
&& echo $SUDOUSER':'$PASSWORD | chpasswd
# Configure timezone and locale to en_US. __Change locale and timezone to whatever you want.__
ENV LANG="en_US.UTF-8"
ENV LANGUAGE=en_US
RUN locale-gen en_US.UTF-8 && locale-gen en_US
RUN echo "Europe/Copenhagen" > /etc/timezone && \
apt-get install -y locales && \
sed -i -e "s/# $LANG.*/$LANG.UTF-8 UTF-8/" /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=$LANG
# Create an keyboard-layout file, so we won't have to set it every time the machine starts. Just replace XKBLAYOUT="dk" with your layout, ex. "us".
# RUN printf '# Consult the keyboard(5) manual page.\nXKBMODEL="pc105"\nXKBLAYOUT="dk"\nXKBVARIANT=""\nXKBOPTIONS=""\nBACKSPACE="guess"\n'"" > /etc/default/keyboard
# - doesn't work :(
# set danish keyboard layout
# RUN setxkbmap dk - doesnt work :(
# Install some much needed programs - nano, midnight commander, guake terminal
RUN apt-get install nano -y
RUN apt-get install mc -y
RUN apt-get install guake -y
# Use the Xfce desktop. Because it's nice to look at, in my opinion.
RUN apt-get update -y && \
apt-get install -y xfce4
# There's also the MATE desktop-enviroment. Bit more light-weight.
#RUN apt-get update -y && \
# apt-get install -y mate-desktop-environment-extras
# Install git
RUN apt-get install -y git
# Install Python.
# Whoa, waitaminute - Ubuntu 17.10 already comes with Python 3.6 as default. Just run python3 to invoke it.
# Install Firefox
RUN apt-get install firefox -y
# Install Postman to 'opt' dir
RUN wget https://dl.pstmn.io/download/latest/linux64 -O postman.tar.gz
RUN tar -xzf postman.tar.gz -C /opt
RUN rm postman.tar.gz
# Install Visual Studio Code
ENV VSCODEPATH="https://go.microsoft.com/fwlink/?LinkID=760868"
RUN curl -fSL "${VSCODEPATH}" -o vscode.deb && dpkg -i vscode.deb
# To make it easier to automate and configure VS Code, it is possible to list, install,
# and uninstall extensions from the command line. When identifying an extension, provide
# the full name of the form publisher.extension, for example donjayamanne.python.
USER $USER
WORKDIR /home/$USER
# Enable viewing git log, file history, compare branches and commits - https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory
RUN code --install-extension donjayamanne.githistory
# Install Ms' python - linting, debugging, intellisense, etc.
RUN code --install-extension ms-python.python
# Install code outline provider - better code visualization in the explorer pane
RUN code --install-extension patrys.vscode-code-outline
# Annnnnd back to root for the remainder of this session.
USER root
# Install nomachine, the remote-desktop server that enables us to remote into the container image.
# You don't have to rely on my choice of NoMachine - just go to their website and get a different one, if you want.
ENV NOMACHINE_PACKAGE_NAME nomachine_6.1.6_9_amd64.deb
ENV NOMACHINE_MD5 00b7695404b798034f6a387cf62aba84
RUN curl -fSL "http://download.nomachine.com/download/6.1/Linux/${NOMACHINE_PACKAGE_NAME}" -o nomachine.deb \
&& echo "${NOMACHINE_MD5} *nomachine.deb" | md5sum -c - \
&& dpkg -i nomachine.deb
# Create an executable file that starts the NoMachine remote desktop server.
# A unix executable .sh-file must start with #!/bin/bash. '\n' means 'newline'.
# Note how the file ends with a /bin/bash-command. That's deliberate, it allows
# us do - don't ask me how - keep the container running when we use it later.
RUN printf '#!/bin/bash\n/etc/NX/nxserver --startup\n/bin/bash'"" > /etc/NX/nxserverStart.sh
# Now make the executable _actually_ executable ...
RUN chmod +x /etc/NX/nxserverStart.sh
# ... and start the nomachine-remote server when the container runs, and ...
CMD ["/etc/NX/nxserverStart.sh"]
#... happy developing! Use a NoMachine-client program to log into the server.
# PS: remember to run the container with the -d and -t arguments.
# Check the readme.md file, https://github.com/harleydk/linuxRemoteDocker/blob/master/README.md
如果您是 Docker 的新手,希望这些注释能让您更清楚这里发生了什么。我们首先下载一个 Linux 发行版,然后执行一系列 RUN 命令,这些命令在我们构建映像时执行。这还包括设置用户和超级用户。将文件保存为“Dockerfile”,不带扩展名,然后在该新 Docker 配方的目录中执行……
docker build -t ‘linux_remote_pc’ .<br />
……命令。然后坐下来等一会儿;配方的各个步骤将执行,映像将被构建。现在是时候使用它了。该映像安装并运行一个 NoMachine 服务,通过 NoMachine 客户端应用程序实现远程桌面连接。它速度快且免费。所以,请从他们的网站 https://www.nomachine.com/download 下载一个客户端,并通过执行以下命令来启动一个由刚刚构建的 Docker 映像创建的 Docker 容器。
docker run -d -t -p 4000:4000 --name=linux_remote_pc --cap-add=SYS_PTRACE linux_remote_pc_image
这将启动一个实例,即所谓的“Docker 容器”,将 Docker 主机的端口 4000 映射到容器的端口 4000——我们将连接到该端口,以便远程访问容器。因此,在与 Docker 主机同一网络中的机器上,启动 NoMachine 客户端并连接。
……其中“localhost”当然是运行 Docker 容器的机器的主机名。连接到容器后,您应该会看到这个。
机器告诉我们它缺少一些基本配置——这是因为我们是无人值守安装的,以便一开始不必处理所有那些设置选项。只需按“使用默认配置”即可。
就是这样——您现在拥有一个安装了 VS Code 的机器。
如果您是 Docker 的新手,有很多教程和文档可供参考。强烈建议尝试在“hello world”Dockerfile 上执行构建命令,而不是上面稍微复杂一些的。至少可以熟悉命令行界面和命令响应。
上面的 Dockerfile 保存在我的 github 仓库 https://github.com/harleydk/linuxRemoteDocker 中,您可以随意克隆。那里还有一些进一步的文档。
如果您觉得它有用,或者我可以在某些方面提供帮助,我非常希望收到您的反馈。所以请在评论中给我留言,或者创建一个新的 github issue https://github.com/harleydk/linuxRemoteDocker/issues,我会尽力而为。
感谢阅读,祝您开发愉快。