当我们辛苦写完一个小玩具后自然想赶快部署上去看一下效果,而鉴于可怜服务器资源,我们自然想用最少的空间实现相同的效果。这个时候Alpine就善良登场了。

Alpine

Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。

我尝试过用apk add bash安装bash但是速度非常慢,使用镜像也一样。搞得我十分怀疑我的容器出了问题。

上面有些啰里啰唆,直接比较一下image大小就知道选啥了。

REPOSITORYTAGIMAGE IDVIRTUAL SIZE
alpinelatest4e38e38c8ce04.799 MB
debianlatest4d6ce913b13084.98 MB
ubuntulatestb39b81afc8ca188.3 MB
centoslatest8efe422e6104210 MB

之前拉取ubuntu也是怀疑人生,然后里面只有一个apt管理包。包括常用的ping,netstat都没有,需要自己安装。想一想安装那个需要花费的时间吧。

拥抱 Alpine 吧

编写 Dockerfile, 构建 Alpine 为基础的镜像

我一开始以为它们无非都是提供一些环境而,因此我把From: ubuntu改成了From: alpine

看来我还是too yong, too simple

Alpine 可以怎么小肯定确实很多很多的东西。这样显然行不通的。

然后我就花费了许多的时间来解决这个奇怪的错误上面

standard_init_linux.go:187: exec user process caused no such file or directory

说实话这个错误我看的一脸懵逼,没理由找不到文件啊。

求助 Goooooooogle

没办法,发挥我的传统艺能了。

一通操作下来,发现大部分给出的答案是LF && CRLF的问题。

也就是说,我在 windows 上面写的换行用CRLF到 linux 上面构建会出错。

我的内心是,??????

解决方案是dos2unix转换一下我的Dockerfile。 然而并没有卵用。

后面又找到一个答案,说是缺少bash

然后我又加入了apk add --no-cache bash

还是没啥用处。

只剩下最好一个解决方案了,就是编译成静态链接。 (其实我早想到,但是死活不承认,折腾了一圈还得搞成静态链接)

所以最后的解决方案就是,编译的时候加入-tags netgo生成静态可执行程序。

小插曲

在使用 alpine 之前都是用 ubuntu 构建的镜像

虽然可以跑,但是会出现程序请求 https 时候会出现certificate signed by unknown authority这个错误

我就很郁闷,查了一下发现容器里面没有信任的cert文件,需要自己做个映射。我一看怎么麻烦,那就懒得去搞了。

但是,文档却说

As of Docker 1.13, on Linux any root certificates authorities are merged with the system defaults, including as the host’s root CA set. On prior versions of Docker, and on Docker Enterprise Edition for Windows Server, the system default certificates are only used when no custom root certificates are configured.

按理说应该不存在这个问题。不解...

当我折腾好了之后,就发现这个问题就消失了。啊,哈哈哈。。。(好懵逼啊)

总结

虽然折腾怎么久,但是搞定了alpine。这样后面的就不用臃肿的ubuntu了。

贴一下Dockerfile

FROM alpine

EXPOSE 8080

WORKDIR /root/

COPY main app
COPY template template
COPY asset asset

CMD ["./app"]

还有workflows

name: build & push & deply

on:
  push:
    branches: [master]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Set up Go 1.x
        uses: actions/setup-go@v2.1.1
        id: go
      - name: Check out code into the Go module directory
        uses: actions/checkout@v2
      - name: Get dependencies
        run: |
          go get -v -t -d ./...
          if [ -f Gopkg.toml ]; then
              curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
              dep ensure
          fi
      - name: Build
        # 注意使用 -tags netgo 编译链接静态库
        # 这里编译成 main 方便后面构建docker image
        # "/github/workspace" 应该是在这个目录下面构建的
        run: go build -tags netgo -v -o main .

      - name: Publish Docker
        uses: elgohr/Publish-Docker-Github-Action@master
        with:
          # aliyun 提供私有托管服务
          name: registry.cn-hangzhou.aliyuncs.com/dreamer2q/wx-pusher
          registry: registry.cn-hangzhou.aliyuncs.com
          username: ${{ secrets.DOCKER_USER }} # 用户名
          password: ${{ secrets.DOCKER_PASS }} # 密码
          dockerfile: Dockerfile
          snapshot: true

        # 这里是自动部署, 使用portainer提供的自动部署接口
      - name: trigger deploy web hook
        run: |
          sleep 5
          curl -d "" http://webhook.api
Last modification:August 26th, 2020 at 05:21 pm
要饭啦~