Alpine Linux软件开发环境构建

我在尝试 树莓派Raspberry Pi 3 + 树莓派Raspberry Pi 4 混合集群部署 K3s - 轻量级Kubernetes 时,读到 Setting Up a Software Development Environment on Alpine Linux ,发现很有启发,也是一个有趣的挑战。在一个轻量级的ARM环境中,实现软件开发、 DevOps Atlas ,并采用 边缘云计算构建 构建一个ARM集群。

为什么会选择 Alpine Linux 来构建软件开发环境呢?

Alpine Linux简介 可以看到,Alpine是一个非常非常轻量级的Linux系统,并且适合运行容器( Docker Atlas )。这对于我们开发者来说,是非常适合的 DevOps Atlas 环境。

构建思路:

Docker运行环境

Alpine Linux运行Docker ,然后采用 从Dockerfile构建Docker镜像

  • 使用密码登陆的ssh容器 Dockerfile :

提供ssh和sudo的alpine构建Dockerfile
FROM alpine:latest
RUN apk add --update --no-cache openssh sudo
RUN apk update && apk upgrade
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
RUN adduser -u 502 -G wheel -h /home/huatai -s /bin/sh -D huatai
RUN echo -n 'huatai:some_password_here' | chpasswd
RUN echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 22
COPY entrypoint.sh /
  • 并准备 entrypoint.sh :

启动ssh脚本
#!/bin/sh
ssh-keygen -A
exec /usr/sbin/sshd -D -e "$@"
  • 然后执行构建镜像命令:

    chmod +x -v entrypoint.sh
    docker build -t alpine-ssh .
    
  • 使用以下命令启动容器:

    docker run -itd --hostname x-dev --name x-dev -p 122:22 alpine-ssh:latest
    

安装编译环境

类似Ubuntu的 build-essentialAlpine Linux 提供了 build-base 组合安装包,可以安装大多数常用build工具,包括 g++ makebinutils 。如果要开发 C++,则可以安装一些附加工具包,如 cmake ,以及 linux-headers 等。

  • 安装编译环境 build-base (占用 204MB)

    sudo apk add build-base
    
  • 安装debug工具 gdb 以及 strace

    sudo apk add gdb strace
    

golang

  • 通过仓库安装golang:

    sudo apk add go
    

参考 Go快速起步 验证

rust

  • 通过仓库安装rust:

    sudo apk add rust
    

参考 Rust快速起步 验证

安装编辑器构建IDE

我采用 Vim 来构建开发IDE,采用 轻量级定制vim 来构建自己的开发环境

桌面

注解

我采用字符界面远程开发,所以没有安装桌面。不过作为轻量级Linux发行版,你可以对应安装一个轻量级的 xfce 桌面。参考文档是 alpine linux wiki: Xfce

或许以后我会尝试运行Alpine Linux桌面

原文作者采用了Xfce桌面,并且为了能够方便开发,安装了JetBrains IDE系列。原因是Alpine Linux使用musl库,如果使用 musl-glibc 兼容库非常费劲。而JetBrains是Java程序,OpenJDK(IcedTea项目)可以顺畅在Alpine Linux上运行,所以选择JetBrains全家桶可以非常方便开发工作。

此外,由于 Google 提供的 Android Studio就是基于JetBrains IDE,所以 在树莓派4上运行android studio开发 也是可行的(只不过为了通用方便,容器内通常运行 Ubuntu Linux )。

考虑到树莓派性能有限,并且在 边缘云计算架构 我只有3台 树莓派Raspberry Pi 4 (后续横向扩容)需要部署 K3s - 轻量级Kubernetes 以及在此基础上集成 Rancher Atlas 系统,所以我没有部署任何桌面系统,而是将非常消耗计算资源的容器和虚拟机运行在 HPE ProLiant DL360 Gen9服务器 服务器部署的 私有云架构 中。

容器构建

经过验证后,可以将上述步骤添加到 Alpine Linux 的Dockerfile,以便后续重新构建开发环境,并一步步打磨完善:

  • 最终完整的 x-dev 完整 Dockerfile:

alpine构建开发环境的Dockerfile
FROM alpine:latest
RUN apk update && apk upgrade
RUN apk add --no-cache openssh sudo bind-tools
RUN apk add --no-cache build-base gdb strace
RUN apk add --no-cache go rust
RUN apk add --no-cache git vim htop
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
RUN adduser -u 502 -G wheel -h /home/huatai -s /bin/sh -D huatai
RUN echo -n 'huatai:some_password_here' | chpasswd
RUN echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 22
COPY entrypoint.sh /
  • 执行以下命令构建镜像并启动容器:

构建alpine开发环境docker容器
docker build -t alpine-dev .
docker run -itd --hostname x-dev --name x-dev -p 122:22 alpine-dev:latest
  • 登陆容器:

    ssh 127.0.0.1 -p 122
    

node容器构建案例

  • 构建运行Node的容器环境案例:

alpine构建运行node的容器Dockerfile
FROM alpine:latest
RUN apk update && apk upgrade
RUN apk add --no-cache nodejs npm
RUN addgroup -S node && adduser -S node -G node
USER node
RUN mkdir /home/node/code
WORKDIR /home/node/code
COPY --chown=node:node app.js ./
USER root
EXPOSE 3000
CMD ["node", "app.js"]
  • 准备一个 app.js 作为演示案例:

nodejs Hello World
const http = require('http');

//const hostname = '127.0.0.1';
//容器化运行,node需要监听在所有端口才能publish port
const hostname = '0.0.0.0';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
  • 执行以下命令构建镜像并启动容器:

构建alpine运行node的容器
docker build -t alpine-node .
docker run -itd --hostname x-node --name x-node -p 3000:3000 alpine-node:latest

注解

以上是构建node容器的案例,实际上通过容器运行node建议采用nodejs官方 nodejs / docker-node 来运行

镜像制作和迁移

  • 在完成了容器内部应用升级和安装之后,执行以下命令保存镜像:

    docker commit x-dev local:x-dev
    
  • 然后将镜像导出备份,以及 无需Docker Registry传输Docker镜像

参考