1.准备工作

1.1.docker-compose

根据文档,用docker的方法需要用到docker-compse。首先要安装一下docker-compose,文档给了三个方法,安装docker desktop、安装docker-compose插件、单独安装docker-compose。已经安装过docker了,感觉不需要Desktop,然后单独安装也不推荐,所以打算采用第二种方法。

然后就是直接用apt-get安装即可。

sudo apt-get update
sudo apt-get install docker-compose-plugin

1.2.端口

使用netstat -tulnp查看端口的使用情况。找一个没用的端口,比如现在假设3000是空的。

  • -t 表示显示TCP端口

  • -u 表示显示UDP端口

  • -l 表示显示侦听状态的套接字

  • -n 表示显示数字形式的地址和端口号

  • -p 表示显示进程的PID和名称,需要root权限

2.启动Gitea

在合适的路径创建一个docker-compose.yml文件,粘贴一下内容。文件名为默认的配置文件的名称,不需要修改,或者改了的话在执行命令的时候需要手动置顶一下配置文件的路径。

然后cd到配置文件所属目录下,执行docker-compose up -d命令,其中up表示启动,-d表示后台启动,这里没有指定配置文件的路径,会默认查找目录下的docker-compose.yml文件,或者可以通过-f来指定。另外不知道是因为我是通过插件方式安装还是怎么样,我这边docker-compose命令是找不到的,而是要改为用docker compose,没有了中间的横线。

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.21.1
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"

配置文件中制定了gitea所用的镜像,以及自动重启、数据卷、端口等。数据卷一个是放数据的,两个是同步时区时间的,3000就是访问的端口。这里不指定MySQL等就是默认使用SQLite3作为数据库。

然后执行docker compose up -d命令后,出现了如下的报错。看起来应该是网络问题,访问超时了。

Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

网上搜一下,参考别人的然后加几个镜像源,重启。再执行就可以了。

如果3000端口没有开的话要开一下。然后就可以在浏览器通过访问ip+端口来进入gitea。

第一次打开需要进行一些设置,基本都不用改,名称什么的可以改一下。

另外发现个小细节,其实这个gitea部署在了174服务器上,然后另外弄了个frp搞了内网穿透使得能够在外网访问。然后实际外网用的时候发现,注册发的激活邮件显示的地址是内网的(因为配置里面写的ROOT_ULR是内网),所以导致外网无法注册,后面就把这个ROOT_ULR改成外网的地址了,能够在外网访问。

后面我还想着个ROOT_ULR会不会导致git的地址只能用外网了,结果试了一下发现用内网地址打开网页仓库显示的git地址就是内网地址,用外网地址打开网页显示的就是外网地址,且两个都是可以用的,在这一点上倒是还挺智能的。

3.自动备份

自动备份的方法有很多,了解了一下,打算采用直接把数据卷的内容打包然后scp发送到别的服务器的方式,然后用cron来定期执行。

3.1.备份

想把数据备份到76服务器,但是76又需要密钥登录,不是很想把登录76密钥放在174服务器上,所以打算在76上创一个容器并暴露一个端口出来直接访问,再用数据卷把数据存到宿主机上即可。有一个需要解决的就是这个容器和里面的ssh服务要开机自启,不然每次重启过了还有手动开启很麻烦。

在76服务器,本来想直接采用docker compose的方式实现安装ssh和自动启动,但是不知道为什么一直运行失败。后面改为先用dockerfile创建一个镜像,然后用docker compose直接运行这个。

Dockerfile的内容如下,密码可按需修改。

FROM ubuntu:20.04

# 安装所需内容
RUN apt-get update && \
    apt-get install -y openssh-server ssh vim \
    && mkdir /var/run/sshd

# 设置密码
RUN echo "root:HERE-IS-PASSWORD" | chpasswd
# 修改ssh配置(允许密码登录、root登录)
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
    && sed -i 's/^#\(PermitRootLogin.*\)/\1/' /etc/ssh/sshd_config

# 启动ssh服务
CMD ["/usr/sbin/sshd", "-D"]

# 暴露端口
EXPOSE 22

docker compose的配置如下,端口XXXX按需修改。

services:
  ssh-container:
    image: bak_container:1.0
    container_name: gitea_bak_container
    ports:
      - "XXXX:22"
    volumes:
      - ./data:/root/data
    restart: unless-stopped

然后按照下面的步骤在目录中执行。

# 创建镜像
docker build -t bak_container:1.0 .

# 启动容器
docker compose up -d

然后应该就直接能够访问了(还需要开放端口),然后可以再进去用`ssh-keygen`生成一对密钥,公钥放到容器里,私钥拿回到174服务器用。

在174服务器,也创建一个.sh文件(按需修改相应内容),bash执行这个文件(要sudo)就可以将数据打包发送过去,然后检查一下当前的备份个数如果超过设定值就删除以前的。

#!/bin/bash

# 定义备份源和备份目的地
GITEA_DATA_DIR="PATH"
REMOTE_USER="root"
REMOTE_HOST="10.1.16.76"
REMOTE_PORT="XXXX"
REMOTE_DIR="/root/data"
REMOTE_PW="pwd"
SSH_KEY_PATH="PATH TO SSH KEY"
BACKUP_NAME="gitea-backup-$(date +'%Y-%m-%d-%H%M%S').tar.gz"
BAK_COUNT="5"

# 创建备份文件并压缩 Gitea 数据
tar -czf /tmp/$BACKUP_NAME -C $GITEA_DATA_DIR .

# 将备份文件复制到远程服务器
scp -i ${SSH_KEY_PATH} -P ${REMOTE_PORT} /tmp/$BACKUP_NAME ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}

# 删除本地临时备份文件
rm /tmp/$BACKUP_NAME

# # 保留最近 K 个备份,删除超出的备份
ssh -p ${REMOTE_PORT} -i ${SSH_KEY_PATH} ${REMOTE_USER}@${REMOTE_HOST} "cd ${REMOTE_DIR} && ls -t | grep 'gitea-backup-' | sed -e '1,${BAK_COUNT}d' | xargs -I {} rm -f {}"

3.2.自动执行

然后上述的.sh文件是需要自动执行的,使用cron来实现自动执行(首先要给.sh文件添加可执行权限)。

sudo crontab -e # 进入修改cron的配置

然后在配置文件里面添加如下命令进行保存,代表每天凌晨四点执行bash。

0 4 * * * sudo /media/E/public_projects/gitea/auto_backup.sh

然后因为要用到sudo,以防执行的时候需要输密码导致执行不了。给这个文件添加免密执行。可以修改/etc/sudoers这个文件来实现,可以用`sudo visudo`这个命令来修改。添加以下内容然后保存即可。

root ALL=(ALL) NOPASSWD: /path/to/my.sh
lxb ALL=(ALL) NOPASSWD: /path/to/my.sh
# 以防万一把root和自己的账号都添加了

如果要停止的话可以是再进到cron的配置里面删掉前面的配置。

参考

docker-compose文档

gitea文档

CSDN | Docker容器内添加ssh开机自启动

GPT、Kimi