vscode code server 配置 golang 和 php 开发环境(2)

去年更新了两篇blog,记录了怎么搭建 vscode code server,以及配置golang和php环境的。 一年过去了,我对它们又做了一些更新,完善了golang debug、k8s源码开发、配置同步、ide增量build、docker等方面的支持。

一、为什么不用本地ide

Q:为什么不用本地ide,毕竟本地ide功能要强大很多。

A:客观原因是设备太多了。我有1台办公Win,4台开发机Linux,1台个人Mac,1台家庭Win,1个iPad。如此多的设备和平台,我不希望只给1-2台配置开发环境,太受束缚了。

以前的我在所有设备上都配置了开发环境,用的是IntelliJ IDEA。公司的主要用go,个人主要用php和vue,有时也做一些Android的。配环境总是让人苦恼的一件事,如果遇上重装系统,那就更痛苦了。

当然还有一个问题,就是运行ide其实是个挺费系统性能的事情,我目前还在使用 2012版的 Macbook Air,这样的配置跑个ide就烫手了。

image-20220128104827591

Q:为什么不用JetBrains的Fleet?

A:因为Fleet出来太晚了,目前用vscode还是很好的。

二、dockerfile

另外特别要注意的是我是在x86_64的机器上使用的,所有的镜像均为intel的cpu。

镜像编译主要的难点还是区分在国内还是国外。先假定我们的环境到大部分地区都是可达的,我直接在dockerfile中下载go、php和docker_cli,所以有如下的dockerfile。

FROM kelvinblood/code-server:base-20210903

LABEL org.kelu.image.version.go=1.16.7
LABEL org.kelu.image.version.php=7.1.5
LABEL org.kelu.image.version.code-server=3.11.1
LABEL org.kelu.image.version.vscode=1.57.1
LABEL org.kelu.image.version.dockercli=19.03.14

ARG DOCKER_CLI_VERSION=19.03.14
ARG GOLANG_VERSION=1.16.7
ARG PHP_VERSION=7.1.5
ENV GOROOT /usr/local/go
ENV GOPATH /var/local/go
ENV PATH $PATH:$GOROOT/bin:$GOPATH/bin
ENV GO111MODULE on
ENV GOPROXY https://goproxy.cn

RUN \
  GO_TGZ=go$(echo "$GOLANG_VERSION").linux-amd64.tar.gz && \
  PHP_TGZ=php-${PHP_VERSION}.tar.gz && \
  DOCKER_TGZ=docker-ce-cli_${DOCKER_CLI_VERSION}~3-0~debian-stretch_amd64.deb && \
  echo "**** install tools ****" && \
  apt-get update && \
  apt-get install -y \
    wget \
    iputils-ping \
    build-essential \
    xinetd \
    telnetd \ 
    rsync \
    jq \
    python-pip && \
  pip install pyyaml && \
  cd /tmp && wget https://download.docker.com/linux/debian/dists/stretch/pool/stable/amd64/${DOCKER_TGZ} && \
  dpkg -i *.deb && \
  echo "**** install golang ****" && \
  cd /tmp && wget https://golang.org/dl/${GO_TGZ} && \
  tar zxvf ${GO_TGZ} >/dev/null 2>&1 && \
  mv go ${GOROOT} && \
  echo "**** go get for vscode ****" && \
  go get golang.org/x/tools/gopls && \
  go get golang.org/x/lint/golint && \
  go get github.com/rogpeppe/godef && \
  go get github.com/ramya-rao-a/go-outline && \
  go get github.com/uudashr/gopkgs/v2/cmd/gopkgs && \
  go get github.com/cweill/gotests/gotests && \
  go get github.com/fatih/gomodifytags && \
  go get github.com/josharian/impl && \
  go get github.com/haya14busa/goplay/cmd/goplay && \
  go get github.com/go-delve/delve/cmd/dlv && \
  go get honnef.co/go/tools/cmd/staticcheck && \
  go get github.com/spf13/cobra/cobra && \
  cp /var/local/go/bin/dlv /var/local/go/bin/dlv-dap && \
  echo "**** install php ****" && \
  apt-get -y install libssl-dev libcurl4-openssl-dev libbz2-dev libjpeg-dev libpng-dev libgmp-dev libicu-dev libmcrypt-dev freetds-dev libxslt-dev libcurl3-dev autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c && \
  ln -s /usr/lib/x86_64-linux-gnu/libsybdb.a /usr/lib/libsybdb.a && \
  ln -s /usr/lib/x86_64-linux-gnu/libsybdb.so /usr/lib/libsybdb.so && \
  ln -s /usr/lib/x86_64-linux-gnu/libct.a /usr/lib/libct.a && \
  ln -s /usr/lib/x86_64-linux-gnu/libct.so /usr/lib/libct.so && \
  ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h && \
  ln -s /usr/include/x86_64-linux-gnu/curl /usr/include/curl && \
  cd /tmp && wget http://am1.php.net/distributions/${PHP_TGZ} && \
  tar -xzvf ${PHP_TGZ} && \
  cd php-${PHP_VERSION} && \
  ./configure --prefix /usr/share/php7 --enable-fpm --enable-mbstring --enable-zip --enable-calendar --enable-bcmath --enable-exif --enable-intl --enable-opcache --enable-shmop --enable-soap --enable-sockets --with-fpm-user=www-data --with-fpm-group=www-data --with-pcre-regex --with-kerberos --with-openssl --with-mcrypt --with-zlib --with-bz2 --with-curl --with-gd --with-jpeg-dir=/usr/include/jpeg8 --with-png-dir=/usr/include/libpng12 --with-gettext --with-gmp --with-mhash --with-xsl && \
  make clean && make && make install && make test && make clean && \
  ln -s /usr/share/php7/sbin/php-fpm /usr/local/bin/php-fpm && \
  ln -s /usr/share/php7/bin/php /usr/local/bin/php && \
  cd .. && \
  curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer && \
  echo "**** vscdoe tools ****" && \
  /usr/local/bin/code-server --install-extension ms-ceintl.vscode-language-pack-zh-hans && \
  /usr/local/bin/code-server --install-extension vscodevim.vim && \
  /usr/local/bin/code-server --install-extension golang.Go && \
  mkdir -p /config/extensions && \
  mv /config/.local/share/code-server/extensions/* /config/extensions && \
  echo "**** clean up ****" && \
  apt-get clean && \
  rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*

主要做了几件工作:

  1. 配置常用的软件。有些是k8s编译必须的一些软件。
  2. go和相关go库的安装。有些是vscode支持和k8s编译必须的或者优化的库。
  3. php编译安装。
  4. vscode的插件安装。

如果你不想安装php或者go,或是想编译其他语言的,可以根据这份dockerfile做调整。

三、dockerfile(国内)

按以上的dockerfile,在国外的机器上是可以编译通过的。在国内build遇到了这几个问题,非常影响编译时候的心情💢:

  1. go/php/docker下载慢
  2. apt源update慢
  3. pip install pyyaml直接timeout了,(吐血

于是针对这几个问题,都做了相应的工作:

  1. 先在国外下好传到本地
  2. 换成国内163源
  3. 配置一个http proxy提供给pip使用

1. 下好go/php/docker文件

2个文件:一个负责下载,一个负责启动本地http服务器,方便dockerfile下载。

# download.sh
#!/bin/bash

DOCKER_CLI_VERSION=19.03.14
GOLANG_VERSION=1.16.7
PHP_VERSION=7.1.5

GO_TGZ=go$(echo "$GOLANG_VERSION").linux-amd64.tar.gz
PHP_TGZ=php-${PHP_VERSION}.tar.gz
DOCKER_TGZ=docker-ce-cli_${DOCKER_CLI_VERSION}~3-0~debian-stretch_amd64.deb

wget https://golang.org/dl/${GO_TGZ}
wget http://am1.php.net/distributions/${PHP_TGZ}
wget https://download.docker.com/linux/debian/dists/stretch/pool/stable/amd64/${DOCKER_TGZ}
# web.sh

#!/bin/bash
python -m SimpleHTTPServer 31415

image-20220128102636735

2. 更换apt源

大致如下,详情我贴在文后

image-20220128102831433

3. 创建一个http proxy 提供给pip使用

使用privoxy创建的,具体内容就不展示了,可以参考我这篇文章《linux 配置 privoxy 实现系统全局/自动代理》.

完成这三个步骤后的dockerfile如下,主要区别的地方就是增加了本地服务器地址和代理地址两个变量。

FROM kelvinblood/code-server:base-20210903

LABEL org.kelu.image.version.go=1.16.7
LABEL org.kelu.image.version.php=7.1.5
LABEL org.kelu.image.version.code-server=3.11.1
LABEL org.kelu.image.version.vscode=1.57.1
LABEL org.kelu.image.version.dockercli=19.03.14

ARG DOCKER_CLI_VERSION=19.03.14
ARG GOLANG_VERSION=1.16.7
ARG PHP_VERSION=7.1.5
ENV GOROOT /usr/local/go
ENV GOPATH /var/local/go
ENV PATH $PATH:$GOROOT/bin:$GOPATH/bin
ENV GO111MODULE on
ENV GOPROXY https://goproxy.cn

RUN \
  LOCAL_WEB_SERVER=172.16.0.2:31415 && \
  PROXY=172.16.0.2:8118 && \
  GO_TGZ=go$(echo "$GOLANG_VERSION").linux-amd64.tar.gz && \
  PHP_TGZ=php-${PHP_VERSION}.tar.gz && \
  DOCKER_TGZ=docker-ce-cli_${DOCKER_CLI_VERSION}~3-0~debian-stretch_amd64.deb && \
  echo "**** download from china ****" && \
  echo "deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse" >/etc/apt/sources.list && \
  echo "deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse" >>/etc/apt/sources.list && \
  echo "deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse"  >>/etc/apt/sources.list && \
  echo "**** install tools ****" && \
  apt-get update && \
  apt-get install -y \
    wget \
    iputils-ping \
    build-essential \
    xinetd \
    telnetd \ 
    rsync \
    jq \
    python-pip && \
#  pip install pyyaml && \
  pip install --proxy http://${PROXY} pyyaml && \
  cd /tmp && wget http://${LOCAL_WEB_SERVER}/${DOCKER_TGZ} && \
  dpkg -i *.deb && \
  echo "**** install golang ****" && \
  cd /tmp && wget http://${LOCAL_WEB_SERVER}/${GO_TGZ} && \
  tar zxvf ${GO_TGZ} >/dev/null 2>&1 && \
  mv go ${GOROOT} && \
  echo "**** go get for vscode ****" && \
  go get golang.org/x/tools/gopls && \
  go get golang.org/x/lint/golint && \
  go get github.com/rogpeppe/godef && \
  go get github.com/ramya-rao-a/go-outline && \
  go get github.com/uudashr/gopkgs/v2/cmd/gopkgs && \
  go get github.com/cweill/gotests/gotests && \
  go get github.com/fatih/gomodifytags && \
  go get github.com/josharian/impl && \
  go get github.com/haya14busa/goplay/cmd/goplay && \
  go get github.com/go-delve/delve/cmd/dlv && \
  go get honnef.co/go/tools/cmd/staticcheck && \
  go get github.com/spf13/cobra/cobra && \
  cp /var/local/go/bin/dlv /var/local/go/bin/dlv-dap && \
  echo "**** install php ****" && \
  apt-get -y install libssl-dev libcurl4-openssl-dev libbz2-dev libjpeg-dev libpng-dev libgmp-dev libicu-dev libmcrypt-dev freetds-dev libxslt-dev libcurl3-dev autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c && \
  ln -s /usr/lib/x86_64-linux-gnu/libsybdb.a /usr/lib/libsybdb.a && \
  ln -s /usr/lib/x86_64-linux-gnu/libsybdb.so /usr/lib/libsybdb.so && \
  ln -s /usr/lib/x86_64-linux-gnu/libct.a /usr/lib/libct.a && \
  ln -s /usr/lib/x86_64-linux-gnu/libct.so /usr/lib/libct.so && \
  ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h && \
  ln -s /usr/include/x86_64-linux-gnu/curl /usr/include/curl && \
  cd /tmp && wget http://${LOCAL_WEB_SERVER}/${PHP_TGZ} && \
  tar -xzvf ${PHP_TGZ} && \
  cd php-${PHP_VERSION} && \
  ./configure --prefix /usr/share/php7 --enable-fpm --enable-mbstring --enable-zip --enable-calendar --enable-bcmath --enable-exif --enable-intl --enable-opcache --enable-shmop --enable-soap --enable-sockets --with-fpm-user=www-data --with-fpm-group=www-data --with-pcre-regex --with-kerberos --with-openssl --with-mcrypt --with-zlib --with-bz2 --with-curl --with-gd --with-jpeg-dir=/usr/include/jpeg8 --with-png-dir=/usr/include/libpng12 --with-gettext --with-gmp --with-mhash --with-xsl && \
  make clean && make && make install && make test && make clean && \
  ln -s /usr/share/php7/sbin/php-fpm /usr/local/bin/php-fpm && \
  ln -s /usr/share/php7/bin/php /usr/local/bin/php && \
  cd .. && \
  curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer && \
  echo "**** vscdoe tools ****" && \
  /usr/local/bin/code-server --install-extension ms-ceintl.vscode-language-pack-zh-hans && \
  /usr/local/bin/code-server --install-extension vscodevim.vim && \
  /usr/local/bin/code-server --install-extension golang.Go && \
  mkdir -p /config/extensions && \
  mv /config/.local/share/code-server/extensions/* /config/extensions && \
  echo "**** clean up ****" && \
  apt-get clean && \
  rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*

四、运行

整个ide镜像弄好了,对于开发者来说还有一个需要解决的,我平时使用肯定是需要增加插件、一些自定义的配置,还有golang开发时go mod需要下载库之类的,不能镜像一挂就什么都没了吧。。。

所以这里需要将它们提取出来,我分成了两个步骤,一个是build images时提取,另一个是docker-compose拉起镜像。

1. build.sh

image-20220128103852344

#!/bin/bash

rm -rf  ./config ./go
tag=$(date +%Y%m%d)
docker build -t kelvinblood/code-server:release-$tag .

id=$(docker create kelvinblood/code-server:release-$tag)
docker cp $id:/config .
docker cp $id:/var/local/go .
docker rm -v $id

touch settings.json

另外,我个人使用的个人配置文件如下:

# settings.json

{
    "workbench.colorTheme": "Solarized Dark",
    "editor.fontSize": 18,
    "go.testTimeout": "60s",
    "go.toolsManagement.autoUpdate": true
}

2. docker-compose.yml

version: "2.1"
services:
  code-server:
    image: kelvinblood/code-server:release-20220127
    container_name: code-server
    hostname: vscode
    network_mode: bridge
    environment:
      - PUID=0
      - PGID=0
      - TZ=Asia/Shanghai
      - PASSWORD=  #optional
#      - HASHED_PASSWORD= #optional
#      - SUDO_PASSWORD= #optional
#      - SUDO_PASSWORD_HASH= #optional
      - PROXY_DOMAIN=kelu.org #optional
    volumes:
      - ./gophp/config:/config
      - ./gophp/go:/var/local/go
      - ./gophp/settings.json:/config/data/User/settings.json:rw
      - /var/run/docker.sock:/var/run/docker.sock:rw
      - /root/Workspace:/root/Workspace
    restart: unless-stopped

image-20220128104310205

运行后界面如下:

image-20220128104534765


nmcli 使用命令行连接wifi

nmcli 的具体命令可以参考redhat的相关文档。这篇文章简单记录如何使用命令行连接wifi。

简单来看如下:

nmcli dev wifi list/show
nmcli dev wifi connect <SSID>  password <password>
nmcli conn up <Name> 
  1. 查看可用 Wi-Fi 访问点

    nmcli dev wifi list
    

    image-20220104093644673

  2. 输入密码连接wifi

    nmcli dev wifi connect bakemonogatari password xxxxxx
    

    image-20220104101559167

    每次命令执行后,会在 /etc/NetworkManager/system-connections/ 目录下创建一个新文件来保存配置,重复执行则创建多个这样的文件。删除wifi连接,在 /etc/NetworkManager/system-connections/ 目录下的对应文件也会被删除。

    nmcli conn show # 查看
    nmcli con del bakemonogatari # 删除
    

    image-20220104102320594

  3. 主动连接某配置的wifi

    nmcli connection up bakemonogatari # 开启
    nmcli connection down  # 关闭
    
  4. 设置该wifi自动连接

    nmcli connection modify bakemonogatari connection.autoconnect yes
    
  5. 其他操作

    • 检查可用设备,查看设备链接状态

       nmcli dev status # 
      

      wlp3s0 是我们的wifi设备。

      image-20220104091538547

    • 以下命令更改 Wi-Fi 状态:

       nmcli radio wifi [on | off ]
      

      image-20220104091721278

参考资料


linux awesome 窗口管理器使用备忘

最近将窗口管理器从 gnome3 换到了 awesome,一个平铺式的窗口管理器。已经使用了5天了,感觉还可以。中途还研究了其他东西,最后回归到 awesome + nautilus 的方式使用。 这篇文章做一些记录。

我使用的环境是 Debian 9 x86_64,由 gnome3 登录界面切换为 awesome 窗口管理器。

目前安装的awesome信息为:

awesome v4.0 (Harder, Better, Faster, Stronger)
 • Compiled against Lua 5.1.5 (running with Lua 5.1)
 • D-Bus support: ✔
 • execinfo support: ✔
 • RandR 1.5 support: ✔
 • LGI version: 0.9.1

一、Awesome 介绍与WM概念

窗口管理器 vs 桌面环境

  • 窗口管理器(Windows Manager),负责绘制窗口的边框,处理窗口运行比如移动、最小化之类的行为。

  • 桌面环境(Desktop Environment),窗口管理器的超集,它使用窗口管理器及其其他软件提供一个完整的工作环境。

例如:gnome就是一个桌面环境,默认使用Metacity作为窗口管理器。

平铺式窗口管理器

平铺就是之所有的窗口都不会相互重叠,而是 自动的 被调整大小使得它们能够刚好占满整个屏幕。

相对的,我们平时使用的是浮动式窗口管理器,由于屏幕空间有限,当前激活的窗口会浮在最上面,而遮住下面的窗口。

常见的窗口管理相关的工具如下:(来自alim0x - Awesome-Linux-Software-zh_CN)

合成器
  • Compton - Compton 是一款独立的合成管理器,适合同没有原生提供合成功能的窗口管理器一同使用。
  • Gamescope - Gamescope 是一款微合成器,提供一个带有独立输入,分辨率和刷新率的沙盒 Xwayland 桌面。
  • Sway - Sway 是平铺 Wayland 合成器和 X11 下 i3 窗口管理器的新替代。
  • Xcompmgr - Xcompmgr 是一个简单的合成管理器,能够渲染下拉阴影,使用 transset 工具的话,还可以实现简单的窗口透明。
叠加式窗口管理器
  • 2bwm - 快速的浮动窗口管理,有两个特殊边界,基于 XCB 库,由 mcwm 衍生。
  • Blackbox - 快速,轻量化的 X 窗口系统窗口管理器,没有那些烦人的库依赖。
  • Fluxbox - 基于 Blackbox 0.61.1 代码的 X 窗口管理器。
  • Openbox - 高度可配置,带有可扩展标准支持的下一代窗口管理器。
平铺式窗口管理器
  • Bspwm - bspwm 是一个平铺式窗口管理器,将窗口以二叉树的叶结点的方式展现。
  • Herbstluftwm - 使用 Xlib 和 Glib 的手工平铺式窗口管理器。
  • i3 WM - 更好的平铺及动态窗口管理器。完全重写。目标平台是 GNU/Linux 和 BSD 操作系统。
  • i3-gaps - i3-gaps 是拥有更多功能的 i3。
  • Pop!_OS Shell - Pop Shell 是基于 GNOME shell 的窗口管理器,键盘驱动,自动平铺。
  • Qtile - qtile 是一款全功能,可 hack 的平铺窗口管理器,使用 Python 编写和配置。
动态窗口管理器
  • awesome - 高度可配置,下一代 X 框架窗口管理器。
  • dwm - X 动态窗口管理器。它以平铺,单片镜以及浮动布局的方式管理窗口。
  • spectrwm - 小型动态平铺 X11 窗口管理器。主要受 xmonad 和 dwm 启发。
  • xmonad - 动态平铺 X11 窗口管理器,用 Haskell 编写和配置。

docker compose 添加额外的host信息

官方手册里也有,因为偶尔也会用到,每次都懒得找,写个文章做记录。

以下两种方式效果一样,v2和v3都ok:

app:
  images: kelvinblood/kelu
  extra_hosts:
    kelu.org: 1.2.3.4
    kelu.local: 4.3.2.1

或者

extra_hosts:
  - "somehost:162.242.195.82"
  - "otherhost:50.31.209.229"

git 命令行查看文件的某个版本历史

我一般使用可视化的 ui 工具来查看某个文件的历史,但也免不了有的场景只有命令行工具。

命令行查看如下:

  1. 查看版本的提交号:

    git log
    

    ps: 我习惯使用下面这个命令,能展示每笔提交更详细的信息:

    git log --stat
    
  2. 查看该版本的文件:

    git show e0d599a9807b8ec1ce8271821feb2a90cc8a8e62:app/Console/Commands/TestCommand.php
    

linux 使用 unzip 解压的中文乱码问题

来自windows下的解压乱码真是痛:

image-20211220110600679

zip格式没有指定编码格式,Windows下生成的zip文件中的编码是GBK/GB2312等,Linux下的默认编码是UTF8。

可以使用 unzip-iconv 这个补丁包,指定解压的编码格式。

一、安装unzip-iconv补丁

$ wget https://github.com/ikohara/dpkg-unzip-iconv/archive/refs/heads/main.zip
$ unzip main.zip
$ cd main
$ make source
$ sudo make build-dep
$ make
$ sudo make install

更详细的说明参考GitHub上的项目信息: https://github.com/ikohara/dpkg-unzip-iconv

二、使用

unzip -O cp936 xxx.zip

参考帮助