提示:在继续阅读之前,请注意此文章最后更新于 1570 天前,其中的部分内容可能已经无效或过时。

在公司转到linux下开发已经有一年多了,通过docker进行容器化开发也有一段时间了。借着这次自己电脑重装系统,准备由原来的win下开发转换到和在公司相同的wsl2+docker容器化开发环境。顺便将本地的blog切换到wsl2,mongodb数据库切换到docker
也借机将之前随手写的一些踩坑记录整理一下,以备下次查用

安装vscode远程插件

vscode远程化开发真的是太棒了。中间因为学习groovy的原因,下载过IntelliJ。也不知道是否是我不会用,体验比起vscode差太多了
首先Extensions里搜索remote,排名前几的统统安装。大概的作用是:

  • Remote - WSL: vscode远程连接wsl
  • Remote - Containers: vscode远程连接docker container
  • Remote - SSH: 远程连接服务器(通过ssh)
  • Remote - SSH: Editing Configuration Files: 这个我没仔细看,应该是引导你进行配置文件配置的
  • Remote Development: 允许你打开容器里的任意目录(通过code .)

然后取你需要的,我这里因为有wsl2的关系,所以远程连接服务器相对用的比较少。这里就不做记录了。只记录wsl2和docker容器相关的内容。

安装wsl2

参考wsl2采坑记录

安装docker

参考 docker安装和踩坑记录

添加一个.devcontainer配置

官网有非常详细的配置和介绍,这里只记录满足简单开发的配置。
首先

有两种配置方式dockerfiledocker-compose。这里我需求比较简单,就使用dockerfile的形式
创建好后会有一个.devcontainer的目录,目录内包含devcontainer.jsondockerfile两个文件
devcontainer.json包含一些配置,这些配置会在构建镜像的时候生效,也可以传递一些环境变量给dockerfile使用
dockerfile则是用于构建这个镜像的配置文件。这里列一些常用环境的搭建

node

node环境的搭建使用这个基础镜像mcr.microsoft.com/vscode/devcontainers/typescript-node:0-14。此镜像具有git、typescript、node环境。但是由于微软官方的镜像拉取速度奇慢无比,几乎拉不下来。而且内网访问不到。所以在网上找到了这位老哥(下方参考)的仓库地址,可以直接从他的docker仓库拉取镜像。不过一般不建议这样做,因为第三方镜像很可能被修改过
配置如下:

// .devcontainer.json
{
	"name": "Node.js & TypeScript",
	"build": {
		"dockerfile": "Dockerfile",
		// Update 'VARIANT' to pick a Node version: 10, 12, 14
		"args": {
			"VARIANT": "14"
		},
	},
	"mounts": [
		"source=/root/.ssh,target=/root/.ssh,type=bind,consistency=cached",
		"source=/root/.npm,target=/root/.npm,type=bind,consistency=cached",
		"source=/usr/local/share/.config/yarn/global,target=/usr/local/share/.config/yarn/global,type=bind,consistency=cached",
		// "source=/usr/local/bin,target=/usr/local/share/npm-global/bin,type=bind,consistency=cached"
	],
	// Set *default* container specific settings.json values on container create.
	"settings": {
		"terminal.integrated.shell.linux": "/bin/bash"
	},
	// Add the IDs of extensions you want installed when the container is created.
	"extensions": [
		"dbaeumer.vscode-eslint"
	],
	"workspaceFolder": "/workspaces/node/_q",
	"remoteUser": "root"
}
ARG VARIANT="14-buster"
FROM vscode_typescript_node:0-${VARIANT}

需要注意的点有:

  • mount用来将宿主机上的文件目录挂在到docker容器。这里我主要想缓存npm包、映射全局yarn包和映射git配置(用于在容器中拉去git仓库)
  • workspaceFolder用来指定启动容器后所在的目录
  • remoteUser用来指定登录的用户,我为了图省事直接指定了root。一般需要自己在dockerfile中创建普通用户并赋予权限(推荐)
    配置好之后,就可以选择Remote-containers:Reopen in Container(上面创建配置文件的选项上面那一项)启动了
    启动之后如图:

在宿主机执行docker ps的话,会看到这个正在运行的容器实例:

每次退出,并不会销毁这个实例,只是stop。下次重新通过上面的Remote-containers:Reopen in Container连接到容器的时候,就会重启这个容器
因此你在容器里的操作,并不会因为退出了vscode而消失
但是有时候会有一些特殊的原因删除掉这个容器实例(比如docker system prune)。这时候再次连接就会新创建一个容器连接,之前所做的修改就全部丢失了(除了.devcontainer所在的目录,vscode自动帮你做了映射)。这就是为什么需要配置一些映射目录,以持久化容器中的修改
当然也可以每次都通过这个容器创建一个镜像,然后修改dockerfile中的基础镜像。但是不如映射目录来的方便
每次修改.devcontainer相关的配置,vscode都会提醒你重新rebuild。另外在任意路径下执行code .可以新打开一个vscode窗口连接到容器,并定位到当前目录,这是最上方提到的Remote Development插件提供的

参考:
Node.js & TypeScript
VS Code Remote Development Container Images
Newbe.McrMirror
mcr_mirror.json

python

python的配置vscode也内置了,和node执行一样的步骤即可。不同的是,由于上面说的微软官方镜像不好拉取,所以我使用最新的python镜像代替了mcr.microsoft.com/vscode/devcontainers/python:0-3
直接docker pull python即可拉取python最新的镜像。然后修改一下dockerfile

# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
# ARG VARIANT="3"
# FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
FROM python:latest

maven

maven的配置就复杂一些了,涉及到了根据提供的参数是否下载相应的插件、创建用户并赋予权限。进阶学习的话,建议研究一下

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.155.1/containers/java-8/.devcontainer/base.Dockerfile

FROM java:0-8

# [Option] Install Maven
ARG INSTALL_MAVEN="false"
ARG MAVEN_VERSION=""
# [Option] Install Gradle
ARG INSTALL_GRADLE="false"
ARG GRADLE_VERSION=""
RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk flush candidates && sdk install maven \"${MAVEN_VERSION}\""; fi \
    && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi

# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi