0%

关于DroneDocker in Docker (dind)解决方案,本人历经2天尝试了各种解决方案,最终解决方案为volumes挂载,已在本文体现

为什么

为什么?为什么要使用GogsDrone?答案是习惯!!!

工作中一般使用GIT管理工具为gitlab,自有开源项目一般都是使用的github,自有私有项目之前一直用gitee;玩Nas也有好几年了,最初也想过在Nas上通过docker搭建gitlab无奈配置不过硬

怎么说呢?了解Gogs是在它出来的那一段时间,但是也一直没有用过。最近心血来潮还是想自己在Nas上做一个GIT私有服;于是挑中了GogsGitea,鉴于两个服务属于同源最后选择了Gogs

Gogs

关于Gogs的安装我这里就不过多的赘述,可以看下面的两个文档

Gogs Github

Gogs Docker

这需要说明的是Gogs支持MySQL, PostgreSQL, SQLite3, MSSQLTiDB;目前我使用的是MySQL,关于Mysql的安装部署可以查看官方文档这里也不过多赘述

Mysql安装文档

对于在群晖Docker中去管理Mysql的工具这里我推荐adminer安装文档如下

adminer安装文档

最后我要说的是一个是端口映射的问题,一个是卷映射的问题,如下图


最后直接访问:http://192.168.1.2:10080就OK了

这里贴出一下整个Gogs配置文件

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
// /data/gogs/conf/app.ini

APP_NAME = Gogs
RUN_USER = git
RUN_MODE = prod

[database]
DB_TYPE = mysql
HOST     = 192.168.1.2:3306 // mysql地址端口
NAME     = gogs
USER = root
PASSWD   = password // mysql密码
SSL_MODE = disable
PATH = data/gogs.db

[repository]
ROOT = /data/git/gogs-repositories
publish
[server]
DOMAIN           = 192.168.1.2 // 访问域名
HTTP_PORT       = 10080 // http端口
ROOT_URL         = http://192.168.1.2/ // 访问域名
DISABLE_SSH = false
SSH_PORT         = 10022 // SSH端口
START_SSH_SERVER = false
OFFLINE_MODE = false

[mailer]
ENABLED = false

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION   = true // 禁止注册,只能有管理员能加账号
ENABLE_CAPTCHA         = true
REQUIRE_SIGNIN_VIEW   = true // 默认跳转到登录页

[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false

[session]
PROVIDER = file

[log]
MODE = file
LEVEL = Info
ROOT_PATH = /app/gogs/log

[security]
INSTALL_LOCK = true
SECRET_KEY = security

到此为止,我们就完成了Gogs的所有安装

Drone

Drone安装

为什么?为什么要使用Drone还是因为习惯。因为在使用Gitlab的时候使用的CI/CD都是gitlab自带的gitlab ci;所以这里我们也需要一个CI/CD的工具于是我选择了Drone,当然市场上CI/CD的工具是比较多的

Drone安装这里我们参考官方文档

Gogs单机安装文档

Docker命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run \
-d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /volume1/docker/drone:/data \
-e DRONE_GIT_ALWAYS_AUTH=false \
-e DRONE_GOGS_SERVER=http://192.168.1.2:10080 \
-e DRONE_SERVER_HOST=http://192.168.1.2:10800 \
-e DRONE_DATABASE_DRIVER=mysql \
-e DRONE_DATABASE_DATASOURCE="root:password@tcp(192.168.1.2:3306)/drone?parseTime=true" \
-p 80:80 \
-p 443:443 \
--name=drone \
drone/drone:latest

这里贴别强调一下/var/run/docker.sock:/var/run/docker.sock的挂载是必不可少的,因为后面的DIND会用到,另外因为我使用了Mysql所以上面DRONE_DATABASE_DRIVER配置为mysql

接下来访问http://192.168.1.2:10800就会出现Drone登录界面,账号为Gogs管理员账号,这两个账号相通,而且也会自动同步Gogs项目

.drone.yml

在编辑.drone.yml之前我们需要在drone管理界面对项目设置

这里需要设置项目为受信任项目,如果Project settings未显示,则表示当前用户在Drone不是管理员可以更改数据库授权为管理员

1
UPDATE `users` SET `user_admin` = '1' WHERE `user_id` = '1';

接下来我们编写.drone.yml,对于.drone.yml编写我们以Spring Boot项目为例,首先我们需要编辑DockerFile
1
2
3
4
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/hello-1.0.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

接下来我们编辑.drone.yml,关于.drone.yml请参考.drone.yml文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kind: pipeline
name: default

steps:
- name: build
image: maven:3.5-jdk-8
commands:
- mvn package -B -Dmaven.test.skip=true # 打包跳过测试

- name: publish
image: docker:dind
volumes:
- name: docker
path: /var/run/docker.sock # dind挂载来自Drone容器/var/run/docker.sock
commands:
- docker login --username=* --password=* registry.cn-shenzhen.aliyuncs.com
- docker build -t spring-boot:master .
- docker tag spring-boot:master registry.cn-shenzhen.aliyuncs.com/new/spring-boot:master
- docker push registry.cn-shenzhen.aliyuncs.com/new/spring-boot:master

volumes:
- name: docker
host:
path: /var/run/docker.sock # 这里挂载Drone容器所在/var/run/docker.sock,当然Drone容器/var/run/docker.sock来自于群晖宿主机/var/run/docker.sock

通过上面我们定义了两步,build利用mavenSpring Boot进行了打包操作;publish利用dind将打包好的jar包通过DockerFile打包成镜像并推送到镜像仓库,这里说一下我使用的镜像仓库是阿里云

这里也请注意WebHook的地址为上面安装的Drone地址请注意填写正确

下面我们看一下Drone执行过程

到这里我们就告一段落了


以上就是群晖对接整个GogsDrone过程

最近在开发一个项目是用的eggjs同时又需要对接到微信公众平台,所以记录下自己Egg对接微信的过程

验证Token

我们知道在微信开发时都需在公众开发配置中对Token验证一次,接下来谈谈验证的步骤

第一步确定验证URL

比如我的是https://www.jakehu.me/wechat,那么先对eggjs路由改造

1
2
3
4
5
// app/router.js

module.exports = app => {
app.router.get('/wechat', app.controller.wechat.index);
};

改造完路由后我们还必须对安全这块进行设置,屏蔽对路由/wechatcsrf验证
1
2
3
4
5
6
7
// config/config.default.js

config.security = {
csrf: {
ignore: '/wechat',
},
};

第二步编写验证Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// app/controller/wechat.js

async index () {
const query = this.ctx.request.query;
const signature = query.signature;
const timestamp = query.timestamp;
const nonce = query.nonce;
const echostr = query.echostr;
   if (await this.check(timestamp, nonce, signature, 'token')) {
this.ctx.body = echostr;
} else {
this.ctx.body = 'It is not from weixin';
}
}

async check (timestamp, nonce, signature, token) {
const tmp = [ token, timestamp, nonce ].sort().join('');
const currSign = crypto.createHash('sha1').update(tmp).digest('hex');
return (currSign === signature);
}

然后就可以在开发者配置进行验证就好了

注:上面代码中的token即为你在开发者配置页面中填写的token

接入开发

第一步安装必要组件

这里我们用到了co-wechat插件

1
npm i co-wechat -s

安装后对插件进行配置
1
2
3
4
5
6
7
// config/config.default.js

config.wechat = {
token: 'token',
appid: 'appid',
encodingAESKey: 'encodingAESKey',
};

编写对接代码

首先是Controller的编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// app/controller/wechat.js

const wechat = require('co-wechat');
module.exports = app => {
class WechatController extends app.Controller { }

// 因为 Egg 需要用类的形式来组织,而 wechat 是通过 middleware 方法来生成中间件
WechatController.prototype.wechat = wechat({
token: 'token',
appid: 'appid',
encodingAESKey: 'encodingAESKey',
}).middleware(async (message, ctx) => {
console.log(message);
return { type: 'text', content: 'Hello world!' };
});

return WechatController;
};

其次我们对路由再进行改造
1
2
3
4
5
// app/router.js

module.exports = app => {
app.router.post('/wechat', app.controller.wechat.wechat);
};

到此就结束了,完美对接!!!


完美对接!!!

环境

公司的GIT环境一直是用Gitlab跑在阿里云的Docker环境中的,Gitlab的配置并没有做更改,然而今天发现突然报Forbidden而且还时好时坏。通过查看官方文档【Rack Attack】发现可能是项目太多并发太高触发了IP屏蔽

解决方案

根据官方的文档【Rack Attack】【IP whitelist】可有如下三种方法解决:

  1. 添加IP白名单
  2. 扩大每个IP HTTP authentication次数
  3. 直接关闭Rack Attack

实践

  1. 添加IP白名单

步骤:

  • vi /etc/gitlab/gitlab.rb
  • 查找rack_attack_git_basic_auth
  • gitlab_rails['rack_attack_git_basic_auth']取消注释
  • 修改ip_whitelist白名单将gitlab部署主机IP地址加入
    'ip_whitelist' => ["127.0.0.1","172.16.7.21"],
  • 最后执行gitlab-ctl reconfigure重载配置

在添加白名单后发现问题依然存在,于是在上述完成后继续第二种方式

  1. 扩大每个IP HTTP authentication次数

步骤:

  • maxretry调整为200

最后配置如下:

1
2
3
4
5
6
7
gitlab_rails['rack_attack_git_basic_auth'] = {
'enabled' => true,
'ip_whitelist' => ["127.0.0.1","172.16.7.21"],
'maxretry' => 200,
'findtime' => 60,
'bantime' => 3600
}

再次执行gitlab-ctl reconfigure重载配置

完美解决!!!

前记

最近在做微信开发本地测试,需要用到80端口;鉴于Eggjs默认端口为7001,于是开始了一场Eggjs绑定80端口之战

Scripts

scripts改造,将dev命令改为如下:

1
"dev": "egg-bin dev --port=80",

问题一

当运行npm run dev之后出现下面问题

1
bind EACCES null:80, code: EACCES

绑定80端口失败,看来是权限不够

解决方案:sudo高权限运行

问题二

当运行sudo npm run dev之后出现下面问题

1
sudo: npm:找不到命令

看来是bin下面没有可执行文件

解决方案:ln -s

1
2
3
4
5
6
7
$ which npm
> /home/jakehu/.nvm/versions/node/v8.12.0/bin/npm
$ sudo ln -s /home/jakehu/.nvm/versions/node/v8.12.0/bin/npm /usr/bin/npm

$ which node
> /home/jakehu/.nvm/versions/node/v8.12.0/bin/node
$ sudo ln -s /home/jakehu/.nvm/versions/node/v8.12.0/bin/node /usr/bin/node

最后只需要运行sudo npm run dev就可以了


如果出现bind EADDRINUSE null:80, code: EADDRINUSE错误,表示有程序占用80端口,pkill掉即可

虽然度娘是一个垮掉的搜索引擎,但是谁叫它在强国是垄断的存在呢。谈谈Hexo部署在Github Pages怎么提交Sitemap给百度。

Sitemap

因为Github Pages禁止百度爬虫所以这里我们不做过多的说明,无疑这种方式是行不通的

自动推送

目前在用的一种推送方式

1
自动推送是百度搜索资源平台为提高站点新增网页发现速度推出的工具,安装自动推送JS代码的网页,在页面被访问时,页面URL将立即被推送给百度

安装方式也很简单,只需要在页面中加入以下JS即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>

主动推送(实时)

我们重点来说说主动推送

首先我们这里需要安装一下生成sitemap的包

1
npm i hexo-generator-baidu-sitemap -s

新建文件push_sitemap_to_baidu.php,这里我们通过PHP来实现

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
<?php
// 解析xml
$file = "./public/baidusitemap.xml";
$xml = simplexml_load_file($file);
$urls = array();
foreach ($xml as $key => $value) {
$url = array();
$url = (array) $value->loc;
$urls[] = current($url);
}
// 调用百度API
$api = 'http://data.zz.baidu.com/urls?site=https://www.jakehu.me&token=***';
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
// 返回结果记录
$time = date("Y-m-d H:i:s");
$content = $time . " --- " . $result . PHP_EOL;
$file = "push_sitemap.log";
$fp = fopen($file, "a+") or die("fail to open the file");
fwrite($fp, $content);
fclose($fp);

最后会在根目录下生成push_sitemap.log日志文件

然后改造package.json如下

1
2
3
"scripts": {
"push": "hexo cl && hexo g && gulp && hexo d && php -f push_sitemap_to_baidu.php"
}

这条命令包含了清理生成压缩部署推送Sitemap,关于gulp压缩部分可看这里【点击查看】

最后我们可以直接运行命令进行部署和推送npm run push,或者将push改为start直接运行npm start即可