如何构建虚拟工作空间
在本文中,我将
Docker
通过一个真实案例来讲解如何使用容器作为开发工作区。我将讨论多个Dev Ops
相关主题。不过,这仍然是我在开源之旅中有机会实践的一个例子。
我们想要实现什么目标?
我有机会参与的一个很棒的开源项目是One 编程语言。这个项目的目标是创建一种名为One的编程语言。要构建项目并运行测试,你必须在你的机器上安装和配置一系列难以安装和配置的依赖项,例如Make
、LLVM
等等。此外,我们希望开发人员能够轻松参与并为项目做出贡献。因此,我们优先考虑使用 Docker 镜像来构建代码并运行测试。因此,我们为组织创建了这个精美的镜像。
在本文中,我将向您展示我们是如何做到这一点的,以及如何制作您自己的开发图像。
构建Docker
映像
首先,我们需要构建镜像。这部分其实没什么特别的,因为我们只需要Dockerfile
为镜像编写一个。然而,这个镜像的特别之处在于它包含的软件。通常,你应该安装运行项目和测试所需的软件包,以及像这样的版本控制系统git
。就我而言,我在轻量级alpine
基础镜像中包含了以下软件包:
FROM alpine:latest
LABEL The One Programming Language
# LLVM version
ARG LLVM_VERSION=12.0.1
# LLVM dependencies
RUN apk --no-cache add \
autoconf \
automake \
cmake \
freetype-dev \
g++ \
gcc \
libxml2-dev \
linux-headers \
make \
musl-dev \
ncurses-dev \
python3 py3-pip \
git
接下来,我设置了 reaming 包,例如LLVM
和pre-commit
。最后一个是一个用于管理和维护多语言pre-commit
钩子的强大框架。它是您开源项目的重要补充。因为Git hook
脚本有助于在提交代码审查之前识别一些简单的问题。我们在每次提交时运行钩子,以自动指出代码中的问题,例如缺少分号、尾随空格和调试语句。通过在代码审查之前指出这些问题,代码审查人员可以专注于变更的架构,而不会将时间浪费在琐碎的风格挑剔上。
# Build and install LLVM
RUN wget "https://github.com/llvm/llvm-project/archive/llvmorg-${LLVM_VERSION}.tar.gz" || { echo 'Error downloading LLVM version ${LLVM_VERSION}' ; exit 1; }
RUN tar zxf llvmorg-${LLVM_VERSION}.tar.gz && rm llvmorg-${LLVM_VERSION}.tar.gz
RUN cd llvm-project-llvmorg-${LLVM_VERSION} && mkdir build
WORKDIR /llvm-project-llvmorg-${LLVM_VERSION}/build
RUN cmake ../llvm \
-G "Unix Makefiles" -DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
|| { echo 'Error running CMake for LLVM' ; exit 1; }
RUN make -j$(nproc) || { echo 'Error building LLVM' ; exit 1; }
RUN make install || { echo 'Error installing LLVM' ; exit 1; }
RUN cd ../.. && rm -rf llvm-project-llvmorg-${LLVM_VERSION}
ENV CXX=clang++
ENV CC=clang
# pre-commit installation
RUN pip install pre-commit
现在一切都已完美配置,您可以复制项目目录,构建代码并运行测试,同时显示重要的日志:
# Work directory setup
COPY . /One
WORKDIR /One
# CMake configuration & building
RUN mkdir build
RUN cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ -H/One -B/One/build -G "Unix Makefiles"
RUN cmake --build ./build --config Debug --target all -j 6 --
# Change directory to build
WORKDIR /One/build
# Running example input.one
RUN ./lexer ../src/input.one log
RUN cat log
# Running tests
RUN ./lexer_test
RUN ./parser_test
RUN ./argument_test
# Tests Dashboard
CMD ctest --output-on-failure
部署到DockerHub
为此,您需要一个DockerHub
帐户。但是,只需要您的帐户用户名和凭据即可。因为我们将使用 部署它GitHub Actions
。与 类似pre-commit
,使用GitHub Actions
或任何CI\CD
工具都是很好的Dev Ops
做法。特别是我们将配置镜像以运行pre-commit
钩子、构建代码、运行测试,并将新镜像部署到DockerHub
。实际上,您只需对以下内容进行微小更改GitHub Workflow
即可在任何其他项目中使用它。
让我们开始配置GitHub Workflow
将在每个推送或拉取请求上运行的:
name: Dockerize One Programming language
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build-deploy:
name: Build and Publish Docker image
runs-on: ubuntu-latest
接下来,我们将添加GitHub Actions
部署到所需的配置步骤DockerHub
。特别是,您不需要任何其他的GitHub Actions
。因为您已经拥有一个Dockerfile
满足所有先决条件的!
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
我们将继续登录我们的DockerHub
帐户:
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{secrets.DOCKER_HUB_USERNAME}}
password: ${{secrets.DOCKER_HUB_PASSWORD}}
在我们进入下一步之前,您需要将secrets.DOCKER_HUB_USERNAME
和添加secrets.DOCKER_HUB_PASSWORD
到您的Github
存储库:
最后,将新图像发布onelangorg/one:latest
为DockerHub
:
- name: Build and Push to DockerHub
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: onelangorg/one:latest
别忘了配置缓存,这样就不用每次都重复那些不必要的配置步骤了。而且,这还能大幅缩短运行时间。我的情况是,没有缓存时运行时间大约是两个小时,但有缓存时通常不会超过一分半钟!
cache-from: type=registry,ref=onelangorg/one:latest
cache-to: type=inline
因此,您将在您的 docker 帐户中创建一个Docker
存储库。
将其用作工作区
在本节中,您需要提取已安装的docker
图像:DockerHube
VSCode
Remote-Containers
Docker
这个很棒的扩展允许通过打开容器内部的窗口进入容器本身VSCode
。
打开附加到容器的新窗口后,您可以打开开发目录:
现在您已经配置好了工作区并可以使用了!
结论
现在您已经读完了这篇文章,您应该明白使用Docker
、DockerHub
和的重要性,GitHub Actions
以及它们是多么容易使用。这些技术可以帮助开发人员提高工作效率,而无需重复配置工作区。每次拉取请求时,我们都会获得一个Docker
包含干净代码的更新镜像,并且由于pre-commit
、Github Actions
和缓存,我们可以成功运行测试。