记新windows电脑打造前端开发环境流程

系统环境

  • 查看电脑配置(主要是CPU内存硬盘SSD这些),对于该配置能完成什么样的开发强度心里有数
  • 联网,设置固定IP(较推荐)
  • 清理已安装工具,取消不常用的任务栏(比如IE浏览器,应用商店)
  • 规划分区,明确每个分区盘的用处

工具下载

下载以下常用工具并安装

  • 7z
  • Chrome
  • VSCode
  • python
  • Git(VSCode安装后再安装),SourceTree(图形化Git管理),BeyondCompare(Diff对比工具)
  • NodeJs
  • yarn
  • Everything
  • Wox(Everything和python安装后再安装)
  • Cmder
  • Office工具
  • MacType(美化windows字体显示)
  • 迅雷极速版/FDM
  • IM工具 QQ 微信 钉钉
  • VirtualBox
  • 其它工具 坚果云 Zerotier-One
  • 从坚果云的同步文件中安装ssr并添加订阅地址

Chrome

前端开发浏览器是重头,所以要配置好浏览器的一些东西

  • ssr运行后登录chrome同步扩展程序,确保常用的vue-devtool Proxy SwitchSharp NIM(NodeJs调试管理工具) 划词翻译扩展已安装
  • 登录后等待同步书签
  • Proxy SwitchSharp导入坚果云同步的备份文件,并点击扩展图标选择自动模式,至此FQ已完成,后续可以科学上网
  • 设置 -> 下载内容 -> 下载前询问每个文件的保存位置 勾选上

Cmder

windows下如果要获得流畅的命令行使用体验,Cmder那是必备的工具,后续的命令行操作也是使用该工具执行,安装后需要做一些简单的设置,参考

  • 注册右键菜单 管理员身份打开cmd并cd到Cmder目录,执行Cmder.exe /REGISTER ALL
  • 设置启动目录 Settings -> Startup - > Task,修改{cmd::Cmder}项,把:
    cmd /k "%ConEmuDir%\..\init.bat"改为cmd /k "%ConEmuDir%\..\init.bat" -new_console:d:G:\workspace
  • 设置alias 打开Cmder安装目录下的config/user-aliases.cmd文件,添加常用的简写命令,比如

    1
    gc = git commit -am $1
  • 设置常用快捷键 在Settings -> Keys & Macro页面中搜索split,为split bottom设置快捷键Ctrl+Shift+D为split right设置快捷键Ctrl+D,保持和iTerm2一致。设置Minimize/Restore (Quake-style hotkey also)的快捷键为Ctrl+F1,这个可以用来快速显隐窗口。

Git

Git现在几乎成了主流的版本控制工具,在开发之前我们需要先对Git做个简单的配置

  • 配置Git

    1
    2
    git config --global user.name "erguotou"
    git config --global user.email erguotou525@gmail.com
  • 生成本地公私钥

    1
    2
    ssh-keygen -t rsa
    cat ~/.ssh/id_rsa.pub

    将生成的公钥复制到Github/Gitlab之类的仓库中。

  • 修改文件默认结尾格式
    1
    2
    git config core.eol lf
    git config core.autocrlf false

VSCode

目前来看最火的编辑器,速度比Atom快很多,使用前先安装几个常用的插件

  • EditorConfig for VS Code
  • ESLint
  • HTML Snippets
  • language-stylus
  • Path Intellisense
  • Prettier
  • Vetur

然后修改创建文件的默认结尾为LF,在用户配置中加入"files.eol": "\n"

NodeJs

前端开发必备,主要是换源,安装常用全局模块

1
2
3
npm i -g nrm http-server
nrm use taobao
yarn config set registry 'https://registry.npm.taobao.org'

Everything & Wox

类似Mac上的Alfred,配置简单,主要是改下快捷键为Ctrl+~

高级玩法

  • AutoHotKey AHK为windows用户提供了更多的可能,开发时可以用它定义快捷输入、执行自动化操作,可以定义开机自启动脚本,显隐应用窗口等等
  • MacType Windows的ClearType字体很多时候看着都很难受,这时我们需要MacType来优化字体显示,可以参考这个做个自定义优化或者直接使用Candy改的MacType
分享到

基于Rancher搭建k8s的集群环境

本文主要纪录了在k8s的学习过程中我是如何搭建k8s集群环境的经历。
在学习和了解了k8s的一些基础概念我开始尝试去自己搭建一套集群环境,经过一段时间的尝试,我决定使用rancher来帮助搭建环境,并使用rancher os作为主机镜像。
你要问我为什么使用rancher搭建?因为简单啊!为什么使用rancher os作为主机镜像?因为小啊!

环境准备

  • 官网下载好rancheros.iso文件
  • 4台虚拟机或者主机,根据实际业务场景增加或减少,机器用途如下:
    | Hostname | IP | Role | Configuration |
    | :————: | :————-: | :————: | :———–: |
    | rancher-server | 192.168.103.90 | rancher server | 1C1G8G |
    | k8s-node1 | 192.168.103.101 | k8s node | 2C2G20G |
    | k8s-node2 | 192.168.103.102 | k8s node | 2C2G20G |
    | k8s-node3 | 192.168.103.103 | k8s node | 2C2G20G |
  • 确认本机已生成ssh密钥对,然后在本机生成cloud-config.yml,用于ssh连接到node节点:

    1
    echo -e "#cloud-config\nhostname: rancher-server\nssh_authorized_keys:\n - $(cat .ssh/id_rsa.pub)" > $HOME/cloud-config.yml

    如果虚拟机网络没有dhcp,还需要在cloud-config.yml中加入network相关的配置

    1
    echo -e "#cloud-config\nhostname: rancher-server\nrancher:\n  network:\n    interfaces:\n      eth0:\n        address: 192.168.103.90/24\n        gateway: 192.168.103.1\n        mtu: 1500\n        dhcp: false\nssh_authorized_keys:\n  - $(cat .ssh/id_rsa.pub)" > $HOME/cloud-config.yml

    PS:一定要保证hostname唯一,我之前就被坑了

安装Rancher OS系统

  • rancher-server虚机上选择iso镜像,启动虚机,进入系统后启动的是类似Live CD的系统,所以我们需要先安装rancheros到硬盘,否则下次重启后数据都将丢失
  • 使用命令ip addr查看网卡是否被分配ip,如果没有请参考官网介绍配置静态ip

    1
    2
    3
    4
    sudo ros config set rancher.network.interfaces.eth0.address 192.168.103.90/24
    sudo ros config set rancher.network.interfaces.eth0.gateway 192.168.103.1
    sudo ros config set rancher.network.interfaces.eth0.mtu 1500
    sudo ros config set rancher.network.interfaces.eth0.dhcp false

    设置完成后执行sudo system-docker restart network使其生效

  • 给虚机设置password:sudo passwd rancher
  • 将本机的cloud-config.yml文件复制到虚机上:scp $HOME/cloud-config.yml rancher@172.68.1.100:/home/rancher/cloud-config.yml,如果本机可以通过ssh登录那么反向的从虚机上执行scp命令也可以
  • 在虚机上执行安装:sudo ros install -d /dev/sda -c cloud-config.yml,完成后重启虚机
  • 注意:如果使用ros命令设置的网络ip和cloud-config.yml配置的ip是一致的,那么在虚机装好系统后本机将无法ssh连上,因为本机已经存储了该ip对应的公钥,所以需要删除~/.ssh/known_hosts文件中该ip所在行
  • 重新ssh连到虚机,切换虚机docker版本,参考切换到支持的版本号,切换命令:sudo ros engine switch docker-17.03.2-ce
  • 重复之前的操作,注意在安装之前要先修改cloud-config.yml文件中的ip地址以及hostname,这样我们就可以得到3台node节点。PS:之前试过克隆虚机的方式,但打开克隆的机器无法登陆,所以还是选择重复执行的方式。

Docker加速

在所有的虚机上执行sudo vi /etc/docker/daemon.json并填入下面内容

1
2
3
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

保存后执行sudo system-docker restart docker然后执行docker info查看是否成功设置docker源

安装Rancher server

rancher-server虚机上执行

1
sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:stable

等待一段时间后在本地打开浏览器访问http://<rancher-server-ip>:8080即可访问Rancher UI。
在web页面中的操作就不做详细介绍,大致就是添加环境,然后按照页面提示添加我们的3台k8s node主机,然后等待各种服务安装完成即可,点击查看官方视频介绍(需翻墙)
PS:参考文章中kubernetes环境管理一节修改国内加速。

分享到

记录在开发electron-ssr过程中遇到的问题

首先是项目介绍,其实这个项目就是给shadowsocksr-python项目加一个GUI壳,所以它的功能就是为了FQ。GitHub地址在这

其次,本文这里只记录这此在2017年底开始的重构经历,因为之前的代码写得实在比较乱(我一开始只是打算练习用的。。。)。OK,话不多说,下面进入正题。

脚手架

我们在开发一个完整的功能的时候往往不是从零开始做(因为那太费时间和经历了,还得自己维护项目框架),这里我是从electron-vue项目初始化而来的。为什么用这个框架?跨平台用electron,前端开发用vue配合webpack,所以就选择了这个框架咯。

开发前的约定

之前其它分支的代码乱就是因为在开发之前没有做一个好的规划,然后就是哪用到什么就直接写,不方便后期维护和代码阅读。这次在开发之前做了几个简单的约定:

  • ipc通讯的channel要约定清楚,并且用常量定义,详见https://github.com/erguotou520/electron-ssr/blob/redesign/docs/EVENT_LIST.md
  • 主进程代码在src/main目录维护,渲染进程代码在src/renderer目录维护,两者通用代码在src/shared目录维护,第三方库在src/lib目录维护
  • 主进程和渲染进程都使用数据驱动开发的方式开发,渲染进程使用vue开发,主进程使用rxjs开发,2个进程间使用ipc进行数据变更通知和更新
  • 主进程和渲染进程代码统一使用ES6语法编写

项目目录结构

有了开发约定好就开始撸码,有些代码是从之前的分支中复制过来稍作改变便可,而大部分则是全新编写。src目录的大致结构如下:

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
src
├─lib
│ ├─proxy_conf_helper # mac os上用于设置系统代理模式的helper
│ └─sysproxy.exe # windows上用于设置系统代理模式的helper
├─main # main进程
│ ├─bootstrap.js # 项目启动,初始化操作
│ ├─client.js # shadowsocksr-python命令执行和终止
│ ├─data.js # main进程的中央数据文件
│ ├─index.dev.js # 开发环境的入口文件
│ ├─index.js # 入口文件
│ ├─ipc.js # 负责ipc通讯
│ ├─logger.js # 日志
│ ├─pac.js # 负责pac文件下载和提供pac地址
│ ├─proxy.js # 设置系统代理模式
│ ├─tray-handler.js # 任务栏操作方法
│ ├─tray.js # 任务栏
│ └─window.js # 页面窗口
├─renderer # renderer进程
│ ├─assets # 页面资源
│ ├─components # vue组件
│ ├─qrcode # 二维码识别
│ ├─store # renderer进程的中央数据
│ ├─views # 页面
│ ├─ipc.js # 负责ipc通讯
│ ├─constants.js # 常量定义
│ └─main.js # 前端入口文件
└─shared # main和renderer共享文件夹
├─config.js # 应用配置相关
├─env.js # 应用环境相关
├─events.js # ipc交互事件定义集合
├─ssr.js # SSR配置对象
└─utils.js # 工具集

renderer进程开发技术点

  • 页面开发中用到了vue vuexiview组件库,其中iview稍微做了些修改。
  • vuex作为前端数据中心,维护了很多页面数据,页面的修改都是维护vuexstate
  • 鉴于页面内容不是特别多就没有使用vue-router,而是使用简单的component配置is属性做页面切换。
  • 整个页面开发中最饶人的是我把扁平的configs数组变成了按分组显示的树形结构,导致整个交互变得极其复杂,最后在绕来绕去饶了好几次后还是使用数据驱动开发的思维解决。

main进程开发技术点

  • 由于main进程使用rxjs作为数据维护中心,而我又是第一次使用rxjs,所以在初期就遇到了不少问题。比如多处文件可能会触发(ipc和tray都会触发)数据变更,应该怎么去编写和改变Observable数据,比如支持多播以及和renderer进程保持同步。最后还是在data.js中统一初始化和改变数据(对外暴露可改变数据的方法)并提供多播能力,其它文件在使用时直接subscribe关注,在变更时使用data.js暴露的入口进行数据变更。这样在开发时数据的维护会更方便,而且可以保持每个文件尽量只关注自己的业务。
  • main进程最复杂的应该是设置系统代理功能。由于每个系统的调用方法不一致,所以要收集所有系统的实现方式,可以参考https://github.com/erguotou520/electron-ssr/blob/redesign/docs/AUTO_PROXY.md的收集结果(Linux系统中非gnome桌面如何实现还没有找到方法,如果你知道,欢迎提issue告知)。

    理论知道了只是第一步,实现是第二步。开开心心地用child_process.exec执行命令,开发时一切正常,happy。然而到了打包的时候懵逼了,没有可执行文件了。OK,我放到static目录下,还是不行,因为这些文件还是在asar压缩包里,没法复制和执行。最后在electron-builder中找到了extraFiles字段,就是用来将文件复制到项目根目录下的(如何找到项目根目录也是个坑,得使用app.getPaht(‘exe’)来实现`)。

    目前还有一个问题也是mac上实现最大的问题。mac上使用networksetup设置需要sudo权限,而如何实现只弹框输入一次管理员密码就可以一直修改系统代理模式才是最大的难题。一开始使用networksetup命令实现时每次切换都需要输入密码,很烦。后来参考shadowsocks-NG项目,直接将它生成的proxy_conf_helper文件复制到项目里使用,但目前在打包后还是会闪退,目前仍在查找实现方案。然后使用sudo-prompt模块执行sudo命令将其拷贝到指定位置并赋权。

    在打包到0.2.0-beta-1版本之前一直使用正常,忽然有人跟我说10.9.5版本的mac闪退,远程调试后才发现原来shadowsocks-NGproxy_conf_helper不支持10.11以下版本,尴尬。目前最简单的方法就是检查mac版本,然后低于10.11版本的直接屏蔽切换代理的功能,当然有没有更优雅的实现方式还是有待继续思考的。

  • 还有个有意思的问题是在0.2.0-alpha-4版本时提的issue。后来我重新查看了下NodeJs文档,发现确实用execFile更佳,因为它不是在shell中执行,避免了命令被特殊字符(比如&|"'等等)干扰的问题,这个问题倒是也让我学到了些开发经验。
  • 一开始在开发PAC功能时考虑的是这个版本先按简单的来,满足最基本的pac功能即可,而且自己一般都是用chrome插件来选择性的FQ,所以开发完也没太测试。然后打版发布后有用户提BUG说PAC功能用不了,然后自己本地试了下啊,确实用不了(之前蜜汁自信了)。然后找原因啊,还求助了别人啊,愣是没发现哪里的错。一个偶然的情况下重新看到PAC原理才想起来我返回的pac内容里面根本没有指定socks地址和端口啊!后来想了想,因为ssr是要用一些特殊字段做标记然后使用运行时的变量来替换特殊字段的(简单的说就是pac.replace(/__PROXY__/g, 'socks5 127.0.0.1:1080')),这才明白错在哪,原来真相竟然就是这么简单,害我一开始还在那研究http服务器的问题。

其它的坑

  • 配置向下兼容。如果再后期维护时添加了新的系统配置项,需要在系统初始化时复制到应用配置对象中并保存。
  • 异常处理。错误文件?端口占用?
  • 在更新订阅服务器时,同时使用window.fetchelectron.net.request来请求数据,并使用Promise.race来选择最快完成的数据。
  • mac系统打包后默认不能复制粘贴,需要添加Menu菜单和常见的一些菜单项来修复该问题。

最后

如果你喜欢这个项目,欢迎来star。如果你觉得这个项目对你有帮助,欢迎来打赏

分享到

工作中遇到的cookie知识整理

本文主要记录在工作中遇到的cookie知识的一些整理,这些零散的细节的知识点在没遇到的时候是模棱两可,遇到的时候又不是很深入地了解,所以还要查资料,写demo来反复验证。所以这里把这次关于cookie的知识记录下以便后续查看。

在介绍结果之前先阐述个基本知识:同源,即相同协议、相同域名、相同端口。浏览器对于跨域访问有一些限制,但是对于cookie的限制稍微有些不同。

在实验中我们不讨论设置cookiedomain,只考虑设置path字段,有如下结论:

  • 同源情况下共享cookie,没毛病
  • 不同协议、同域名、同端口在不设置path或使用默认的path=/的情况下是共享cookie的,注意这里的默认path/,此时http和https是可以共享的
  • 同协议、同域名、不同端口在不设置path或使用默认的path=/的情况下是共享cookie的,此时跨端口是可以共享的
  • 不同协议、同域名、不同端口在不设置path或使用默认的path=/的情况下是共享cookie的,此时跨端口是可以共享的
  • 同协议、同域名、同端口、不同子目录的情况下在不设置path或使用默认的path=/的情况下是共享cookie的,即http://xxx.xx:port/abchttp://xxx.xx:port/def是共享cookie
  • 同协议、同域名、同端口、不同子目录的情况下在设置path为子目录的情况下不同的子目录是不共享cookie的,即path=/abchttp://xxx.xx:port/abchttp://xxx.xx:port/def不共享
  • 同协议、同域名、不同端口、不同子目录的情况下在不设置path或使用默认的path=/的情况下是共享cookie的,即http://xxx.xx:port1/abchttp://xxx.xx:port2/def是共享cookie
  • 同协议、不同二级域名在不修改domain的情况下是不共享cookie的,即https://super.domain.comhttps://sub.domain.com是不共享cookie

因此可以得出:

不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名(sub-domains)来访问cookie。
但跨二级域名是不共享cookie的。

测试文件

测试参考

相关文章

分享到

利用dokku打造自己的私有云仓库和自动化部署

dokku是什么?一句话概括就是一个几百行shell代码的高可扩展性的类Heroku的单服务器PAAS平台,利用它可以简化很多docker操作,更加方便我们维护一个docker driven的平台。

  1. 创建机器,选择Ubuntu系统,同时做好域名映射
  2. 安装dokku

    1
    2
    3
    # 选择0.9.4版本,后面的版本都有些问题
    wget https://raw.githubusercontent.com/dokku/dokku/v0.9.4/bootstrap.sh
    sudo DOKKU_TAG=v0.9.4 bash bootstrap.sh

    然后打开对应的域名,完成dokku的初始化

  3. 创建gogs应用,参照https://dokku.github.io/tutorials/deploying-gogs-to-dokku
    其中推送代码部分可以用tag部署方式,所有命令如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    dokku apps:create gogs
    dokku proxy:ports-add gogs http:80:3000
    dokku docker-options:add gogs deploy -p 2222:22
    mkdir -p /var/lib/dokku/data/storage/gogs
    chown -R dokku:dokku /var/lib/dokku/data/storage/gogs
    dokku storage:mount gogs /var/lib/dokku/data/storage/gogs:/data
    dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql
    dokku mysql:create gogs
    dokku mysql:link gogs gogs
    # 使用指定版本
    docker pull gogs/gogs:0.11.4
    docker tag gogs/gogs:0.11.4 dokku/gogs:0.11.4
    dokku tags:deploy gogs 0.11.4
  4. 使用Let’s Encrypt进行https加密

    1
    2
    3
    4
    sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
    dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=erguotou525@gmail.com
    dokku letsencrypt gogs
    dokku letsencrypt:cron-job --add

    完成之后打开web页面完成gogsinstall,注意配置页面的各设置(mysql的配置地址可以用dokku mysql:info gogs查看。即使设置错了,也可以后期使用dokku enter gogs,在/data/gogs/conf/app.ini中直接修改)。

  5. 创建drone应用,droneserver端和agent

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # server
    dokku apps:create drone
    dokku mysql:create drone
    dokku mysql:link drone drone
    # 暂时不能使用最新版本,坑了很久
    # docker pull drone/drone:latest
    docker pull drone/drone:0.7.3
    docker tag drone/drone:0.7.3 dokku/drone:0.7.3
    # 配置drone的环境变量
    dokku config:set drone DRONE_OPEN=false DRONE_GOGS_PRIVATE_MODE=true DRONE_DATABASE_DRIVER=mysql DRONE_DATABASE_DATASOURCE='root:password@tcp(1.2.3.4:3306)/drone?parseTime=true' DRONE_HOST=https://drone.erguotou.me DRONE_GOGS=true DRONE_GOGS_URL=https://gogs.erguotou.me DRONE_SECRET=secret DRONE_ADMIN=username,password
    dokku tags:deploy drone 0.7.3
    dokku proxy:ports-add drone http:80:8000
    dokku proxy:ports-remove drone http:443:443 http:8000:8000 http:80:80
    dokku letsencrypt drone
    # agent,暂时不能使用最新版,直接使用docker命令启动,看最新版源码里/ws/broker请求都没有了
    # dokku apps:create drone-agent
    # docker pull drone/agent:latest
    # docker tag drone/agent:latest dokku/drone-agent:latest
    docker run -d -e DRONE_SERVER=wss://drone.erguotou.me/ws/broker -e DRONE_SECRET=password -e DRONE_TIMEOUT=15m -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name=drone-agent-docker drone/drone:0.7.3 agent
    # 配置agent的环境变量
    # dokku config:set drone-agent DRONE_SERVER=wss://drone.erguotou.me/ws/broker DRONE_SECRET=secret
    # dokku storage:mount drone-agent /var/run/docker.sock:/var/run/docker.sock
    # dokku tags:deploy drone-agent latest
  6. 检查应用运行情况
    可使用的命令

    1
    2
    3
    4
    5
    6
    dokku proxy:report app
    dokku proxy:ports-remove app http:80:3000
    dokku proxy:ports-add app http:80:3000
    cat /home/dokku/app/nginx.conf
    dokku ps:stop app
    dokku ps:start app
  7. 创建自己的应用
    dokku中创建对应的app dokku apps:create gift,完成域名映射,配置proxy:ports,使用Let's encrypt插件进行https加密,这些步骤就不多说了。接着在gogs中创建对应的一个仓库,记得项目根目录下要有一个.drone.yml文件(参考http://docs.drone.io/getting-started/进行配置),然后提交代码。

  8. 自动发布应用
    上一步只能使用drone进行自动构建,要想将构建后的项目自动打包发布,还需要一些额外的操作(这里也是坑了自己好久,主要难题是如何将drone agent生成的文件发布到dokku git里,后来经人提醒可以通过共享ssh的方式,然后后续的共享ssh的操作也是摸索了好久才成功,可谓一路心酸)。

    • 找1台虚机生成一份新的ssh公私钥对(也可以本地备份原来的,然后重新生成)

      1
      ssh-keygen -t rsa -C "dokku-deploy"
    • 将上一步生成的id_rsa.pub上传至服务器并添加到dokku中

      1
      2
      3
      4
      # local
      scp ~/.ssh/id_rsa.pub root@erguotou.me:/root/deploy.pub
      # server
      dokku ssh-keys:add deploy ./deploy.pub
    • 项目根目录新建一个ssh目录,然后将上一步生成的ssh公私钥复制进去

      1
      cp ~/.ssh/id_rsa* ./ssh
    • 修改原来的.drone.yml,在原来build之后添加一些操作

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      - rm -rf ~/.ssh
      - mkdir -p ~/.ssh
      - cp ssh/* ~/.ssh
      - chmod 600 ~/.ssh/id_rsa # 特别要注意这3行
      - chmod 644 ~/.ssh/id_rsa.pub
      - ssh-keyscan erguotou.me >> ~/.ssh/known_hosts
      - ssh-keyscan 45.77.42.201 >> ~/.ssh/known_hosts
      - echo 'FROM ilyasemenov/dokku-static-site' > dist/Dockerfile # 根据自己的项目选择合适的Dockerfile或者实现适合自己项目的Dockerfile,也可以使用buildpacks
      - cd dist
      - git config --global user.email "erguotou525@gmail.com"
      - git config --global user.name "erguotou"
      - git init
      - git add ./ -A
      - git commit -m "auto build"
      - git remote add dokku dokku@erguotou.me:gift
      - git push -u dokku master --force

      至此就完成了自动化部署的工作,现在就可以访问https://gift.erguotou.me了。

分享到

CI简介和实际应用

什么是CI

CI
引用知乎上的一个回答

作者:赵劼
链接:https://www.zhihu.com/question/23444990/answer/26995938
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

集成是指软件个人研发的部分向软件整体部分交付,以便尽早发现个人开发部分的问题;部署是代码尽快向可运行的开发/测试节交付,以便尽早测试;
交付是指研发尽快向客户交付,以便尽早发现生产环境中存在的问题。
如果说等到所有东西都完成了才向下个环节交付,导致所有的问题只能再最后才爆发出来,解决成本巨大甚至无法解决。
而所谓的持续,就是说每完成一个完整的部分,就向下个环节交付,发现问题可以马上调整。是的问题不会放大到其他部分和后面的环节。

这种做法的核心思想在于:既然事实上难以做到事先完全了解完整的、正确的需求,那么就干脆一小块一小块的做,并且加快交付的速度和频率,使得交付物尽早在下个环节得到验证。早发现问题早返工。

举个例子,你家装修厨房,其中一项是铺地砖,边角地砖要切割大小。如果一次全切割完再铺上去,发现尺寸有误的话浪费和返工时间就大了,不如切一块铺一块。这就是持续集成。
装修厨房有很多部分,每个部分都有检测手段,如地砖铺完了要测试漏水与否,线路铺完了要通电测试电路通顺,水管装好了也要测试冷水热水。如果全部装完了再测,出现问题可能会互相影响,比如电路不行可能要把地砖给挖开……。那么每完成一部分就测试,这是持续部署。

全部装修完了,你去验收,发现地砖颜色不合意,水池太小,灶台位置不对,返工吗?所以不如没完成一部分,你就去用一下试用验收,这就是持续交付。

补充:从敏捷思想中提出的这三个观点,还强调一件事:通过技术手段自动化这三个工作。加快交付速度。

还有些细节可以参考阮一峰的文章

常用的持续集成工具

  • Travis CI 针对开源项目免费,私有项目收费
  • AppVeyou 主要是windows平台的持续集成
  • Gitlab CI 私有仓库Gitlab自带的CI
  • Jenkins 同样的开源产品,适合私有仓库使用,但是需要jre环境来部署

项目实践

  • vue-fullstack
    该项目为一个vue全栈项目模板,项目中使用travis做持续集成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    language: node_js
    node_js:
    - "6"
    before_install:
    - git config --global push.default matching
    - git config --global user.name "erguotou"
    - git config --global user.email "erguotou525@gmail.com"
    install:
    - npm install -g vue-cli
    - npm install
    - node test/index.js
    script:
    - cd ../test-fullstack
    - npm install
    - npm run lint
    - npm run build
    cache:
    directories:
    - node_modules
    - ../test-fullstack/node_modules
    - $(npm config get prefix)/vue-cli

    该配置文件中主要就做了一件事,根据当前模板生成一个项目文件并执行代码检查和构建操作,以此来简单地验证模板生成的正确性。
    TODO:最好可以添加一个文件结构验证的代码,另外后续会根据生成后的项目自动push到github的其它分支中,并通过heroku实现自动部署

  • electron-ssr 该项目是ShadowsocksR的一个多平台pc客户端,该项目同时使用了travisappveyor用来构建不同平台上的安装包文件,简单的看下配置文件

    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
    # travis
    osx_image: xcode7.3

    sudo: required
    dist: trusty

    language: c

    matrix:
    include:
    - os: osx
    - os: linux
    env: CC=clang CXX=clang++ npm_config_clang=1
    compiler: clang

    addons:
    apt:
    sources:
    - ubuntu-toolchain-r-test
    packages:
    - icnsutils
    - graphicsmagick
    - xz-utils
    - rpm

    cache:
    directories:
    - node_modules
    - app/node_modules
    - $HOME/.electron
    - $HOME/.cache

    before_install:
    - mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v1.2.1/git-lfs-$([ "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-1.2.1.tar.gz | tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull

    install:
    - nvm install 6
    - npm install electron-builder
    - npm install
    - npm prune

    script:
    - npm run build

    branches:
    only:
    - master
    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: 1.0.{build}

    platform:
    - x64

    cache:
    - node_modules
    - app\node_modules
    - '%APPDATA%\npm-cache'
    - '%USERPROFILE%\.electron'

    branches:
    only:
    - master

    init:
    - git config --global core.autocrlf input

    install:
    - ps: Install-Product node 6 x64
    - git reset --hard HEAD
    - npm install npm -g
    - npm install electron-builder
    - npm install
    - npm prune

    build_script:
    - node --version
    - npm --version
    - npm run build

    我们可以看到在travis中同时定义了Linux和Mac的构建任务,在appveyor中定义了Windows平台的构建任务。任务的大致流程都是根据当前的系统环境构建当前系统的安装包(打包App的任务由构建工具提供),然后自动发布到Gihub Release中,这样就实现了代码push->打包构建(全平台)->发布的完整过程,免去很多手动操作以及对系统环境的要求。

  • vio-frontend T2Cloud的VIO产品前端代码,集成Gitlab CI实现自动编译并发布到poc环境,配置文件如下:
    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
    stages:
    - install_deps
    - lint
    # - test
    - build
    - deploy_poc
    # 安装依赖
    install_deps:
    stage: install_deps
    script:
    - npm install --registry=https://registry.npm.taobao.org
    lint:
    stage: lint
    script:
    - npm run lint
    # 运行测试用例
    # test:
    # stage: test
    # only:
    # - develop
    # - master
    # script:
    # - npm run test
    # 编译
    build:
    stage: build
    only:
    - develop
    - master
    script:
    - npm run build
    # 部署测试服务器
    deploy_test:
    stage: deploy_poc
    only:
    - develop
    script:
    - npm run deploy

总结

简单的说,持续集成帮助我们开发人员免去很重复的手工操作任务,同时可以帮我们持续观察项目的构建状态,测试通过与否,实在是我们开发之幸。

分享到

Windows下调试平板设备

本文主要记录Android上的Chrome和IOS上的Safari浏览器的调试方法,方便以后查看。开始之前请自备梯子,下面会需要翻墙。

Android设备调试

借助于Chrome的inspect工具,我们可以调试Android中使用了WebView的应用,所以调试Chrome网页也是同样的道理。

  1. 安装ADB和驱动。网上有很多这方面的文章介绍,但是鉴于很多时候会出现各种问题,所以建议使用一键工具统一安装,下载地址,需翻墙
    安装时一路Y确认安装,结束后你的系统中就已经有了ADB环境和Android驱动。
  2. USB连接上平板设备,并勾选平板设置里面的USB调试(一般在开发者选项里,如果没有开发者选项点击关于并连续点击版本号),如果平板弹出调试授权窗口,勾选一律允许然后点击确定。
  3. 打开命令行输入adb devices,此时应该能获取到设备ID,如果没有请上网查找解决方案。
  4. 平板上打开Chrome并输入网址,打开后在PC的Chrome上输入chrome://inspect/#devices,此时可以查看到已连接的平板上打开的网址,点击对应网址下的inspect,此时就会弹出一个调试窗口,这时候你就可以像调试WEB页面一样愉快地调试Android网页了。

IOS设备的调试

IOS上Safari浏览器的调试就比较简单,连接上设备和Mac,打开Mac上的Safari,勾选Safari的偏好设置里高级菜单下的“在菜单栏显示”开发”菜单”。

然后点击PC Safari的”开发”->”XXX的Mac”下的具体网址,此时就可以在弹出的窗口中进行调试了。

其它环境的调试

至于其它不能调试的情况,都可以使用weinre等方案进行调试,具体请Google之。

分享到

利用firebase打造极速静态博客

之前博客一直是做的动态的,后台页面,添加博文,然后保存后查看博文。但最近VPS感觉不稳定加之价格有点小高(主要是穷),打算将vps上的所有东西都放在云端,使用免费资源(还不是因为穷)。第一步就是从博客开始。

Hexo介绍

Hexo是由台湾的一名大学生创建的静态博客系统,它基于’NodeJs’,生成文章的速度非常快,这也是为什么选择它的原因。当然还有很多其它的系统,但是作为NodeJs阵营的我当然是选择它啦。

Hexo项目搭建

首先,安装官方文档过一遍,在本地安装搭建一个Hexo项目,例如我的HexoBlog
这时运行hexo server并打开浏览器访问http://localhost:4000应该就可以访问到你搭建后的博客了,如果没有,请仔细阅读文档,重来一遍。
这里我稍微修改了下_config.yml文件,然后添加了deploy模块

1
2
3
4
deploy:
type: git
repo: https://github.com/erguotou520/HexoBlog.git
branch: gh-pages

这样以后deploy后的public文件夹里的内容会自动提交到gh-pages分支下。

数据迁移

最开始的博客是在Ghost上跑的,后来又是用的pagekit,到现在的Hexo,每次数据迁移都是手动复制粘贴,太麻烦了,即使它们可能提供了一些迁移工具,但是还是会存在不靠谱的情况,所以还是手动复制吧。
这里要提到Hexo的一个好处了,文章是以markdown格式的文件存储,而不是存在数据库中,对于我们是可视的,再配合上后面的git,可以实现文章的历史管理。

结合Github

本地环境搭建好了之前就开始将它推送到github了,为什么放在github?一来是有个存储的地方,二来自带历史版本管理,三来可以实现自动化。
首先,添加hexo的git deploy插件。

1
npm install hexo-deployer-git --save

接着在项目中添加一些必要的文件,因为Hexo的生成器并没有生成这些文件和内容。

  1. 添加.gitignore,把node_modules.deploy_git添加进来,后者是在添加hexo-deployer-git插件并执行hexo deploy命令时会生成。
  2. 补充package.json文件,可以加上description等其它字段,可选
  3. 添加README.md说明文件,可选

OK,完成后开始推送。这个时候已经实现了hexo和github的结合,但是现在,每次添加完文章后都需要手动执行hexo generatehexo deploy,是否可以更简单呢?

与Travis结合

我们可以利用TravisCI的自动化测试来进行自动构建任务。网上也有很多介绍Hexo+Github的文章,简单来说,就是在项目根目录下添加.travis.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
25
26
27
28
language: node_js

node_js:
- "6"

branches:
only:
- master

before_install:
- npm install hexo-cli -g
- git config --global push.default matching
- git config --global user.name "erguotou"
- git config --global user.email "erguotou525@gmail.com"
- sed -i'' "/^ *repo/s~github\.com~${ACCESS_TOKEN}@github.com~" _config.yml

install:
- npm install

script:
# - git submodule init # 用于更新主题
# - git submodule update
- hexo clean
- hexo d -g

cache:
directories:
- node_modules

其中{ACCESS_TOKEN}就是下文要介绍的token。

接着在github中生成一个用于自动提交用的token。点击github中头像–>’Settings’–>Personal access tokens–>Generate new token生成一个给travis用的token(权限我只勾选了repo相关的)。
因为github提供了中使用token进行push的方式,这也是我为什么_config.yml文件中deploy模块用的repo是https地址的原因了。
生成token后将其添加到travis的环境变量中ACCESS_TOKEN=token。
最后提交所有文件,等待TravisCI的构建结果,此时应当完成了与TravisCI结合的功能,如果构建报错,请具体结合报错内容修改。

与Firebase结合

说到现在,我们都还没提到我们的主角Firebase。对于还不了解Firebase的同学建议先去看下网上的介绍。Firebase为我们提供了实时的云端存储和并提供全球CDN服务,我就是要利用它的CDN服务将我们的静态博客挂在CDN上。
首先,全局安装它的cli工具

1
npm install -g firebase-tools

然后登录firebase

1
2
3
# 不带参数会登录报错
# 如遇到翻墙问题请自行解决
firebase login --no-localhost

接着进入项目根目录,执行

1
firebase init

安装提示完成初始化,Firebase会自动在项目根目录下创建firebase.json文件,我们保证firebase.json里的public值为public即可,因为public文件夹是hexo生成的博客的目录。

1
2
3
4
5
{
"hosting": {
"public": "public"
}
}

此时执行firebase deploy就可以将我们的博客推送上去了。但是我们需要结合TravisCI实现自动部署,所以在.travis.yml中添加firebase的自动部署模块

1
2
3
# 2017-07-10更新
after_success:
- firebase deploy --non-interactive --token ${FIREBASE_TOKEN}

其中FIREBASE_TOKEN是让TravisCI进行部署时的密钥,它需要我们通过下面的命令来生成

1
firebase login:ci --no-localhost

登录验证成功后会得到一个token,复制它,在travis中添加环境变量FIREBASE_TOKENvalue为刚复制的token。
最后git提交推送,travis自动构建,firebase自动部署,OK,完美。

Firebase自定义域名

默认firebase会为我们提供一个域名访问地址,但我们一般会用自己的域名来访问。此时按照Firebase Hosting的文档提示,在我们的域名中添加2个txt记录完成域名拥有权的验证,验证完成后等待firebase颁发https证书(我睡了一晚,醒来之后就好了),最后按照提示,将我们自己的域名做一个cname,解析到firebase给我们提供的域名上就可以啦。

总结

本文介绍了Hexo+Github+TravisCI+Firebase搭建一个免费的拥有https的全球cdn加速的静态博客,综合利用了现有的网上资源,整个搭建过程会遇到各种问题,但都被一一解决。当然,Hexo作为静态博客,也会有一些不足,但这些不足我们都可以使用插件系统来实现,这也是后面要做的内容。
后面打算利用Firebase的database功能实现一个简单的博客评论系统,然后是定义一个自己用的主题,默认的太难看啦。后面的还有很长的一段路要走呢~

分享到

闲置树莓派捣腾记

手上有一个树莓派,之前装个openelec看看视频什么的,后来因为一些原因废弃了。本来打算做私有云的,但是树莓派做私有云可能有些力不从心,等安定了后再捣腾私有云吧,到时可能黑群晖,也可能白群晖,也可能其它方案,都还不一定呢。现在先拿来玩耍玩耍做个共享弄个开源ownCloud还是可以的。废话不多说,进入正题。

安装系统

  1. 使用SDFormat格掉SD卡。
  2. 使用Win32 Disk Imager将img镜像写入SD卡。这2步都在Win主机上执行,因为快,这也是为什么不推荐使用NOOBS安装的原因,太慢了。
  3. 卸下SD卡,装在我们的树莓派上,其它电源、网线、键鼠、显示器都接上。键鼠和显示器不是必须,但是有时为了方便会接上,而且刚进入系统用界面看IP地址也比较方便。
  4. 开机,点亮。
  5. 简单配置。如果是用NOOBS安装的系统,这步可以跳过。进入系统界面后,打开控制台,运行sudo raspi-config进入配置页面。选择第一个Expand Filesystem,将SD卡里的剩余空间全部扩充上。完成后可能要求重启。

调教系统

  1. 更新源。参考科大的帮助页。如果需要更新已有软件,可以使用sudo apt-get upgrade
  2. 静态IP。网上关于更改/etc/network/interfaces文件的方法我试了,没用(jessie版本开始不能用此方法了),在界面中也没找到网络设置的位置。不过可以使用这种方法:
    1
    2
    3
    4
    5
    6
    sudo nano /etc/dhcpcd.conf
    # 在配置文件最后加上
    interface eth0
    static ip_address=192.168.1.200
    static routers=192.168.1.1
    static domain_name_servers=114.114.114.114

改完后记得重启下。

  1. 安装samba。不知道是因为执行过apt-get upgrade的原因还是什么,在安装时会出现依赖冲突,不能安装的情况。最后参考http://askubuntu.com/questions/222658/samba-installation-failed-on-ubuntu-12-10 里面介绍的方法解决的。首先执行
    1
    sudo apt-get install --fix-broken && sudo apt-get autoremove && sudo apt-get update && sudo apt-get install samba

失败,然后卸载。

1
sudo apt-get remove samba-common libwbclient0 tdb-tools`,卸载完成后重新安装`sudo apt-get install samba samba-common-bin

  1. 配置samba。参照http://www.dreamxu.com/raspberrypi-nas/ 。先备份配置
    1
    sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

然后修改配置文件sudo vim /etc/samba/smb.conf并删除默认的home共享。

1
2
3
4
5
6
7
[share]
comment = Raspberry smb
path = /home/pi/share
browseable = yes
writeable = yes
create mask = 0664
directory mask = 0775

为了简单,此处直接使用已有的pi用户。在/home/pi下新建share目录。完成后重启samba服务sudo service samba restart。到此就完成了samba的安装配置,可以在设备上拷贝文件测试了。

分享到

Atom前端开发配置

Atom开发插件集合

2017-03-21更新,去除不常用的插件
2017-08-31更新,添加highlight-selected插件

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
apm list
Community Packages (28) /Users/erguotou/.atom/packages
├── Stylus@3.1.0
├── atom-beautify@0.29.17
├── atom-material-ui@1.3.9
├── autoclose-html@0.23.0
├── busy-signal@1.3.0
├── docblockr@0.9.3
├── editorconfig@2.2.2
├── emmet@2.4.3
├── file-icons@2.0.17
├── highlight-selected@0.13.1
├── intentions@1.1.2
├── language-gitignore@0.3.0
├── language-vue@0.21.2
├── linter@2.1.0
├── linter-eslint@8.1.4
├── linter-htmlhint@1.3.2
├── linter-ui-default@1.2.1
├── local-history@4.0.1
├── minimap@4.26.8
├── minimap-highlight-selected@4.5.0
└── pigments@0.39.1

└── (empty)

1
apm install Stylus atom-beautify atom-material-ui autoclose-html busy-signal docblockr editorconfig emmet file-icons highlight-selected intentions language-gitignore language-vue linter linter-ui-default linter-eslint linter-htmlhint local-history minimap minimap-highlight-selected pigments

UI配置

安装的是atom-material-ui主题,在mac上很多地方行高很高,需要修改其配置文件

分享到