用docker搭建本地docker registry

Docker镜像构建以后,如果想存起来或者分享,一般都存放到dockerhub,或者临时存放到ttl.sh。但dockerhub是有容量限制的,因而自己搭建docker registry也是个不错的选择,而且使用起来也很简单(这归功于docker简单的tag机制,在tag中包含registry前缀即可方便push到不同的地方)。

Docker官方提供了registry的镜像,部署起来比较方便–只有ssl证书方面比较麻烦。

为了部署私有registry,大致上有这么几个要点:

  1. 准备好ssl签名(自签名)。
  2. 在宿主机选好配置文件、registry存储目录。部署稳定的registry:2镜像。
  3. 在客户端信任ssl根证书。

准备自签名SSL证书

生成根证书

先产生私钥文件:

1
2
mkdir root_ca
openssl ecparam -out root_ca/ROOT_CA_PRIVATEKEY.key -name secp384r1 -genkey

还可以选更加简单的 prime256v1 加密算法替换 secp384r1。

创建CSR:

1
openssl req -new -sha256 -key root_ca/ROOT_CA_PRIVATEKEY.key -out root_ca/ROOT_CA_CSR.csr -subj "/C=CN/ST=GD/L=GZ/OU=ALL/O=test/CN=test"

其中信息缩写:

  • CN - CommonName
  • L - LocalityName
  • ST - StateOrProvinceName
  • O - OrganizationName
  • OU - OrganizationalUnitName
  • C - CountryName

创建配置文件ROOT_CA.cnf

1
2
3
4
5
cat > root_ca/ROOT_CA.cnf
basicConstraints=critical,CA:TRUE
nsComment = "comment"
keyUsage=critical, keyCertSign
subjectKeyIdentifier=hash

创建根证书:

1
openssl x509 -req -sha256 -days 36500 -extfile root_ca/ROOT_CA.cnf -in root_ca/ROOT_CA_CSR.csr -signkey root_ca/ROOT_CA_PRIVATEKEY.key -out root_ca/ROOT_CA_CERT.crt

到此,所有文件为:

1
2
3
% ls root_ca 
ROOT_CA.cnf ROOT_CA_CSR.csr
ROOT_CA_CERT.crt ROOT_CA_PRIVATEKEY.key

用根证书颁发域名证书(假设域名为mysvr)

创建key和CSR

1
2
3
mkdir mysvr_certs
openssl ecparam -out mysvr_certs/mysvr.key -name prime256v1 -genkey
openssl req -new -subj "/C=CN/ST=GD/O=test/OU=LAN/CN=mysvr" -key mysvr_certs/mysvr.key -out mysvr_certs/mysvr.csr

创建ssl.cnf配置文件,用于颁发证书

1
2
3
4
5
6
7
8
9
10
cat > mysvr_certs/ssl.cnf
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1= mysvr.local
DNS.2= mysvr.lan
IP.1 = 192.168.0.121

通过CA为mysvr的CSR颁发证书mysvr.crt。

首次生成crt:

1
openssl x509 -req -CA root_ca/ROOT_CA_CERT.crt -CAkey root_ca/ROOT_CA_PRIVATEKEY.key -CAcreateserial -days 398 -sha256 -extfile mysvr_certs/ssl.cnf -in mysvr_certs/mysvr.csr -out mysvr_certs/mysvr.crt

首次生成crt会通过-CAcreateserial参数产生srl文件在root_ca/ROOT_CA_CERT.srl,以后再度颁发证书则用首次的srl即可:

1
2
cp root_ca/ROOT_CA_CERT.srl mysvr_certs/mysvr.srl
openssl x509 -req -CA root_ca/ROOT_CA_CERT.crt -CAkey root_ca/ROOT_CA_PRIVATEKEY.key -CAserial mysvr_certs/mysvr.srl -days 398 -sha256 -extfile mysvr_certs/ssl.cnf -in mysvr_certs/mysvr.csr -out mysvr_certs/mysvr.crt

验证证书是否可信:

1
openssl verify -CAfile root_ca/ROOT_CA_CERT.crt mysvr_certs/mysvr.crt

mysvr_certs/mysvr.crt: OK

如果以后要更新IP,则需要修改cnf,再重新颁发即可。

部署docker registry

我这里部署到群晖的nas上,其docker服务界面支持设置环境变量(命令行 -e)、端口(-p)、文件路径(-v),整体设置如下:

运行registry:2镜像,设置环境变量:

1
2
REGISTRY_HTTP_TLS_CERTIFICATE=/certs/mysrv.crt
REGISTRY_HTTP_TLS_KEY=/certs/mysrv.crt

上述路径为映射的路径。

设置路径映射:

1
2
3
docker/docker-registry/registry:/var/lib/registry
docker/docker-registry/config.yml:/etc/docker/registry/config.yml
docker/mysrv/certs:/certs

上传证书文件到宿主机的docker/mysrv/certs目录下。

设置端口:

1
4000:4000

在客户端信任证书(安装根证书)

macos下让浏览器信任证书

安装根证书,双击,添加到login items,然后到Keychain Access里面找到test证书,确认信息,然后选择always trust。

此时浏览器已经能信任该证书。对于docker,只要重启engine即可。

Linux下让docker信任证书

本质上是复制根证书到docker客户端的registry配置目录内,然后重启即可。

docker registry证书在 /etc/docker/certs.d/${domain}:${port}/ca.crt 目录。例如我们这里为:

1
2
cp root_ca/ROOT_CA_CERT.crt /etc/docker/certs.d/mysrv.local\:4000/ca.crt
sudo systemctl restart docker

在群晖的docker服务中添加我们自己的docker registry

主要两步:

1. 添加根证书到群晖系统

群晖的 /etc/ssl/certs/ca-certificates.crt 文件内存放了所有证书,这个文件是由 /usr/syno/bin/update-ca-certificates.sh 脚本根据 /var/db/ca-certificates 目录来维护的。

因而,要添加证书,则可以这样做:

1
2
3
sudo cp my_path_to_mysrv_root.crt /var/db/ca-certificates/mysrv_root.crt
sudo chmod 644 /var/db/ca-certificates/mysrv_root.crt
sudo update-ca-certificates.sh

这个证书还会被自动链接到这个位置:

1
2
3
4
$ ls -lh /etc/ssl/certs/`sudo openssl x509 -hash -noout -in /var/db/ca-certificates/mysrv_root.crt`*
lrwxrwxrwx 1 root root 13 Apr 8 22:41 /etc/ssl/certs/8528aafc.0 -> mysrv_root.pem
$ sudo ls -l /etc/ssl/certs/mysrv_root.pem
lrwxrwxrwx 1 root root 37 Apr 8 22:41 /etc/ssl/certs/mysrv_root.pem -> /var/db/ca-certificates/mysrv_root.crt

2. 添加根证书到群晖docker服务的配置目录

1
2
sudo mkdir -p /var/packages/Docker/etc/certs.d/mysrv.local:4000/
sudo my_path_to_mysrv_root.crt /var/packages/Docker/etc/certs.d/mysrv.local:4000/ca.crt

然后重启docker服务:

1
sudo systemctl restart pkgctl-Docker # 这个命令会比较久。

注意:使用.local域名的话,要注意主机上是否能解析(可以用ip)。

使用

支持,可以对镜像打tag并且push:

1
2
docker tag my/image mysrv.local:4000/my/image
docker push mysrv.local:4000/my/image

可通过url查询镜像:

1
https://mysrv.local:4000/v2/_catalog

通过hexo发布静态网页到nginx

环境

把hexo的静态文件部署到nginx,环境是ubuntu。

nginx

参考默认的站点,改成blog目录:

1
2
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-enabled/blog
sudo rm /etc/nginx/sites-enabled/default

修改其中的root为$HOME/blog。然后重启服务:

1
sudo service nginx restart

创建站点目录,使用www-data组。

1
sudo usermod -a -G www-data $myuser

此时重新登陆下用户,便于这个用户可以chgrp到www-data。

1
2
3
4
sudo mkdir /var/www/blog
sudo chown $myuser /var/www/blog
chgrp www-data /var/www/blog/
chmod g+rwxs blog

注意,不能放到$HOME下面,因为ubuntu的$HOME对其他用户是隐藏的。

创建仓库

用这个git仓库的post-hook来实现自动checkout,这样就能做到push到这个仓库即静态发布。

创建裸仓库目录:

1
2
3
mkdir $HOME/repos
cd $HOME/repos
git init --bare blog.git

设置post-hook:

1
2
3
cd $HOME/repos/blog.git/hooks
mv post-update.sample post-update
echo "git --work-tree=/www/var/blog --git-dir=$HOME/repos/blog.git checkout -f" >> post-update

注意,这个仓库是发布仓库,用于存放发布后的网页,而不是本blog的源码仓库。

安装hexo

在本地安装node.js,然后安装hexo,如果全局安装:

1
2
3
npm install hexo-cli -g
npm install hexo -g
npm install hexo-deployer-git -g

我使用局部安装。

对目录进行init。因为不是全局安装,所以用npx来调用当前目录的module。

1
2
3
4
5
mkdir $HOME/blog && cd $HOME/blog
npm install hexo-cli
npm install hexo
npm install hexo-deployer-git
npx hexo init

本地预览:
m

1
2
npx hexo s
# 可访问 http://localhost:4000/

blog目录用仓库管理:

1
2
3
git init
git add .
git commit -am "init"

默认 ignore了 本地json module:

1
2
3
4
5
6
7
8
✗ cat .gitignore 
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/%

从hexo默认页面也可以看到几个关键的操作(都有缩写):

1
2
3
4
$ hexo new "My New Post"
$ hexo server
$ hexo generate
$ hexo deploy

为deploy配置好部署到远程git的操作。

修改_config.yml当中的deploy配置:

1
2
3
4
deploy:
type: git
repo: $user@$server_ip:~/repos/blog.git
branch: master

部署:

1
2
✗ npx hexo d
INFO Deploy done: git

观察远程文件没生效,后来发现post-hook需要去掉exec:

1
#exec git update-server-info

成功。

关于git的权限配置

git仓库的权限就是ssh的权限,为了直接用key访问,把本地的pub key放到远程的 ~/.ssh/authorized_keys 里面即可。

关于备案号

方法一

因为theme是在module代码里面的,所以最好找一个已经支持的,比如Fluid,然后配置_config.yml里面的beian即可。

安装参考:

1
https://github.com/fluid-dev/hexo-theme-fluid

1
npm install --save hexo-theme-fluid

然后到主_config.yml里面指定:

1
2
theme: fluid
language: zh-CN

到主题的_config.yml里面设定:

1
2
3
4
5
6
7
8
9
10
11
12
# 国内大陆服务器的备案信息
# For Chinese mainland website policy, other areas keep disable
beian:
enable: true
# ICP证号
icp_text: 京ICP证123456号
# 公安备案号,不填则只显示ICP
police_text: 京公网安备12345678号
# 公安备案的编号,用于URL跳转查询
police_code: 12345678
# 公安备案的图片. 为空时不显示备案图片
police_icon: /img/police_beian.png

方法二

直接修改

1
./node_modules/hexo-theme-landscape/layout/_partial/footer.ejs

在里面加代码即可。

在Ubuntu部署gitlab

设置仓库

1
curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash

安装

1
sudo apt-get install gitlab-ce=14.7.5-ce.0

设置

Thank you for installing GitLab!
GitLab was unable to detect a valid hostname for your instance.
Please configure a URL for your GitLab instance by setting external_url
configuration in /etc/gitlab/gitlab.rb file.
Then, you can start your GitLab instance by running the following command:
sudo gitlab-ctl reconfigure

For a comprehensive list of configuration options please see the Omnibus GitLab readme
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md

Help us improve the installation experience, let us know how we did with a 1 minute survey:
https://gitlab.fra1.qualtrics.com/jfe/form/SV_6kVqZANThUQ1bZb?installation=omnibus&release=14-7

改gitlab的nginx端口

1
2
sudo vim /var/opt/gitlab/nginx/conf/gitlab-http.conf
sudo gitlab-ctl restart

注意修改端口后重新配置 /etc/gitlab/gitlab.rb。