Docker环境构建Gitea版本库服务

Gitea是一个开源软件包,用于托管使用Git以及其他协作特性(如bug跟踪、wiki和代码审查)的软件开发版本控制。它支持自托管,但也提供一个免费的公共第一方实例托管在滴滴的中国云,它是Gogs的分支,Gitea使用Go语言编写,可以托管在Go支持的所有平台上,包括Linux、macOS和Windows。项目由Open Collective资助。以上来自维基百科

建立一个管理Gitea服务的项目

项目目录结构如下:

1
2
3
4
5
$ tree
├── docker-compose.yaml
└── etc
    ├── localtime
    └── timezone

项目目录正如你所见是不是特别的简单呀!有一个docker-compose.yaml文件和一个etc目录,docker-compose.yaml这个文件是定义具体的容器服务,而etc目录则是为了保障容器环境时区为北京时间,添加的两个文件配置文件,localtime文件是拷贝于我本机Mac,而timezone是我手动添加的,这个timezone文件的具体内容为Asia/Shanghai,这个可以根据你的国家进行设置。

docker-compose.yaml

这个docker-compose.yaml是docker compose工具在运行容器服务时默认加载的配置文件,当然你也可以是其它的文件名,不过还是使用官方的建立吧,就叫docker-compose.yaml,遵守规则还是很有必要的,会省去很多麻烦,如果你非得不叫这个文件名,你在使用docker-compose运行容器服务时要指明配置文件。再来说一下何为docker compose? 说白了它就是对一组容器统一管理,而不用单个的运行容器,可以使用buildupdown来快速的管理容器服务,当然还有其它的一些命令,常用的就这几个,具体可以参数官方文档进行更深入的了解。这个文件定义如下:

 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
version: "3.6"

services:
  gitea-server:
    image: gitea/gitea:latest
    container_name: wmx-gitea-server
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - DB_TYPE=mysql
      - DB_HOST=db-server:3306
      - DB_NAME=gitea
      - DB_USER=gitea
      - DB_PASSWD=helloworld
    restart: always
    networks:
      - gitea
      - externals
    volumes:
      - /usr/local/data/docker/gitea:/data
      - ./etc/timezone:/etc/timezone:ro
      - ./etc/localtime:/etc/localtime:ro
    ports:
      - "22:22"

networks:
  gitea:
    driver: bridge
  externals:
    external: true

这个文件特别简单,需要特别注意的是DB_HOST=db-server:3306这个环境变量,还有networks中定义的externals外部网络,当前这个docker-compose.yaml中定义的gitea-server服务,要想访问容器环境中的另外容器服务,必须让这个两个容器在同一外部网络内(当然容器之间的链接还其它方式),这里是externalsdb-server这个容器服务是我在另外一个单独的容器管理项目中定义的(用于单独的管理MYSQL容器服务),他们都在externals外部网络内。对于这个文件需要特别说明一点,当容器服务在宿主主机或外部网络不需要使用的时候不需要指定容器端口号与宿主主机端口关联操作,容器与容器之间的服务访问只需要在同一外部网络内,然后指定相应的服务名加端口号进行链接,即可实现我们的需求,具体的用于单独管理MYSQL容器服务的docker-compose.yaml文件定义如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: "3.6"

services:
  db-server:
    image: mysql:8.0
    container_name: wmx-db-server
    restart: always
    environment:
        - MYSQL_ROOT_PASSWORD=helloworld
    networks:
        - dbnet
        - externals
    volumes:
        - /usr/local/data/docker/mysql/8.0:/var/lib/mysql
        - ./etc/timezone:/etc/timezone:ro
        - ./etc/localtime:/etc/localtime:ro
    ports:
      - "3308:3306"

networks:
  dbnet:
    driver: bridge
  externals:
    external: true

你可以参数我的另一博文《Docker下如何优雅的管理你的NGINX》来了解更多的docker-compose.yaml文件定义。

建立MYSQL用户及数据库

建议为你的每一个应用创建单独的用户及数组库,不要使用root用户,权限太大,在你的宿主主机上连接到MYSQL容器服务进行操作,如果你觉得在远程服务器命令行操作实在不方便,你可以在本地使用MYSQL管理工具连接到远程MYSQL容器服务,如Navicat,当然如果你使用的是阿里云ECS服务器,你需要先将3308端口添加到安全组,要不然姜子牙再生他也帮你连接不成功远程ECS服务器中的MYSQL容器服务,还有就是你还需要将3308添加到防火墙对外开放,才可以(如何开放端口可以参考我的另一博文《CentOS7开放端口号》)。图形化操作应该不是问题吧!

创建容器挂载数据目录

你在上面的docker-compose.yaml文件中也看到了,在定义gitea-server服务时指定了数据卷挂载/usr/local/data/docker/gitea:/data操作,这个宿主主机/usr/local/data/docker/gitea目录,你可以随意创建任何位置便于管理即可,说一下这里为什么不用数据卷容器,而直接指定其宿主主机目录位置,不用再多一个环节创建数据卷容器,少了中间一层,主要是方便,还需要明确一点,挂载宿主主机目录到容器的目的是什么? 是不是想让容器产生的数据关联到宿主主机也就是数据持久性保存,而不至于容器干掉了,数据也丢失了,目的达到了也就可以了,不要把问题复杂化。

1
$ mkdir -p /usr/local/data/docker/gitea

使用docker compose运行容器服务

这里还是需要强调一下,什么时候使用build命令,什么时候使用up命令,好多小伙伴分不清,build命令是在你的docker-compose.yaml文件中指定了服务需要构建镜像时(定义服务时有build: "."build: "./config"之类的),才需要使用先使用docker-compose build 来构建镜像,之后再使用docker-compose up 来启动容器服务,当然你也可以直接docker-compose up它会先构建镜像然后再启动容器服务。如果在你的docker-compose.yaml文件中定义服务时直接使用了第三方镜像如上面的image: gitea/gitea:latest,这时你使用docker-compose build它会直接跳过,为什么呢? Docker Compose 工具会检测你这个docker-compose.yaml文件定义,它一看gitea-server这个服务定义使用的是镜像,直接跳过并提示db-server uses an image, skippingdocker-compose build它会依赖容器服务定义中的build: "."指定目录中的Dockerfile文件,以Dockerfile定义来构建服务所要使用到的镜像。直接了当地说,build先构建镜像,而up使用镜像启动容器服务,就是这么简单。

1
$ docker-compose up -d

-d参数是后台启动对吧,跟你在启动单个容器时执行的docker run -d ....是一样的。后台启动这个服务守护进程!

建立二级域名NGINX反向代理

在我的另一博客《Docker下如何优雅的管理你的NGINX》已经有介绍,可以参考一下!现在只需要在NGINX容器服务单独管理项目(docker-nginx)中添加一个的config/ss/git.wumoxi.com.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
30
31
server {
    listen 443 ssl;
    server_name git.wumoxi.com;

    # SSL signature.
    ssl_certificate /etc/nginx/ca/git.wumoxi.com/cert.pem;
    ssl_certificate_key /etc/nginx/ca/git.wumoxi.com/cert.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;

    # Http response body max size.
    client_max_body_size 8m;

    # Proxy application backend api service.
    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://gitea-server:3000/;
    }

    location ~ /\.ht {
        deny all;
    }
}

server {
    listen 80;
    server_name git.wumoxi.com;
    rewrite ^(.*) http://$host$1 permanent;
}

注意了,这里最主要的是反向代理proxy_pass http://gitea-server:3000/;,上面已经强调过了gitea-server这个服务必须和(docker-nginx中定义的服务)nginx-server是在同一外部网络内。重新启动NGINX容器服务,在项目目录下直接执行docker-compose build构建镜像(因为有自定义Dockerfile存在),然后使用docker-compose down将之前的容器服务先停掉,再执行docker-compose up -d 即可!这个二级域名为git.wumoxi.com

使用浏览器访问Gitea服务

输入二级域名git.wumoxi.com访问Gitea服务,结果如下所示:

截屏2020-04-23下午7.03.47.png

不错嘛,可以访问了,是不是距离成功又进了一步。

安装Gitea服务

刚刚访问首页预览成功,你点点看嘛,是不是直接跳转取了安装页面,如下所示:

screencapture-git-wumoxi-install-2020-04-23-19_17_49.png

数据库设置

数据库设置这里,基本上不用改动,这些信息是Gitea读取到上面的docker-compose.yaml文件配置的容器环境变量,只需要将字符集改为utf8mb4,因为当前所使用的MYSQL版本是8.0,8.0默认字符集就是utf8mb4,并且校对集为utf8mb4_0900_ai_ci

1
2
3
4
5
6
7
mysql> SHOW CREATE DATABASE gitea;
+----------+---------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                                 |
+----------+---------------------------------------------------------------------------------------------------------------------------------+
| gitea    | CREATE DATABASE `gitea` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

一般设置

字段
站点名称 你可以指定一个站点描述信息
仓库根目录 不用动,默认就好
LFS根目录 不用动,默认就好
以用户名运行 默认git就可以不用动
SSH 服务域名 如: git.wumoxi.com
SSH 服务端口 默认22不用动
HTTP 服务端口 要修改为 80443
Gitea 基本 URL 如:http://git.wumoxi.com/
日志路径 不用动,默认就好

可选设置(Gitea邮件服务)

字段
SMTP 主机 如果你使用的foxmail: 如:smtp.qq.com:465,如果你使用其它的邮箱服务请勿必将SMTP地址设置正确
电子邮件发件人 发送邮件的发件人名称(经过测试它必须是一个邮箱地址):如:example@foxmail.com
SMTP 用户名 发送邮件的邮箱地址:如:example@foxmail.com
SMTP 密码 如果使用Foxmail请生成授权码,如: hello-world-email-secret
需要发电子邮件确认注册 勾选
启用邮件通知提醒 勾选

这样就可以了,它会是Gitea服务发送邮件的默认邮箱。下面是全部配置如:

screencapture-git-wumoxi-install-2020-04-24-10_26_51.png

安装Gitea应用

这里要说一下,当你点击立即安装时,Gitea会初始化数据库(主要是生成数据表)、Gitea服务生成应用配置文件(你可以到你指定的挂载目录/usr/local/data/docker/gitea去查看),然后跳转到用户登录页面,如下所示:

截屏2020-04-23下午8.17.01.png

创建hello-world仓库走流程

注册用户

需要注意了,第一个注册的用户将会成为管理员。注册成功之后会自动登录。

创建仓库

screencapture-git-wumoxi-repo-create-2020-04-23-20_26_51.png

注意,勾选初始化存储库(添加.gitignore、许可证和自述文件),你好歹也让它有点文件!

修改提交

screencapture-git-wumoxi-wumoxi-hello-world-edit-master-README-md-2020-04-23-20_32_44.png

将README.md文件内容从hello-world修改为hello-world-change-online, 直接提交变更。

screencapture-git-wumoxi-wumoxi-hello-world-edit-master-README-md-2020-04-23-20_42_05.png

咦~不好了吧,提交不成功,可以看到它调用了http://localhost:443/api/internal/hook/pre-receive/wumoxi/hello-world这个地址,那就是gitea-server这个服务有问题,什么问题呢?从官网这里可以找到答案!

1
注意:如果在http上使用非3000端口,请将app.ini更改为match LOCAL_ROOT_URL = http://localhost:3000/。

有了这一句解释之后就可以打开/usr/local/data/docker/gitea/gitea/conf/app.ini配置文件在[server]配置区块中加入LOCAL_ROOT_URL = http://localhost:3000/

1
2
[server]
LOCAL_ROOT_URL = http://localhost:3000/

修改这个配置文件之后,再次提交,即可提交成功!

screencapture-git-wumoxi-wumoxi-hello-world-src-branch-master-README-md-2020-04-23-22_40_26.png

克隆到本地做修改测试(HTTPS方式)

克隆

1
2
3
4
5
6
7
$ git clone http://git.wumoxi.com/wumoxi/hello-world.git
Cloning into 'hello-world'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.

修改提交

1
2
3
4
5
6
7
8
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 292 bytes | 292.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To http://git.wumoxi.com/wumoxi/hello-world.git
   3e66c6b..507fb76  master -> master

正如上面所见,因为是公有项目,无需添加SSH公私即可克隆和提交代码,注意哦,上面是通过HTTPS方式,而非SSH,试试SSH方式如何!

克隆到本地做修改测试(SSH方式)

将仓库修改为私有,添加SSH公钥到你注册的账号,进行仓库克隆操作。

克隆

1
2
3
4
5
6
7
$ git clone git@git.wumoxi.com:wumoxi/hello-world.git
Cloning into 'hello-world'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (6/6), done.

修改提交

1
2
3
4
5
6
7
8
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 293 bytes | 293.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To git.wumoxi.com:wumoxi/hello-world.git
   6a56230..f13019d  master -> master

经过上面的简单测试HTTPS和SSH方式可都完成项目的版本操作,特别说明一下我的服务器SSH端口号非标准22,而让这个Gitea服务使用标准的SSH端口号22,这样很容易配置。这样在仓库的SSH链接上也不会有很难看的端口号。其它方面的安全问题,你动手都测试一下做到相对安全。就是这个样子简单吧!

screencapture-git-wumoxi-2020-04-24-10_41_04.png

comments powered by Disqus