0.前言
之前我已经写了 Drone+Forgejo+SonarQube 持续集成code review的文档,
但在之前的文档中,我们并没有自己动手创建docker,都是用别人做好的镜像。
现在我们需要把开发环境打到docker镜像中,并且把我们的代码库拉到镜像中,做一个基线 ,
每次Forgejo上触发一个webhook时,我们上Drone基于这个基线,执行指令递归拉取所有git submodule,执行打包脚本。
1 三种思路
摆在我们面前有三种选择
前者的好处是,文件系统分层情况良好,当你有很多镜像时,他们可能可以复用某一些文件层,节约空间和网络流量
不好的地方就是步骤比较繁琐。后者的好处就是操作简单,但基础镜像的分层信息会丢失。
因为我们除了Drone构建打包用docker,基本上没其他事了,ubuntu16裸机的这个分层,复用率不高,另外我们只在ci cd的这台电脑上加载这个镜像,没有什么docker集群,所以也不用担心网络流量的问题。所以综合考虑,我们可以考虑使用第二种方式或第三种方式, 由于我硬盘剩余空间比较小,故采用第二种方式
1 安装docker
由于闫工给我的机器是ubuntu,所以我用apt安装 docker,略
2.制作开发环境docker
2.1 docker镜像 拉取,启动
拉一个下载量最多的
1
|
root@drone-ci-8-20:~# docker pull homebrew/ubuntu16.04
|
这时查看电脑上的镜像可以看到已经拉取的
1
2
3
|
root@drone-ci-8-20:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
homebrew/ubuntu16.04 latest 6347afdf9148 6 months ago 1.27GB
|
实例化容器
1
2
|
root@drone-ci-8-20:~# docker run -d homebrew/ubuntu16.04 tail -f /dev/null
ed1c0b7568119b788b940e21fb1b2d50d63c3e9fe74a48a1dabd0d02987b3a5c
|
tail -f /dev/null 会使这个容器一启动就 一直保持运行,这样我们才有机会进去安装环境
1
2
3
|
root@drone-ci-8-20:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed1c0b756811 homebrew/ubuntu16.04 "tail -f /dev/null" 25 seconds ago Up 24 seconds sharp_shtern
|
查看一下容器,已经有一个状态 为up的容器,说明运行成功了。
接下来使用 exec -it 以交互的形式执行容器的bash ,
1
2
|
root@drone-ci-8-20:~# docker exec -it ed1c /bin/bash
linuxbrew@149b1d533469:~$
|
看一下系统内核
1
2
3
|
linuxbrew@ed1c0b756811:~$ uname -a
Linux ed1c0b756811 5.15.0-84-generic #93-Ubuntu SMP Tue Sep 5 17:16:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
linuxbrew@ed1c0b756811:~$
|
内核显示为5.15,而实际上ubuntu内核最新的是4.15.142, 两者显示不一样是因为docker container使用的是host的内核
不过我们只是编译软件,应该没有太多问题,先不管内核版本
接下来的操作,就和ubuntu裸机安装环境没太多区别了,甚至更简单,因为我们只是要编译软件,不需要安装运行环境,比如驱动
2.2 安装基础依赖
接下来更新一下我们公司的apt源 ,下载一下闫工之前写的脚本
1
2
3
4
5
6
|
sudo -i
apt update
apt install wget
cd ~
wget http://file.deepvision-tech.net/scripts/apt.sh
chmod +x apt.sh
|
因为docker中的网络环境和主机中不一样,所以我们需要修改一下脚本 ,手动注释掉 杭州或北京的脚本 逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#!/bin/bash
# v1.1
# 2023.3.21
# yanqianling@deepvision-tech.com
OldSource=`grep ^deb /etc/apt/sources.list|awk '{print $2}'|sort |uniq |sed '/security.ubuntu.com/d'`
NewSource="-apt.deepvision-tech.net/repository/apt-"
OsVer=`cat /etc/issue|awk -F'[ .]+' '{print $2}'`
IP=`ip a | awk '-F[ .]+' '/255/{print $3"."$4"."$5}'|egrep '10.[1,2,8]{1}.'`
YELOW='\E[1;33m'
RED='\E[1;31m'
RES='\E[0m'
#case $IP in
# "10.2.1")
# cp -f /etc/apt/sources.list /etc/apt/sources.list.bak
# echo ""
# echo -e "${YELOW} Old apt sources backup to [/etc/apt/sources.list.bak] ${RES}"
# sed -i "s#${OldSource}#http://bj${NewSource}${OsVer}/#g" /etc/apt/sources.list
# echo -e "${YELOW} new apt source replaced by [http://bj${NewSource}${OsVer}] ${RES}"
# echo -e "${YELOW} Please run command [sudo apt update],Let config become effective ${RES}"
#;;
# "10.1.1"|"10.1.8")
cp -f /etc/apt/sources.list /etc/apt/sources.list.bak
echo ""
echo -e "${YELOW} Old apt sources backup to [/etc/apt/sources.list.bak] ${RES}"
sed -i "s#${OldSource}#http://hz${NewSource}${OsVer}/#g" /etc/apt/sources.list
echo -e "${YELOW} new apt source replaced by [http://hz${NewSource}${OsVer}] ${RES}"
echo -e "${YELOW} Please run command [sudo apt update],Let config become effective ${RES}"
# ;;
# *)
# echo -e "${YELOW} ${IP} ${RES}"
# echo -e "${YELOW}YOU IP Error ${RES}"
#esac
~
~
~
|
例如我操作的这个机器是在杭州的,我就把脚本中的case 语句注释掉,只留下杭州这一段逻辑
然后执行它
替换完源后 ,更新一下
然后开始安装编译环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
sudo apt install -y liblapack-dev
sudo apt install -y libjpeg-dev libpng12-dev libtiff-dev libjasper-dev libdc1394-22-dev
sudo apt install -y libva1 libva-dev libva-drm1 libva-egl1 libva-glx1
sudo apt install -y libswscale-dev libavcodec-dev libavformat-dev
sudo apt install -y libssh2-1 zlib1g-dev
sudo apt install -y libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev libsndio-dev
sudo apt install -y python3-pip
pip3 install openpyxl==2.6.4
pip3 install xlrd==1.2.0
sudo apt install -y libcap-dev libx11-dev libxext-dev libgtk-3-dev libglade2-0 libglade2-dev libpcap0.8 libcap2 ethtool
sudo apt install -y libsndio-dev
sudo apt install -y libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev x11vnc xauth build-essential mesa-common-dev libglu1-mesa-dev libxkbcommon-dev libxcb-xkb-dev libxslt1-dev libgstreamer-plugins-base0.10-dev libxkbcommon-x11-0
sudo apt-get install build-essential libgli-mesa-dev libglul-mesa-dev freeglut3-dev
sudo apt install -y libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev x11vnc xauth build-essential mesa-common-dev libglu1-mesa-dev libxkbcommon-dev libxcb-xkb-dev libxslt1-dev libgstreamer-plugins-base0.10-dev libxkbcommon-x11-0
|
2.3 安装Qt
2.3.1 方式一,编译源码安装
安装qt 5.12.6
传统的方式是 在有gui的环境下运行.run的安装包, 但docker 里的ubuntu默认是没有图形界面的。
所以直接下载官网的源码编译,安装
1
2
3
4
5
6
7
8
9
10
11
12
13
|
wget https://download.qt.io/archive/qt/5.12/5.12.6/single/qt-everywhere-src-5.12.6.tar.xz
tar -zxvf qt-everywhere-src-5.12.6.tar.xz
cd qt-everywhere-src-5.12.6
./configure
make -j8
make install
# 如果出现问题make confclean 清除配置信息 重新编译
|
安装完后会有 /local/Qt-5.12.6/这个路径, 把qmake复制到/usr/bin ,然后键入 qmake -v 查看是否编译安装正常
1
2
3
|
linuxbrew@ed1c0b756811:/usr$ qmake -v
QMake version 3.1
Using Qt version 5.12.6 in /usr/local/Qt-5.12.6/lib
|
因为我们只是用docker来构建,不需要启动图形界面,所以这种可以减少不必要的依赖安装,但编译时长较长,如果不想编译源码的话,可以使用另一种方案,docker宿主机上安装桌面环境
2.3.2 方式二,docker挂载宿主机图形相关卷启动
1
2
|
sudo apt install ubuntu-desktop
xhost local:root
|
使用vnc远程到宿主机后,然后参照这个设置,把docker挂载上显示相关的卷,
1
|
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -v /dev/shm:/dev/shm --device /dev/dri
|
就可以在docker容器中打开 run安装包安装了, 如果还打不开run安装包,可以尝试指定 不依赖硬件的平台
1
|
qt-opensource-linux-x64-5.12.6.run -platform minimal
|
或
1
|
qt-opensource-linux-x64-5.12.6.run -platform offscreen
|
p latform 的可选项
directfbegl,directfb,eglfs,linuxfb,minimal,minimalegl,offscreen,wayland-egl,wayland,xcb。
以及这个, 使用脚本,静默安装 installation - Silent install Qt run installer on ubuntu server - Stack Overflow
2.4 克隆源码构建
全安装后, 克隆一下源码
1
2
3
4
|
mkdir -p ~/source/repos
cd ~/source/repos/
git clone http://10.1.8.8/AL/dv-detector.git
git submodule update --init --recursive
|
然后就可以运行打包脚本构建了
1
|
./pkg.sh 1.1.1.1 tst_build
|
2.5 把现有docker container 转换为docker image
删除掉不需要的文件,尽可能减少容器占用的空间,然后再打镜像
1
2
3
4
5
|
root@drone-ci-8-20:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed1c0b756811 homebrew/ubuntu16.04 "tail -f /dev/null" 25 seconds ago Up 24 seconds sharp_shtern
docker commit ed1c0b756811 dv_detector:master1.1.1.1
|
因为我们目前没有搭建docker 私有仓库,所以一般通过导入导出 docker 镜像到文件系统传输
导出docker 镜像到文本系统
1
|
docker save -o myimage_exported.tar dv_detector:master1.1.1.1
|
从文件系统导入
1
|
docker load -i myimage_exported.tar
|
3 配置drone,执行docker runner
Overview | Drone
官网之述备矣
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
kind: pipeline
type: docker
name: build
clone:
disable: true
steps:
- name: pkg
image: dv_detector:master1.1.1.1
environment:
DRONE_BRANCH: $DRONE_BRANCH
PKG_VERSION: "1.1.1.2"
PKG_NAME: "测试打包"
settings:
detach: false
entrypoint: [""]
commands:
- cd ~/source/repos/dv-detector
- git reset --hard
- git clean -xdf
- git pull origin master
- git submodule update --recursive
- bash -c "./pkg.sh $PKG_VERSION $PKG_NAME''_$(git rev-parse --short=6 HEAD)"
|
最终打出的包放在容器中没后续动作,因为本文只做技术验证
如果需要,只需要在comands里加额外的处理就可以了
![image-20230927200630893](image-20230927200630893.png)
end
100. 附录:Docker 常用命令
100.1 容器生命周期管理:
- 创建一个容器:
docker run <image_name>
- 启动容器:
docker start <container_name>
- 停止容器:
docker stop <container_name>
- 重启容器:
docker restart <container_name>
- 删除容器:
docker rm <container_name>
- 查看运行中的容器:
docker ps
- 查看所有容器(包括停止的):
docker ps -a
- 进入容器内部命令行:
docker exec -it <container_name> /bin/bash
100.2 镜像操作:
- 搜索镜像:
docker search <image_name>
- 下载镜像:
docker pull <image_name>
- 列出本地镜像:
docker images
- 删除本地镜像:
docker rmi <image_name>
100.3容器日志和信息:
- 查看容器日志:
docker logs <container_name>
- 查看容器详细信息:
docker inspect <container_name>
100.4容器文件传输:
- 从容器复制文件到本地:
docker cp <container_name>:<src_path> <dest_path>
- 从本地复制文件到容器:
docker cp <src_path> <container_name>:<dest_path>
100.5构建镜像:
- 基于 Dockerfile 构建镜像:
docker build -t <image_name>:<tag> <path_to_Dockerfile>
100.6Docker Compose:
- 使用 Docker Compose 启动多个容器:
docker-compose up
- 停止 Docker Compose 启动的容器:
docker-compose down
100.7网络操作:
- 列出 Docker 网络:
docker network ls
- 创建 Docker 网络:
docker network create <network_name>
100.8清理:
- 清理无用容器:
docker container prune
- 清理无用镜像:
docker image prune
- 清理无用卷(数据卷):
docker volume prune
>> Home
Comments