分类 Linux学习 下的文章

最近一个项目使用Docker来部署的,但每次手动部署都需要先把代码拉取到本地,然后在执行命令删除原来的容器和镜像,最后再部署,非常繁琐,所以直接把这些命令放在一个Shell脚本内,实现一键部署,代码如下:

# 指定代码目录
codePath="/root/";
# 接收输入,形如:  xxx.sh projectName
project=$1;
if [ ! -n "$1" ] ;then
  projectName="projectName";
fi
cd $codePath$projectName
echo "git pull start" ;
# 拉取最新代码
git pull origin master
echo "git pull finish" ;

echo "Docker build start" ;
# 停止容器、删除容器、删除镜像
docker stop app
docker rm app
docker image rm app
docker build . -t app
echo "Docker build finish" ;

echo "Docker deploy start" ;
# 开始部署
docker run -d --name app --network host --restart=always -v ~/app.env:/app.env app
echo "Docker deploy finish" ;

自此一个半自动部署脚本完成,后续有时间再把脚本和Jenkins集成到一起,就可以实现定时或者提交后自动部署了。

背景

目前由于国内备案不支持 .im 域名,导致只能通过海外服务器中转+CDN加速的方式来达成访问,这样的情况下不管是CDN加速还是frp内网穿透,都会导致服务端无法直接获取到真实的IP地址。

思路

通过学习Typecho源码发现,在/var/Typecho/Request.php的 660 行左右,找到了setIp方法,这个方法主要是switch循环,先尝试从$this->getServer(__TYPECHO_IP_SOURCE__)中获取 IP,然后再尝试从$this->getServer('REMOTE_ADDR')中获取IP,而查看getServer相关的代码,发现基本功能就是获取$_SERVER内的相关变量。

解决

通过代码逻辑可以知道,这是官方提前预留出的获取IP地址的方式,显然也是最正确的做法,只要在配置文件提前定义好常量__TYPECHO_IP_SOURCE__的值,那么程序就会优先从这个对应$_SERVER的成员中获取值。
在配置文件/config.inc.php中添加:

/** 定义 IP 来源 */
define('__TYPECHO_IP_SOURCE__', 'HTTP_ALI_CDN_REAL_IP');

这时候后端就能获取到真是的IP地址了,统计工具插件也就可以工作了。

推荐一款Typecho类似于百度统计的本地统计插件Access,还是很好用的。

debian 配置网络和其他Linux类服务器不太一样,debian主要的配置都在 /etc/network/interfaces 文件内,可以配置每个网络接口的IP获取方式和网关地址,同时也是在这里面配置路由转发等。

目前的现状:

enp6s0 连接内网
enp11s0 连接外网

希望的状态:

所有内网的请求通过enp6s0 过来的都走 enp6s0 返回,所有服务器出口的访问和更新,都走 enp11s0 出去,需要在最底部添加一条路由,告诉服务器所有内网的请求走单独的网关(gw)和设备(dev)返回,以下是我的 interfaces文件内的配置:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# Primary
auto enp6s0
iface enp6s0 inet static
address 192.168.69.84
netmask 255.255.255.0

# Second
auto enp11s0
iface enp11s0 inet static
address 192.168.1.102
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 114.114.114.114 114.114.115.115
# 下面表示,所有 192.168 开头的内网请求都走内网的网关和设备返回
up route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.69.254 dev enp6s0

最近组内新购入了一台Mac mini,主要用来当打包机和服务器,考虑到原先的iMac性能不足,所以在采购之初,iOS组同事就将Mac mini的处理器配置到顶格,但无奈内存还是8G,一点点小遗憾,拿到这机器后,我们搁置了一周,后来商量决定还是直接上Docker,以免后续再换新机器又得一堆折腾的事情,所以由我来先折腾安装Docker和在上部署Android所需要的环境。

安装 Docker

macOS上最好用的安装方式还是Homebrew,如何安装Homebrew,参考我之前的博文《终端使用小技巧》

Homebrew 的 Cask 已经支持 Docker for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装:

$ brew cask install docker
//最后会显示安装成功 ↓↓↓↓
🍺  docker was successfully installed!

当然也可以手动下载,就和其他macOS软件一样,是个dmg文件,直接把小鲸鱼拖到Applications里面即可。

安装完以后,从应用中找到 Docker 图标并点击,运行之后,会在右上角菜单栏看到多了一个可爱的鲸鱼图标,这个图标表明了 Docker 的运行状态。

安装 gogs

既然安装好Docker,肯定是为了使用Docker Hub上的gogs镜像创建容器。

步骤

1、拉取gogs镜像

$ docker pull gogs/gogs

2、创建数据挂载目录并设置1000权限

$ sudo mkdir -p ~/Data/Gogs
$ sudo chown 1000 ~/Data/Gogs -R

3、使用run命令绑定端口和挂载目录映射

$ docker run --name gogs -d -p 22:22 -p 3000:3000 -v ~/Data/Gogs:/data gogs/gogs
备注:
--name 容器命名,不能与已存在的重名
-d 将容器跑到后台
-p 用来配置外置端口:内置端口映射关系
-v 用来配置外置目录:内置目录映射关系

4、配置自己的gogs

此处主要就是傻瓜化的页面参数配置,略

5、将配置好的容器打包成镜像

打包镜像比较简单,先找到容器的CONTAINER ID,然后根据CONTAINER ID将容器commit并取个新的镜像名。

//获取[CONTAINER ID]
$ docker ps
//打包成镜像
$ docker commit -m  ""   -a  ""   [CONTAINER ID]  [新镜像名]

以自定义镜像部署

上面提到了gogs的容器打包成自定义镜像,artifactory和jenkins的方式基本类似,我在本地已经全部打包成带-local的自定义镜像,下面的代码显示了如何轻松部署自定义镜像。

$ docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
jenkins-local                             latest              7e534022aff8        7 minutes ago       712MB
maven-local                               latest              f14f7278269b        8 minutes ago       1.03GB
gogs-local                                latest              6af3a7b9a547        About an hour ago   156MB
docker.bintray.io/jfrog/artifactory-oss   latest              b87d8f746026        6 days ago          907MB
gogs/gogs                                 latest              d5b9815c59e1        13 days ago         96.5MB
registry.docker-cn.com/jenkins/jenkins    lts                 806f56c84444        3 weeks ago         703MB
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                        NAMES
03805c16bd1d        e945e5b0afdb        "/entrypoint-artifac…"   2 hours ago         Up 2 hours          0.0.0.0:8081->8081/tcp                       artifactory
d83c9d67e9ec        gogs/gogs           "/app/gogs/docker/st…"   9 hours ago         Up 3 hours          0.0.0.0:22->22/tcp, 0.0.0.0:3000->3000/tcp   gogs
$ docker run --name jenkins -d -p 8080:8080 -p 50000:50000 -v /Users/sungrow/Data/Jenkins:/var/jenkins_home jenkins-local
846200d6f0a184c7f96b94bb9d92d548c5b6e2993dedf60cf9bb36957d733507
$ docker run --name maven -d -p 8081:8081 -v /Users/sungrow/Data/Artifactory:/var/opt/jfrog/artifactory maven-local
1e00e1a243a2119b4ae399e05fe63fa5b7bed1f97299a71c63c7afcdbd26d7bf
$ docker run --name gogs -d -p 22:22 -p 3000:3000 -v /Users/sungrow/Data/Gogs:/data gogs-local
71eeffa65a574b64258cacdfa9948c8c51022fe28af80ed2b5e8b6ecabf63548

时区问题

Docker时区使用的是默认的UTC时间,与我们机器的时间不一致,所以需要对容器内的时间进行同步

//获取[CONTAINER ID]
$ docker ps
//复制宿主时区
$ docker cp /etc/localtime [CONTAINER ID或者CONTAINER NAME]:/etc/localtime

Jenkins由于使用的是openjdk,还需要额外设置下,打开【系统管理】->【脚本命令行】运行下面的命令:

System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')

在之前的博客树莓派安装frp实现内网穿透,记录了如何搭建frp服务端和如何在树莓派上搭建frp客户端,接着上次的博客,这次我又在我的MacBook Pro上折腾起来了。

下载frpc

Mac因为有UI界面,可以直接鼠标操作,省去敲命令行的繁琐,先去 https://github.com/fatedier/frp/releases 下载最新版本的frpc,特别注意下,Mac用的版本是darwin_amd64结尾的,下载完成后,解压到本地的指定目录,例如我解压到 /usr/local/bin/frpc 目录。

配置开机自启动

解压完成以后为了保证每次开机都能自定启动,需要我们配置frpc.plist文件,并加入到 ~/Library/LaunchAgents/ 这个文件中。

frpc.plist文件内容:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>frpc</string>
    <key>ProgramArguments</key>
    <array>
    <string>/usr/local/bin/frpc</string>
    <string>-c</string>
    <string>/etc/frpc.ini</string>
    </array>
  </dict>
</plist>

最后需要加载生效


 sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist