#Docker

binfmt_misc 简介

binfmt_misc 是 Linux 内核提供的一个机制,它允许用户空间定义新的二进制格式,并将它们与相应的解释器关联起来。这个机制使得在 Linux 上能够动态地注册并运行不同架构的二进制可执行文件,从而支持交叉编译和多架构环境。

具体来说,binfmt_misc 的功能可以通过 /proc/sys/fs/binfmt_misc/ 目录下的文件系统接口实现。这个目录下的文件用于注册和管理二进制格式和相应解释器之间的关联关系。

下面是一些与 binfmt_misc 相关的重要概念和文件:

  1. 注册表文件:/proc/sys/fs/binfmt_misc/ 目录下,每个注册的二进制格式都有一个对应的注册表文件。这些文件的命名通常遵循格式 <格式名称>,例如 qemu-riscv64
  2. 注册和注销: 用户空间可以通过在注册表目录下创建文件来注册新的二进制格式。这可以通过写入注册表文件的方式完成。相反,通过删除这些文件,可以注销二进制格式的支持。
  3. 解释器: 对于每种注册的二进制格式,需要指定相应的解释器,即用于执行这种格式的程序。在注册表文件中,通过 interpreter 字段指定解释器的路径。
  4. 参数: 除了解释器,还可以为每个注册的格式指定一些参数。这些参数可以影响如何运行二进制文件。

内核如何通过 binfmt_misc 机制添加新架构的支持?

可以通过向 /proc/sys/fs/binfmt_misc/register 文件写入注册信息来注册新的二进制格式。告诉内核某一格式的文件用什么解释器来执行。写入的格式如下:

:name:type:offset:magic:mask:interpreter:flags

各个字段以冒号分隔,部分字段可以缺省,但是冒号需要保留。

字段含义如下:

  • name:二进制格式的名称,比如qemu-riscv64

  • type:类型为 E 或 M。

    • 如果是 E,可执行文件格式由其文件扩展名标识:magic 是要与二进制格式相关联的文件扩展名;offset 和 mask 将被忽略。
    • 如果是 M,格式由文件中绝对偏移(默认为 0)处的魔数标识,并且 mask 是一个位掩码(默认为全 0xFF),表示数字中哪些位是有效的。
  • interpreter:是要作为匹配文件的参数运行的解释器,使用解释器的绝对路径,比如/usr/bin/qemu-riscv64-static

  • flags:可选字段,控制 interpreter 打开文件的行为。共支持 POCF 四种 flag。

    • P 表示 preserve-argv[0],保留原始的 argv[0] 参数。
    • O 表示 open-binary,binfmt-misc 默认会传递文件的路径,而启用这个参数时,binfmt-misc 会打开文件,传递文件描述符。
    • C 表示 credentials,即会传递文件的 setuid 等权限,这个选项也隐含了 O
    • F 表示 fix binary,binfmt-misc 默认的行为在 spwan 进程时会延迟,这种方式可能会受到 mount 命名空间和 chroot 的影响,设置 F 时会立刻打开二进制文件。

举个例子,如果要在 x86_64 架构的系统上运行 RISC-V 架构的二进制文件,可以通过以下方式注册 RISC-V 二进制格式:

首先需要添加解释器,通常使用 QEMU 的静态二进制文件作为解释器,在 Ubuntu 系统中我们可以使用以下命令安装:

sudo apt install qemu-user-static

注册二进制格式

echo ':qemu-riscv64:M:0:7f454c460201010000000000000000000200f300::/usr/libexec/qemu-binfmt/riscv64-binfmt-P:POCF' > /proc/sys/fs/binfmt_misc/register

表示将 RISC-V 二进制格式注册到 /proc/sys/fs/binfmt_misc/qemu-riscv64 文件中,使用 /usr/libexec/qemu-binfmt/riscv64-binfmt-P 作为解释器,同时传递 POCF 参数。执行了以上命令,内核会自动创建一个 /proc/sys/fs/binfmt_misc/qemu-riscv64 文件,内容如下:

$ sudo cat  /proc/sys/fs/binfmt_misc/qemu-riscv64
enabled
interpreter /usr/libexec/qemu-binfmt/riscv64-binfmt-P
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200f300
mask ffffffffffffff00fffffffffffffffffeffffff

这就完成了 RISC-V 二进制格式的注册。此时,你就可以在 x86_64 架构的系统上运行 RISC-V 架构的二进制文件了。

使用 Docker 运行 RISC-V 的容器:

$ docker run --rm -it devops/openeuler-builder:23.09-riscv64  uname -m
riscv64

使用封装好的程序简化注册过程

以上的写入 register 文件的方式比较繁琐,可以使用封装好的程序来简化注册过程。

方式一:

sudo apt install qemu-user-binfmt

可以安装所有 QEMU 支持的架构。

方式二:

# 安装解释器
sudo apt install qemu-user-static
# 安装binfmt操作支持
sudo apt install binfmt-support
# 开启异构支持
sudo update-binfmts --package=qemu-user-static --enable

同上。

注销

echo -1 >/proc/sys/fs/binfmt_misc/status # 注销所有注册的条目
echo -1 >/proc/sys/fs/binfmt_misc/qemu-riscv64 # 注销单个条目

或者通过命令行工具完成:

# 安装binfmt操作支持
sudo apt install binfmt-support
# 禁用qemu-riscv64,再次查看/proc/sys/fs/binfmt_misc/发现qemu-riscv64已被删除
sudo update-binfmts --disable qemu-riscv64

Gitea 如何实现多架构应用构建?

Gitea 不会自己运行 Job,而是将 Job 委托给 Runner。Gitea Actions 的 Runner 被称为 act runner,它是一个独立的程序。在接收到 Job 后,act runner 会根据 Job 的内容,启用不同的 Container 来运行 Job。

为了避免消耗过多资源并影响 Gitea 实例,Gitea 和 Runner 一般运行在不同的机器上。但是同一个 Runner 启动的容器一定在同一台机器上。我这里演示的统一都在同一台 x86 架构的机器上。

因为都运行在 x86 架构的机器上,所有执行任务的 Container 也一定是 x86 架构的。但是我们了解了上面的 binfmt_misc 机制后,就可以在容器内部通过注册不同架构的二进制格式,从而在 x86 架构的机器上运行不同架构的二进制文件。就可以实现多架构应用构建。

打开 Gitea 的 tea 的项目源码找到它的 release workflow 文件,可以看到它使用了docker/setup-qemu-action@v3这个 action 来实现多架构构建。

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

查阅action 的源码,可以发现底层实现是通过binfmt_misc来实现的。

func init() {
    // 定义了一些全局变量
	flag.StringVar(&mount, "mount", "/proc/sys/fs/binfmt_misc", "binfmt_misc mount point")
	flag.StringVar(&toInstall, "install", "", "architectures to install")
	flag.StringVar(&toUninstall, "uninstall", "", "architectures to uninstall")
	flag.BoolVar(&flVersion, "version", false, "display version")
}
func install(arch string) error {
	cfg, ok := configs[arch]
    // 拼接路径为/proc/sys/fs/binfmt_misc/register,打开这个文件检查是否能够打开成功
	register := filepath.Join(mount, "register")
	file, err := os.OpenFile(register, os.O_WRONLY, 0)

	binaryBasename, binaryFullpath, err := getBinaryNames(cfg)
	if err != nil {
		return err
	}
    // 向/proc/sys/fs/binfmt_misc/register 写入 line,注册二进制格式
	line := fmt.Sprintf(":%s:M:0:%s:%s:%s:%s", binaryBasename, cfg.magic, cfg.mask, binaryFullpath, flags)
	_, err = file.Write([]byte(line))
	if err != nil {
		e, ok := err.(*os.PathError)
		if ok && e.Err == syscall.EEXIST {
			return errors.Errorf("%s already registered", binaryBasename)
		}
		return errors.Errorf("cannot register %q to %s: %s", binaryFullpath, register, err)
	}
	return nil
}

Q & A

为何/proc/sys/fs/binfmt_misc/register 文件是只读的?

/proc/sys/fs/binfmt_misc/register 文件是只写的,这是因为在 Linux 中,/proc 文件系统下的很多文件都是通过对文件进行写入来进行配置和控制的。这些文件通常代表内核参数或控制接口,提供了一种方便的方式来与内核进行交互。

对于 /proc/sys/fs/binfmt_misc/register 文件来说,通过写入注册信息,用户可以向内核注册新的二进制格式,告知内核如何执行特定的二进制文件。这种只写的设计是为了保持简单性和安全性。允许用户在运行时动态地注册新的格式,而不是从文件中读取注册信息,可以提供更大的灵活性。

虽然 /proc/sys/fs/binfmt_misc/register 文件是只写的,但是通过向文件中写入正确格式的注册信息,用户仍然能够有效地配置新的二进制格式。这种设计符合 Linux 中的文件系统和权限模型。

参考资料

Kernel Support for miscellaneous Binary Formats (binfmt_misc)

Docker-Compose

version: "3.8"
services:
  nexus:
    image: sonatype/nexus3
    container_name: nexus
    restart: always
    ports:
      - 8081:8081
    volumes:
      - /srv/nexus/data:/nexus-data

修改/srv/nexus目录的所有者为当前用户:

sudo chown -R username:username /srv/nexus

修改data目录有最高权限,否则无法启动成功:

sudo chmod -R 777 /srv/nexus/data

代理Docker Hub

登录WEB页面

登录WEB页面,地址为:http://192.168.1.9:8081。
用户名为:admin,密码通过命令获取:

docker exec nexus3 cat /nexus-data/admin.password

创建Blob

在 Nexus Repository Manager 中,Blob Store(二进制大对象存储)是一个用于存储仓库数据的核心组件。Blob Store 主要用于存储各种二进制文件,例如软件包、依赖库、构建产物等,这些文件通常被称为“blob”。

Blob Store 的作用包括:

  1. 存储二进制文件: Blob Store 被设计用来安全、可靠地存储二进制文件。这些文件可以是各种形式的构建产物、软件包、依赖库等。Blob Store 是 Nexus 仓库管理系统的核心,它为这些文件提供了一个中央存储位置。

  2. 支持不同类型的存储后端: Nexus 支持不同类型的 Blob Store,例如本地文件系统、云存储(如Amazon S3、Google Cloud Storage)等。这使得用户可以根据需求选择不同的存储后端,并根据实际情况进行扩展或迁移。

  3. 提供存储策略: Blob Store 允许你定义存储策略,以确定何时以及如何清理或删除不再需要的文件。这对于管理仓库的存储空间非常重要,可以根据策略自动清理不再需要的快照或旧版本。

  4. 支持代理和缓存: 在 Maven Repository 的场景下,Blob Store 还可以用于代理远程 Maven 仓库,并缓存远程仓库中的文件。这有助于提高构建性能,减少对远程仓库的依赖。

我们缓存的镜像需要存储为blob,所以需要创建一个Blob store。点击左侧菜单栏的Blob Stores,然后点击Create blob store,选择Type为File,Name填写为dockerhub。

创建Repository

在 Nexus Repository Manager 中,有三种主要的仓库类型:Hosted Repository、Proxy Repository、和 Group Repository。每种类型都有不同的作用和用途:

  • Hosted Repository(托管仓库):

    • 作用: 用于存储和管理本地创建的部署(deploy)的二进制文件。这包括你自己或你的团队创建的库,例如 Maven 构件、npm 包、Docker 镜像等。
    • 使用场景: 当你需要在内部存储和分享自己创建的构建产物时,你可以使用 Hosted Repository。
  • Proxy Repository(代理仓库):

    • 作用: 用于代理和缓存远程仓库的二进制文件。当你从远程仓库获取构建依赖时,Proxy Repository 会将这些文件缓存在本地,从而提高构建性能并减少对远程仓库的依赖。
    • 使用场景: 在构建过程中,你通常会依赖于一些公共的远程仓库,例如 Maven Central、npm registry、Docker Hub等。使用 Proxy Repository 可以有效地管理这些依赖并减少对远程仓库的直接访问。
  • Group Repository(组合仓库):

    • 作用: 允许你将多个仓库组合成一个逻辑单元。当你需要在构建中同时使用多个仓库的内容时,Group Repository 可以将这些仓库组合在一起,使它们在应用程序中看起来像一个单一的仓库。
    • 使用场景: 当你有多个 Proxy Repository 或 Hosted Repository 时,你可以使用 Group Repository 将它们组合在一起。这对于简化构建配置、统一依赖管理等非常有用。

我们一般创建三个仓库,proxy代理公共镜像,hosted保存自己的镜像,group将proxy和hosted组合在一起。我们分别创建三个仓库。

proxy

点击左侧菜单栏的Repositories,然后点击Create repository,选择Docker (proxy),按照下图填写:

Remote storage 图中填写为https://registry-1.docker.io,这是dockerhub的地址。但是实测会很慢,所以我们使用加速地址https://dockerproxy.com。需要注意修改一下。

还有一些国内镜像源可选,可以参考这个项目。Test Registry · docker-practice/docker-registry-cn-mirror-test@83a4dd4

Blob store选择为刚刚创建的dockerhub

hosted

hosted比较简单,只需要填个名称就行了,这里填写为docker-hosted

group

group 需要注意以下:

  1. HTTP需要单独设置端口号。我们设置与WEB页面不同的端口号,8082即可。
  2. 需要将proxy和hosted都添加到group中,这样才能将两个仓库组合在一起。

启用Realms

这里要在 Security-Realms 里面启用 Docker Bearer Token Realm。

拉取镜像

如果直接使用docker pull拉取镜像,会报错:

$ docker pull 192.168.1.9:8082/redis

Using default tag: latest
Error response from daemon: Get "https://192.168.1.9:8082/v2/": http: server gave HTTP response to HTTPS client

编辑/etc/docker/daemon.json文件,添加以下内容:

{
  "insecure-registries": [
    "192.168.1.9:8082"
  ],
  "registry-mirrors": [
    "http://192.168.1.9:8082"
  ]
}

注意:registry-mirrors中只保留一个Nexus的地址,这样默认就会从Nexus拉取镜像。如果有多个地址,就可能会从其他地址拉取镜像。因为我们在Nexus中配置的URL就是docker-proxy的地址,他就是一个国内代理地址,所以这里我们只保留一个Nexus的地址就行。
注意: insecure-registries 拼写,不要写成 insecure-registry。最好直接复制,json格式很严格。

重启Docker服务:

sudo systemctl restart docker

登录Docker Registry:

需要注意的shi,这里的用户名和密码是Nexus的用户名和密码,不是Docker Hub的用户名和密码。

docker login 192.168.1.9:8082 -u admin -p admin123

拉取镜像:

$ docker pull redis                      

Using default tag: latest
latest: Pulling from redis
1f7ce2fa46ab: Already exists 
4827e9d1e197: Pull complete 
5845062cfda9: Pull complete 
44d659adcf8b: Pull complete 
b6962d83313d: Pull complete 
5d29cf86ecab: Pull complete 
4f4fb700ef54: Pull complete 
3a2d9f90268c: Pull complete 
Digest: sha256:249e1bfb9448ae9e76807748f8cb3c5cc73e55441b7b36364c61a7428c9e814c
Status: Downloaded newer image for 192.168.1.9:8082/redis:latest
192.168.1.9:8082/redis:latest

可以在首页的Browse Docker中看到镜像已经被缓存了。

推送镜像

如果你需要上传自己修改的镜像,那么就需要修改之前的docker-hosted,其中HTTP中该为8083,和docker-proxy的端口号区分。这样我们就可以从8082下载镜像,从8083推送镜像。

首先我们需要重命名镜像,格式如下

docker tag <imageId or imageName> <nexus-hostname>:<repository-port>/<image>:<tag>
docker tag af340544ed62 192.168.1.9:8083/hello-world:mytag
docker push 192.168.1.9:8083/hello-world:mytag

拉取这个镜像:

docker pull 192.168.1.9:8083/hello-world:mytag

代理 YUM 源

代理 APT 源

和 YUM 源代理稍有不同的是,APT 源代理时没有 Group 仓库,但是使用APT源的系统如Ubuntu也是有多个版本的,我们只需要在 Distribution 参数里填写需要代理的版本即可,每隔版本用逗号分隔。

常用的版本以及代号如下:

  • Ubuntu 16.04 Xenial Xerus
  • Ubuntu 18.04 Bionic Beaver
  • Ubuntu 20.04 Focal Fossa
  • Ubuntu 21.04 Hirsute Hippo
  • Ubuntu 21.10 Impish Indri
  • Ubuntu 22.04 Jammy Jellyfish
  • Ubuntu 22.10 Kinetic Kudu
  • Ubuntu 23.04 Lunar Lobster
  • Ubuntu 23.10 Mantic Minotau

代理地址为:http://192.168.1.9:8081/repository/apt-proxy/,我们可以在Ubuntu中使用这个地址来代理APT源。修改`/etc/apt/sources.list`文件,将原来的源地址替换为Nexus的地址即可。

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://192.168.1.9:8081/repository/apt-proxy/ jammy main restricted universe multiverse
# deb-src http://192.168.1.9:8081/repository/apt-proxy/ jammy main restricted universe multiverse
deb http://192.168.1.9:8081/repository/apt-proxy/ jammy-updates main restricted universe multiverse
# deb-src http://192.168.1.9:8081/repository/apt-proxy/ jammy-updates main restricted universe multiverse
deb http://192.168.1.9:8081/repository/apt-proxy/ jammy-backports main restricted universe multiverse
# deb-src http://192.168.1.9:8081/repository/apt-proxy/ jammy-backports main restricted universe multiverse

deb http://192.168.1.9:8081/repository/apt-proxy/ jammy-security main restricted universe multiverse
# deb-src http://192.168.1.9:8081/repository/apt-proxy/ jammy-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb http://192.168.1.9:8081/repository/apt-proxy/ jammy-proposed main restricted universe multiverse
# # deb-src http://192.168.1.9:8081/repository/apt-proxy/ jammy-proposed main restricted universe multiverse

代理 pip 源

使用阿里云作为代理,我们需要在Nexus中创建一个PyPI代理仓库。点击左侧菜单栏的Repositories,然后点击Create repository,选择PyPI (proxy),按照下图填写:

再创建一个PyPI Group仓库,将刚刚创建的PyPI代理仓库和PyPI Hosted仓库添加到Group仓库中。

编辑/etc/pip.conf文件,添加以下内容:

或者在用户目录下的~/.pip/pip.conf文件中添加

[global]
index = http://192.168.1.9:8081/repository/pypi/
index-url = http://192.168.1.9:8081/repository/pypi/simple
trusted-host =  192.168.1.9

在 WSL2 中使用 Nexus 代理

因为 WSL2 使用的是宿主机Windows的Docker desktop作为Docker引擎,所以我们需要在Windows中配置Docker的代理。打开Docker Desktop,点击Settings,然后选择Docker Engine,添加以下内容:

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "insecure-registries": [
    "http://192.168.1.9:8082"
  ],
  "registry-mirrors": [
    "http://192.168.1.9:8082"
  ]
}

重启Docker Desktop。然后在WSL2中使用 docker info 查看是否配置成功。

常见错误

docker login nexus unauthorized authentication required

  1. 确认登录密码是否正确,密码为Nexus登录密码
  2. 却是否启用Realms

docker login nexus connection refused

docker login 192.168.1.9:8082 -u admin -p admin123
  1. 确认Docker compose配置文件中已经将端口8082暴露,如果新增需要重启Nexus

  2. 确认防火墙关闭或者已经打开端口

    1. ```bash
      sudo ufw allow 8082
      sudo ufw allow 8082/tcp
      
      3. 确认已经将私有仓库添加到了`/etc/docker/daemon.json`,并且及时重启了docker服务
      
          1. ```bash
              sudo systemctl restart docker.service
  3. 确认已经开启了Http connector

    1. 如图:

Tunasync 项目简介

Tunasync 是一个开源的镜像站点镜像工具,可以帮助你快速搭建一个镜像站点,也可以帮助你快速的同步镜像站点的镜像。我们所熟知的清华大学镜像站就是使用 Tunasync 来同步镜像的。

准备 workspace

创建目录用于存放 Tunasync 的程序、配置文件和数据库文件:

1
2
3
mkdir /home/username/tunasync
mkdir /home/username/tunasync/conf
mkdir /home/username/tunasync/db

创建目录用于存放镜像文件:

1
sudo mkdir /srv/mirrors

srv 目录需要 root 权限,将 mirrors 目录的所有者改为当前用户:

1
sudo chown -R username:username /srv/mirrors

下载 Tunasync

可以从 Tunasync 项目的 Github releases 编译好的程序直接使用。

1
2
3
cd /home/username/tunasync
wget https://github.com/tuna/tunasync/releases/download/v0.8.0/tunasync-linux-amd64-bin.tar.gz
tar -zxvf tunasync-linux-amd64-bin.tar.gz

配置 Tunasync

Manager 配置

创建配置文件/home/username/tunasync/conf/manager.conf,并添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
debug = false

[server]
addr = "127.0.0.1"
port = 12345
ssl_cert = ""
ssl_key = ""

[files]
db_type = "bolt"
db_file = "/home/username/tunasync/db/manager.db"
ca_cert = ""

Worker 配置

创建配置文件/home/username/tunasync/conf/worker-openeuler.conf,并添加以下内容:

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
[global]
name = "openeuler_worker"
log_dir = "/srv/mirrors/log/tunasync/{{.Name}}"
mirror_dir = "/srv/mirrors"
concurrent = 10
interval = 1440

[manager]
api_base = "http://localhost:12345"
token = "some_token"
ca_cert = ""

[cgroup]
enable = false
base_path = "/sys/fs/cgroup"
group = "tunasync"

[server]
hostname = "localhost"
listen_addr = "127.0.0.1"
listen_port = 16010
ssl_cert = ""
ssl_key = ""

[[mirrors]]
name = "centos"
provider = "rsync"
upstream = "rsync://mirrors.tuna.tsinghua.edu.cn/openeuler/"
use_ipv6 = false

启动 Tunasync

启动 Manager

1
2
cd /home/username/tunasync
./tunasync manager -c conf/manager.conf >> /srv/mirrors/log/plog/manager.log &

启动 Worker

1
2
cd /home/username/tunasync
./tunasync worker -c conf/worker-openeuler.conf >> /srv/mirrors/log/plog/worker-openeuler.log &

通常可能同步不止一个镜像站点,可以创建多个 Worker 配置文件,然后启动多个 Worker。

创建 web 服务

  1. 安装 Apache2:

    1
    2
    sudo apt update
    sudo apt install apache2
  2. 修改配置文件:

    Ubuntu 中的 Apache2 主要配置文件是 /etc/apache2/apache2.conf。可以在此文件中进行全局配置,也可以使用专门的配置文件,例如 /etc/apache2/sites-available/your-site.conf

    1
    sudo nano /etc/apache2/apache2.conf

    apache2.conf 文件中,添加以下行,设置 DocumentRoot 和目录访问权限:

    1
    2
    3
    4
    5
    6
    7
    DocumentRoot /mirrors

    <Directory "/mirrors">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
    </Directory>

    请确保将 <Directory> 部分添加到正确的位置。可以在文件中找到 <Directory /var/www/> 部分,然后在该部分下添加配置。

  3. 重新启动 Apache2 服务:

    在进行配置更改后,需要重新启动 Apache2 服务以使更改生效:

    1
    sudo systemctl restart apache2
  4. 补充文件:

    index.html 文件和其他需要的文件添加到 /srv/mirrors 目录中。

  5. 测试:

    打开 Web 浏览器,访问 http://your-server-iphttp://localhost,应该能够看到 /srv/mirrors 目录中的文件。

  6. 如打不开,需要开启防火墙

    1
    2
    sudo ufw allow http
    sudo ufw allow https
  7. 修改 Web 服务端口

    1. 编辑 Apache2 配置文件:

      1
      sudo nano /etc/apache2/ports.conf
    2. **在文件中找到 Listen​ ** 行,修改端口:

      1
      Listen 2081
    3. 编辑虚拟主机配置(如果有):

      如果你有虚拟主机配置文件(通常在 /etc/apache2/sites-available/ 中),确保其中的 <VirtualHost> 部分中的端口也被修改为 2081。

    4. 保存并退出配置文件。

    5. 重启 Apache 服务:

      1
      sudo systemctl restart apache2

打开防火墙端口

1. **打开 2081 端口:**

    
1
sudo ufw allow 2081
2. **检查配置:**
1
sudo ufw status
确保 2081 端口已经正确添加。 3. **重启防火墙(可选):**
1
sudo ufw reload
或者
1
sudo systemctl restart ufw
这样,你就将 Apache2 Web 服务的端口修改为 2081,并且只开放了 2081 端口。确保修改了防火墙规则后,仍能够通过新的端口访问你的网站。

docker-compose 部署

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
version: "3.7"

services:
postgres:
image: postgres:latest
container_name: postgres
ports:
- 5432:5432
networks:
- br-net-gitea
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: 123456
POSTGRES_DB: gitea
volumes:
- ./postgresql:/var/lib/postgresql
- ./data:/var/lib/postgresql/data

gitea:
image: gitea/gitea:1.20.5
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=192.168.1.9:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=user
- GITEA__database__PASSWD=123456
restart: always
networks:
- br-net-gitea
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh/:/data/git/.ssh


ports:
- 3000:3000
- "127.0.0.1:2222:22"


depends_on:
- postgres

act_runner:
image: gitea/act_runner:latest
environment:
- GITEA_INSTANCE_URL=http://192.168.1.9:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=Qw5Qf4A1bTENfIOQlc1NSNyFYMLp7TAtSujb5ihF
- GITEA_RUNNER_NAME=docker_runner
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./act_runner/act_data:/data
- ./act_runner/act_cache:/root/.cache

常见问题

首次登录web时没有创建管理员账号,如何登录

打开Gitea网页注册的第一个账号就是管理员账号。无需特殊设置。也无需找回密码。

从Github导入仓库时报错:从不允许的主机导入

打开配置文件gitea/conf/app.ini,修改以下配置:

1
2
3
4
[migrations]
ALLOW_LOCALNETWORKS = true
ALLOWED_DOMAINS = 127.0.0.1,192.168.31.100,github.com,*.github.com
IMPORT_LOCAL_PATHS = true ;; 导入本地仓库开关,false:设置为false,防止所有用户(包括admin)导入服务器上的本地路径。

docker-compose restart gitea重启容器。

以下修改配置文件后,需要重启容器才能生效,不再赘述。

如何开启软件包

1
2
[packages]
ENABLED = true

开启action

1
2
[actions]
ENABLED=true

error response from daemon server gave http response to https client

docker login 报错

配置/etc/docker/daemon.json

1
2
3
"insecure-registries": [
"192.168.1.9:2010"
]

如何上传docker镜像到gitea制品库

1
2
3
4
5
6
7
8
9
# 登录你的镜像仓库,也就是你的 Gitea 服务器地址
docker login 192.168.1.9:2010

# 从官方仓库拉取一个 nginx:latest 镜像,并改名
docker pull nginx:latest
docker tag nginx:latest 192.168.1.9:2010/zhangsan/nginx:latest

# 推送镜像到 Gitea 服务器
docker push 192.168.1.9:2010/zhangsan/nginx:latest

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: "3.7"

services:
radarr:
container_name: radarr
image: dockerproxy.com/linuxserver/radarr:latest
ports:
- "7878:7878"
environment:
- PUID=1000
- PGID=1000
- UMASK=002
- TZ=Asia/Shanghai
volumes:
- /root/sharedfolder/appdata/radarr:/config
- /root/sharedfolder/media:/movies
- /root/sharedfolder/downloads/qbittorrent:/downloads

配置中文界面:

导入视频:

在 WSL2 中,你可能会遇到与 Docker 服务相关的问题,因为 WSL2 与传统 Linux 系统在某些方面有所不同。在这种情况下,你可以尝试以下步骤来解决问题:

  1. 首先,确保你已经安装了 WSL2 的最新版本。你可以通过运行以下命令来更新 WSL2:
1
wsl --update
  1. 确保 Docker Desktop for Windows 已安装并启用 WSL2 集成。你可以在 Docker Desktop 设置中找到这个选项。确保你的 WSL2 发行版已被添加到 Docker Desktop 的 WSL 集成列表中。点击链接下载安装在 Windows 上安装 Docker 桌面
  2. 在 WSL2 中,尝试手动停止 Docker 服务:
1
sudo /etc/init.d/docker stop
如果这个命令无法停止 Docker 服务,请尝试以下命令:
1
sudo killall dockerd
  1. 卸载 Docker:
1
sudo apt-get purge docker-ce
  1. 删除 Docker 相关的文件和目录:
1
sudo rm -rf /var/lib/docker
  1. 重新启动 WSL2:
1
wsl --shutdown
  1. 然后重新打开 WSL2。
  2. 在 WSL2 中,不要直接安装 Docker CE。而是使用 Docker Desktop for Windows 提供的 Docker 服务。这意味着你不需要在 WSL2 中安装 Docker CE,因为 Docker Desktop 已经提供了 Docker 服务。
  3. 确保你的 WSL2 发行版可以访问 Docker Desktop 提供的 Docker 服务。你可以通过运行以下命令来检查:
1
2
3
docker --version

docker info
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×