# 代码托管

[git.nju.edu.cn](https://git.nju.edu.cn)

# 已开启的高级功能

### Gravatar
### Reply by email
### Advanced Search
### Container Registry
### Shared Runners
- Linux Docker

# Git镜像教程

NJU Git可以设置从其他代码托管平台如GitHub、GitLab、Gitee等拉取、推送代码仓库（镜像）。

教程见：[https://mp.weixin.qq.com/s/EjAedt6A3PvuASGlFCfyWQ](https://mp.weixin.qq.com/s/EjAedt6A3PvuASGlFCfyWQ)

# CI/CD自动化构建Docker镜像

> 一个通过CI/CD自动构建Docker镜像并用于HPC集群计算的简单示例。

示例代码仓库：[https://git.nju.edu.cn/escience/singularity-example](https://git.nju.edu.cn/escience/singularity-example)

容器化在集群上使用时有很大的优势，主要体现在：
+ 容器内模拟的root权限，无需权限即可任意安装自己想要的程序包
+ 版本可控，自定义性强
+ 可复用性强，一处构建，多处部署

因此，对于一些编译特别复杂但早已有Docker镜像的计算软件，或者自己写的配置环境麻烦的软件，考虑Singularity是个不错的选择。

此外，eScience中心的多个服务也涵盖了**一整套工作流**。所以全程无需出校访问**在校园内网**即可实现。

本文将通过一个简单但常见的Conda虚拟环境下Python Numpy库的镜像构建来演示如何使用这一功能。

## 通过 Dockerfile 构建自己的镜像

通过Dockerfile，可以事先构建一个Docker镜像。

```Dockerfile
FROM continuumio/miniconda3:22.11.1

# 使用南大镜像站conda源
COPY .condarc /root/.condarc

# 创建环境
RUN conda create -n my-env python=3.10 numpy

# 激活环境
SHELL ["/bin/bash", "--login", "-c"]
RUN conda init bash
RUN echo "source activate my-env" > ~/.bashrc
ENV PATH /opt/conda/envs/my-env/bin:$PATH
```
此处`.condarc`是修改为了南京大学镜像站的软件源以保证速度。如果要安装其他的包，把`numpy`改成你要的包即可，同时还可以控制Python版本。

如若本地有Docker，可通过`docker`本地尝试构建：
```bash
docker build -t escience/conda-numpy .
```
> Docker也可以使用Docker缓存`docker.nju.edu.cn`。

构建完毕后，本地跑一下相关的脚本以测试：
```bash
docker run -i escience/conda-numpy python < test.py
```

## 设置CI/CD

CI/CD是代码托管服务`git.nju.edu.cn`的一个自动化工具，在代码仓库下的`.gitlab-ci.yml`文件中配置CI/CD，可以让服务器按照设定执行自动构建、编译、测试、集成、部署等等。

CI/CD需要一个基础镜像来运行，这个镜像`gcr.nju.edu.cn`也有缓存服务。文件内容如下：
```yaml
# 执行顺序
stages:
  - build
  - test
# 自动构建镜像
build:
  stage: build
  image:
    name: gcr.nju.edu.cn/kaniko-project/executor:debug # 南大gcr缓存加速
    entrypoint: [""]
  script:
    - /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
  rules: # 只在推送标签时触发
    - if: $CI_COMMIT_TAG
# 使用文件来测试
test:
  stage: test
  image:
    name: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}
  script:
    - python "${CI_PROJECT_DIR}/test.py"
    rules:
    - if: $CI_COMMIT_TAG
```

推送代码到仓库后，为某个提交创建标签，例如此处我们创建为`test`，这也会成为镜像的标签。

[![](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/scaled-1680-/image-1693320077376.png)](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/image-1693320077376.png)

触发流水线任务后，如果通过，在 **“CI/CD”-“流水线”** 可以看到作业情况：

[![](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/scaled-1680-/image-1693320092417.png)](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/image-1693320092417.png)

在自动构建成功后，即可在 **“软件包与镜像库”-“容器镜像库”** 中查看到此镜像。

[![](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/scaled-1680-/image-1693320100633.png)](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/image-1693320100633.png)

> 当然，这里你也不一定必须用Kaniko的构建方案，此处是为了实现自动化。你也可以本地构建完毕后通过`docker push`命令直接推送至`reg.nju.edu.cn`来托管。此外，Singularity有其自己的[定义文件](https://docs.sylabs.io/guides/latest/user-guide/definition_files.html)（类似Dockerfile），可以用类似的方式一步到位而不需要单独构建一个Docker镜像。

## 在集群上使用

`hpc.nju.edu.cn`唐楼集群的简单基本使用见[《校内用户超算集群申请与基本使用简明指南》](https://doc.nju.edu.cn/books/efe93/page/2024)一文。

登录集群通过此镜像来构建Singularity镜像：
```bash
singularity build conda-numpy.sif docker://reg.nju.edu.cn/escience/singularity-example:test
```
[![](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/scaled-1680-/image-1693320116488.png)](https://doc.nju.edu.cn/uploads/images/gallery/2023-08/image-1693320116488.png)

虽然镜像较大，但是可以看见速度仍然很快，这正是开头**全程校园内网**带来的好处。

由于示例是一个`numpy`的环境，后续我们对应地使用作业脚本即可。创建一个`job.lsf`文件：
```shell
#BSUB -q 6140ib
#BSUB -n 1

module load singularity/latest

SINGULARITY="singularity run --env MKL_NUM_THREADS=$LSB_DJOB_NUMPROC conda-numpy.sif"
${SINGULARITY} python test.py
```
然后执行
```shell
bsub < job.lsf
```
通过`bjobs`查看任务运行情况，完成后通过`bpeek`指令可以查看输出，可以看到，任务成功提交并正确执行了。

## 总结

通过CI/CD自动构建Docker镜像并用于HPC集群计算的简单示例，我们尝试将eScience的下列服务进行了结合：

+ 缓存/镜像加速：`docker.nju.edu.cn`、`gcr.nju.edu.cn`、`mirror.nju.edu.cn`
+ CI/CD自动构建：`git.nju.edu.cn`、`reg.nju.edu.cn`
+ 计算集群：`hpc.nju.edu.cn`

在这个过程中，这些服务的灵活使用有助于从版本控制、环境搭建、迁移部署等诸多方面建立可靠的工作流程，最终得以节省时间、便捷开发，提升创新协同的质量。