[Docker] DevContainer高效开发(第一篇):基于remote container开发

简介: VS Code的Dev Containers简化了Python的容器化开发,将开发环境与应用一同打包在Docker中,消除环境配置问题。这种方式使得多语言、多版本开发变得整洁高效。

@[toc]

1. dev container

docker和容器化技术让运维有了质的飞跃,从此,部署软件再也无需担心软件运行所需的繁杂环境,只要拉取镜像然后运行就可以将应用连带其部署的环境一步到位。

但是回想起我们的开发过程,谁还不是依然需要先安装一堆环境(编译器、库等等),然后才能进行开发。如果我们恰好还需要开发各种语言、各种应用,那光是繁杂的环境就足以把电脑搞的乱糟糟。更何况,大多数语言会拥有很多版本,而且版本之间兼容性不佳(例如Python),在自己电脑上安装多个版本的python有时候已经让人血压升高,何况我还要记得哪个版本在哪,哪个版本的库在哪,不同的版本用的是哪一个包管理器等等繁琐的细节……

于是,dev container的想法就产生了。顾名思义,就是在容器中开发。这样一来,开发的应用连带这开发环境就被”连根拔起“,以后就再也不需要担心重新配置开发环境的麻烦了,要做的仅仅是确认一下机器上有没有docker,然后运行一个容器开发就可以。

下面就以python为例,来说明一下如何使用vscode进行容器化开发。vscode中的远程开发和容器开发插件让dev container从概念变成了现实。

2. 安装插件

我不想将容器运行在本地,于是采用了先远程开发连接服务器,再使用服务器上的容器开发的方式。但是不管怎样,本地vscode上安装了插件才能和远程连接开发。

要安装的核心插件是ms-vscode-remote.remote-ssh和ms-vscode-remote.remote-containers两个。如图所示:
image.png

安装之后,可以在左侧看到远程连接的选项卡,进入后如图所示:
image.png

上面的下拉框可以切换是主机还是container。我们要做的是先ssh连接一台主机,再打开这个选项卡选到containers,就可以管理主机上的容器了。

3.配置文件

容器化开发的容器配置应该是因项目而异的。因为对于每个项目,所需要的环境都不尽相同。就算是两个python项目,开发中用到的包也不一样,不应该使用一个容器开发多个项目。因此,项目的容器配置会放在项目目录下。vscode已经为我们准备好了范式,我们可以在项目下使用.devcontainer目录,存放devcontainer.json和Dockerfile、docker-compose.yaml文件。

devcontainer.json是vscode对容器的配置文件,里面存放了要启动或构建的镜像、要附带安装的vscode插件、创建后执行的命令等一系列信息。Dockerfile中描述了我们特定项目需要的容器应该怎么构建。虽然可以直接使用一个官方镜像开发,但是最好还是做一些定制化,构建项目个性化的镜像。docker-compose.yaml中指定了镜像应该如何运行。

以下就是python项目中对应配置文件的示例:devcontainer.json:


// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.202.3/containers/python-3
{
   
   
    "name": "Python 3",
    "build": {
   
   
        "dockerfile": "Dockerfile",
        "context": "..",
        "args": {
   
    
            // Update 'VARIANT' to pick a Python version: 3, 3.9, 3.8, 3.7, 3.6.
            // Append -bullseye or -buster to pin to an OS version.
            // Use -bullseye variants on local on arm64/Apple Silicon.
            "VARIANT": "3.9",
            // Options
            "NODE_VERSION": "lts/*"
        }
    },

    // Configure tool-specific properties.
    "customizations": {
   
   
        // Configure properties specific to VS Code.
        "vscode": {
   
   
            // Set *default* container specific settings.json values on container create.
            "settings": {
   
    
                "terminal.integrated.profiles.linux": {
   
   
                    "bash": {
   
   
                        "path": "/bin/bash"
                    }
                },
                "python.defaultInterpreterPath": "/usr/local/bin/python",
                "python.languageServer": "Default",
                "python.linting.enabled": false,
                "python.linting.pylintEnabled": false,
                "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
                "python.formatting.blackPath": "/usr/local/py-utils/bin/black",
                "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
                "python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
                "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
                "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
                "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
                "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
                "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
            },

            // Add the IDs of extensions you want installed when the container is created.
            "extensions": [
                "ms-python.python",
                "formulahendry.code-runner"
                // "ms-python.vscode-pylance"
            ]
        }
    },

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [9000],

    // Use 'portsAttributes' to set default properties for specific forwarded ports. More info: https://code.visualstudio.com/docs/remote/devcontainerjson-reference.
    // "portsAttributes": {
   
   
    //     "9000": {
   
   
    //         "label": "Hello Remote World",
    //         "onAutoForward": "notify"
    //     }
    // },

    // Use 'otherPortsAttributes' to configure any ports that aren't configured using 'portsAttributes'.
    // "otherPortsAttributes": {
   
   
    //         "onAutoForward": "silent"
    // },

    // Use 'postCreateCommand' to run commands after the container is created.
    "postCreateCommand": "pip3 install -r requirements.txt",

    // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    "remoteUser": "root",
    // claws: use this option to run as root in container, else you can not save file because the project is in /root
    "containerUser": "root"
}

几个需要说明的地方:

  • build.args中指定了一些构建镜像时带入的参数,会影响具体应用的构建。
  • customization.vscode.extensions中指定了容器中要安装的插件,vscode创建开发容器时会自动安装这些插件。
  • postCreateCommand中指定了容器创建成功后要执行的操作,通常可以在这里安装依赖。
  • containerUser指定了容器运行的时候采用什么用户,默认是vscode,这里改成root,避免项目放在宿主机的/root下导致容器中修改无权限的情况。(因为容器运行时,项目目录是挂载到宿主机的)
  • remoteUser指定了连接到容器使用的用户名,暂时还没搞清用途。。

Dockerfile:


# See here for image contents: https://github.com/microsoft/vscode-dev-containers/blob/v0.202.3/containers/python-3/.devcontainer/base.Dockerfile
# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
ARG VARIANT=3.9
FROM mcr.microsoft.com/devcontainers/python:0-${
   
   VARIANT}
# [Optional] Allow the vscode user to pip install globally w/o sudo
# ENV PIP_TARGET=/usr/local/pip-global
# ENV PYTHONPATH=${PIP_TARGET}:${PYTHONPATH}
# ENV PATH=${PIP_TARGET}/bin:${PATH}
# RUN if ! cat /etc/group | grep -e "^pip-global:" > /dev/null 2>&1; then groupadd -r pip-global; fi \
#     && usermod -a -G pip-global vscode \
#     && umask 0002 && mkdir -p ${PIP_TARGET} \
#     && chown :pip-global ${PIP_TARGET} \
#     && ( [ ! -f "/etc/profile.d/00-restore-env.sh" ] || sed -i -e "s/export PATH=/export PATH=\/usr\/local\/pip-global:/" /etc/profile.d/00-restore-env.sh )
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
# ARG NODE_VERSION="none"
# RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
COPY requirements.txt /tmp/pip-tmp/
RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
   && rm -rf /tmp/pip-tmp
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install --no-install-recommends git
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1

简单说明:

  • 开头指定了一个arg,和上面devcontainer.json文件中的对应,声明的参数值会在创建容器的时候被devcontainer.json文件中的参数值替换。
  • 后面可以规定一些依赖进行安装,也可以安装一些额外的软件包。尽量使用这份示例中的参数,避免生成缓存,增大镜像的大小。

    4.使用技巧

    安装远程插件后,vscode打开项目目录时会自动循环是否启动container后重新打开,选是就可以快速构建启动容器,然后再容器中打开挂载的项目目录进行开发。如果后来对容器配置进行了修改,可以用Ctrl+Shift+p快速打开命令面板,输入dev container rebuild,选择搜索出来的选项进行重新构建打开:
    image.png

启动的开发容器会自动运行在docker后台,在remote插件中可以对容器进行管理,包括start、stop、remove等,而且状态一目了然,非常方便。

目录
相关文章
|
23天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。
|
2月前
|
Java Docker 索引
Springboot的Container Images,docker加springboot
本文介绍了如何使用Spring Boot的层索引文件和Docker优化Spring Boot应用程序的容器化过程,包括解压缩可执行jar和创建分层Docker映像的方法。
33 9
Springboot的Container Images,docker加springboot
|
27天前
|
Kubernetes Docker 容器
【赵渝强老师】Docker的Container网络模式
Docker容器在网络环境中彼此隔离,但可通过配置不同网络模式实现容器间通信。其中,container模式使容器共享同一网络命名空间,通过localhost或127.0.0.1互相访问,提高传输效率。本文介绍了container模式的特点及具体示例。
|
2月前
|
存储 持续交付 开发者
掌握Docker容器化:提升开发效率与应用部署
【10月更文挑战第4天】在现代软件开发中,Docker容器化技术因其轻量级、可移植和快速部署的特点,成为提升开发效率和简化部署流程的关键工具。本文介绍了Docker的基本概念、核心组件及其优势,并探讨了如何在开发环境中搭建、微服务架构及CI/CD流程中有效利用Docker,助力软件开发更加高效便捷。
|
3月前
|
持续交付 开发者 Docker
掌握 Docker:容器化技术在现代开发中的应用
Docker 是一个开源容器化平台,使开发者能够将应用程序及其依赖项封装在轻量级容器中,确保跨平台的一致性。本文介绍了 Docker 的基本概念、核心组件及优势,并展示了其在快速部署、一致性、可移植性和微服务架构中的应用。通过示例说明了 Docker 在本地开发环境搭建、服务依赖管理和 CI/CD 流程中的作用,以及多阶段构建、资源限制和网络模式等高级特性。掌握 Docker 可大幅提升开发效率和应用管理能力。
|
3月前
|
Unix Shell Linux
5-15|Docker报错OCI runtime exec failed: exec failed: unable to start container process: exec: “/bin/ba
5-15|Docker报错OCI runtime exec failed: exec failed: unable to start container process: exec: “/bin/ba
|
4月前
|
容器 C# Docker
WPF与容器技术的碰撞:手把手教你Docker化WPF应用,实现跨环境一致性的开发与部署
【8月更文挑战第31天】容器技术简化了软件开发、测试和部署流程,尤其对Windows Presentation Foundation(WPF)应用程序而言,利用Docker能显著提升其可移植性和可维护性。本文通过具体示例代码,详细介绍了如何将WPF应用Docker化的过程,包括创建Dockerfile及构建和运行Docker镜像的步骤。借助容器技术,WPF应用能在任何支持Docker的环境下一致运行,极大地提升了开发效率和部署灵活性。
142 1
|
4月前
|
机器学习/深度学习 Kubernetes Docker
机器学习开发的灵药:Docker容器
机器学习开发的灵药:Docker容器
|
4月前
|
Docker 容器
【Azure 应用服务】App Service for Container 无法拉取Docker Hub中的镜像替代方案
【Azure 应用服务】App Service for Container 无法拉取Docker Hub中的镜像替代方案
|
4月前
|
存储 Linux Docker
【Azure 应用服务】应用服务中发布Docker Container,如何添加卷(如Azure File Share)以便永久存储文件
【Azure 应用服务】应用服务中发布Docker Container,如何添加卷(如Azure File Share)以便永久存储文件