防止刷新导致的重复Post提交

写了这么久才第一次意识到这个问题,当表单的地址跟当前的地址一样时,刷新会自动post现在form数据,不明白浏览器为什么刷新会用Post。

最好的办法就是Get A Page – Post B Page – Get A Page

其实就是只要表单的提交地址跟当前地址不一样,提交完后重定向回来即可。

Mac 上Docker开发怎么解析本地IP

如果开发部署需要在多台服务器上时,多个不同compose容器间的连接就成为了问题。

比如我有一个docker-compose-base.yml 部署了mysql和nginx方便给其他应用重用,和另外两个docker-compose-A.yml,docker-compose-B.yml,默认三者都会创建各自的网络,要让他们联通需要一个默认的访问规则,因为我不希望新的应用依赖或者base反过来依赖,最好相互完全独立。

所以我的办法时在linux上可以给docker默认分配192.168.0.1网段后绑定一个默认ip就可以像使用overlay网络一样记住ip就可以互相联通了,这里不需要link容器。

上面解决了多台服务器部署的问题,但是开发的是docker for mac,mac的系统不是linux,素以它有些独特的限制,导致上面的办法不能在mac上使用。因为它无法绑定到私自的网段,私自的网段是不被mac允许的。

问题一:如何稳定的访问到主机?用过docker的知道localhost是没用的,dfm创建了一个新的本地dns类似hosts是“docker.for.mac.localhost”,并且应用到所有容器,这样就不存在mac ip一直更新的麻烦了。

问题二:从主机访问容器的服务?官方推荐是全部publish出来,反正是开发的内网,无所谓了。

另外一个我的办法,就是所有compose里的服务都用bridge模式,这时是可以跨compose link到所有服务的。

Python Flask 400 Bad Request Form表单提交的错误

一个简单的WebForm

用Flask也好几年了,今天莫名其妙的一个简单的Form总是400错误。

搜索到一个SO的答案,让人汗颜呀:https://stackoverflow.com/questions/40442827/bad-request-with-flask

也许用flask的出现400错误大体都是因为错误的使用MultiDict这个类吧。首先这个类是flask团队自建的一个dict子类,因为是子类,不能跟默认的dict一样用,主要是为了解决一个key下可能有多个value的问题。所以它还有个get_list方法。

哎,丢大人了

Ziroom自如寓vs南京-合租吧

自如寓,挺大的,目前在住

南京合租吧

在南京很多毕业生都应该听说过合租吧,南京这个地方高校多,毕业需求大,而且政府对应届毕业生有租房补贴,可以说是这类公寓创业项目最好的城市吧。但是毕业生也有缺点,流动性大,支付能力弱等缺点。

上面的自如就大了,开始在北京做的,面向工薪,价格比普通租赁高很多。

下面从我租住过他们的经历做一下对比:

租金:自如因为品牌所以肯定高很多,反倒合租吧租金接地气。

保洁:都是两次一个月,保洁对合租帮助很大,也是合租巨大优势,否则合租的几个人对谁来保洁还要争论一下,好说话的还好,不好说话的住一个屋檐下就尴尬了。

门锁:合租吧是大门密码锁,里门普通锁。这个ziroom做得好很多,里外屋都是密码锁,还可以用手机更新,很先进,但是使用不方便,每次关门都得按密码烦得的很,而且像住在房中房的感觉,对于同屋其他人的信任就更不需要了。但是安全却得到很大的保障。

月服务费:这个算是给管家保洁这些的费用吧,这个合租吧接地气很多很多,我想自如去南京是干不过它的,170元包含所有这些除了电需要另外交。ziroom居然收取房费的10%,卧槽,这个跟房费有毛关系,还不包含水费,想北上广租金在3k很正常,300一个月都可以请很好的保洁了,更别说几个人一起就好几千了,那个时候听到管家说保洁40一个小时我都怒了。

违约:这个非常重要,这个在这类创业项目中盈利是大头,合租吧是从1.5倍开始算,ziroom好像是2倍,有时候好不容易挑选的时候租金省下的几百租金,在押金这块分分钟就没了。还得提前十五天,ziroom好像是20天告知是否续租,否则租金就没了。那么有的同学问了,1.5或者2倍他们是怎么扣的,毕竟只压了一倍的租金不是。只要违约了,押金是肯定没有了,更多的是预交的房租里扣除。人家算的好好的了。

水电计算:合租吧很棒,水煤气费算在服务费里头,管家省事多了,确实从成本看这里其实没多少钱,170完全能覆盖,电的计算是空调自己交自己的,其他公摊,这个算法已经是我能想到的最公平的了。这里ziroom就差远了,黑的不要不要的,交了几百的服务费里头不算水的,水和煤气照样要单独算,它的算法就粗暴了,直接是所有水电平摊,如果室友用水用电正常还好,碰到用的多的就自认倒霉吧。

细节-垃圾桶:合租吧有标配垃圾桶,ziroom没有(差评)

细节-橙盒:合租吧没有(差评),ziroom很出名的一个盒子,有垃圾袋、抹布、剪刀这些小东西,都是不值钱质量一般的,但是都很实用。

细节桌椅柜:都差不多,床感觉ziroom的好很多,不是指床架,是席梦思很棒。对了提一下泊寓,万科搞的,这些配的就很给力,毕竟是完全它配的好很多。

细节晒衣服:ziroom是没有给解决的,合租吧都有地方可以晒衣服,比如飘窗。

细节-支付:都是可以支付宝这类的很方便,ziroom还支持信用卡。

 

 

自建gogs 连接时端口的选择

git推送默认走ssh的22端口,自建的服务通常会跟服务器的22端口冲突,当然这里指的是docker,又看到达人通过转发的方式实现和宿主一同使用22端口,但是实际上咱自建的服务只要配置一下ssh就可以了。这里吐槽一下 git怎么就不能设置默认连接的端口呢???

修改文件:.ssh/config

最后加入如下,1022端口即是docker映射出来的ssh端口,注意Port前有缩进:

Host git.xxx.com

Port 1022

用Docker安装Gogs 取代gitlab -给自己的代码安个家

 

自己搭建gogs服务器原因如下:

  1. 原先用的git.oschina.com,发现免费版对diff有限制,这就算了,对于history版本也有限制,这个就不能忍了,当时没办法只能用本地的github过度了一下;
  2. 发现gitlab有docker版本,开心啊,配置就省心多了,于是开始架设gitlab dockerise服务;
  3. 穷人来说只能用一台入门的ecs 1gb ram +1 core,结果gitlab搞笑的告诉我它至少需要3g ram,至少1g ram+2g swap,只是一个git服务而已,我的天;
  4. gitlab用的uncorn很吃内存,但是服务100+用户没问题,咱私人的不需要这么强,而且它依赖的是企业级的架构:nginx+redis+sidekiq +rails++unicorn+postgresql 应该没有列完,换mysql还挺麻烦的;
  5. 官方docker打包了上面提到的服务,大小居然达到了1.1GB;
  6. gogs是用go写的,go可是堪比c++的性能,功能强大,后来试用后功能堪比github,大小只有128MB,兼容三大数据库,sqlite也支持,这个要赞一个,意味着在树莓派上也是妥妥的,最近go的应用真是如火如荼呀,架设好后内存只吃了30MB,良心项目~;)
  7. 近2万~星,应该是国人写的,骄傲一个;

直接说安装步骤吧(ubuntu):

安装docker和docker-compose:

apt-get install docker -y && pip install docker-compose

创建一个存放gogs数据的地方:

mkdir -p /srv/gogs

创建docker-compose.yml  :

nano docker-compose.yml

配置如下:

</pre><pre>gogs:
  image: gogs/gogs
  container_name: gogs
  depends_on:
    - db
  ports:
    - "3000"
  ports:
    - "10022:22"
  volumes:
    - "/srv/gogs:/data"</pre><pre>

上面depends_on部分里的db是我的mysql服务,如果你的mysql服务不是dockerise的话请删掉这部分。

最后运行服务:

docker-compose up

上面只是最简单的配置,它还内置了nginx,所以既可以直接访问上面的3000端口(甚至指定证书)也可以跟现有的nginx再次代理本地80端口转发。

服务起来后就可以初始化配置了,默认注册的第一个账户为管理员账户,数据库信息跟其他服务一样,需要先建好它用的库和用户即可。初始化页面配置的都是必须的选项,比较简单,安装好后可以在控制面板看到很多设置信息,但是是不能更改的,估计是开发者偷懒,我很理解,我也会这样,呵呵。需要修改的话按照上面的配置是在主机的/srv/gogs/gogs/conf/app.ini中修改,详细的配置项在:https://gogs.io/docs/advanced/configuration_cheat_sheet 修改后docker-compose restart gogs即可

 

Docker 错误:network xxx id xxxx has active endpoints

Docker 总是会碰到各种问题,很多甚至完全找不到原因。docker cli确实不可靠,有时候已经显示了done,但是并没有生效,好在docker开发如火如荼,碰到的问题也会越来越少。docker 碰到问题后常用的办法就是删掉所有container和networks然后重启就好了,这里不会丢掉任何数据。这里不得不说“-f”这个神奇的参数,比如docker rm xxx失败可能是因为没有stop掉,但是如果-f了它会自己stop,完了还总是出错,出错就出错吧,container还是能被删掉,好奇怪的东西。

回归主题,出现这个错误后我把所有容器都删除了,结果并没用用使用docker network inspect查看后发现network这边并没有随之删除,好奇怪的bug,难道删除容器时network就这么无视么。这里要用docker network disconnect -f [networkid] [containerid] 来删除,下面写了一个脚本,disconnect所有network下的所有容器,并删除所有容器。

docker network ls -q | while read networkid; do
        echo "network:$networkid"
        docker network inspect $networkid | jq -r '.[0].Containers | keys[]' | while read endpoint; do
                echo "docker network inspect $networkid | jq -r ".[0].Containers[\"$endpoint\"].Name""
                container=$(docker network inspect $networkid | jq -r ".[0].Containers[\"$endpoint\"].Name")
                echo "docker network disconnect -f $networkid $container"
                docker network disconnect -f $networkid $container

        done
done
docker rm -f $(docker ps -a -q)

CUI环境下Selenium+chrome最新headless特性的问题

我的环境:

  • Docker jessie
  • Python 3.4
  • Selenium 3
  • Chrome59
  • chrome webdriver 2.30

官方推荐的使用方法:https://intoli.com/blog/running-selenium-with-headless-chrome/

我的参数是:

options = webdriver.ChromeOptions()
options.binary_location = '/usr/bin/google-chrome'
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--window-size=1200x600')

执行官方示例时出现下面的错误:

selenium.common.exceptions.WebDriverException: Message: unknown error: an X display is required for keycode conversions, consider using Xvfb
  (Session info: headless chrome=59.0.3071.86)
  (Driver info: chromedriver=2.30.(8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-49-generic x86_64)

chrome headless时刚更新的特性,搜索到的文章大多都是用的xvfb,只找到一位日本同学绕开了这个问题。其实google官方就有专门说selenimu还不能很好的支持新的headless,实际使用时主要在sendkeys时出错,日本同学用js绕过了这个错误。方法如下:

# driver.get_element_by_css_selector('hoge').sendKeys('fuga') は例外が発生
def _set_value_for_element(selector: str, value: str):
        return 'document.querySelector("{selector}").setAttribute("value", "{value}")'.format(selector=selector, value=value)

driver.get(url)
# sendKeys() を実行すると例外が発生するので、JSを実行する
driver.execute_script(_set_value_for_element(user_name_selector, user_name))
driver.execute_script(_set_value_for_element(user_password_selector, user_password))
driver.find_element_by_css_selector(login_button_selector).click()

家庭NAS DIY经验和笔记 — 公网共享(FTP vs SFTP vs FTPs vs WebDAV)和dns缓存

前面写了两篇:

#原创新人# 升级6硬盘NAS DIY经历和经验

升级6硬盘NAS DIY经历和经验 — 内网穿透篇FRP

内网穿透后远程桌面已经很开心了,难点搞定了后就是一项项服务了,最最重要的服务就是文件的共享,很多其他服务在没搭建前只要有文件共享都是可以暂时顶替的,所以它太重要了。这里对比一下现下流行的几个公网internet文件服务,内网的直接文件共享,老掉牙就不提了哈。

FTP:这个东西谁人不知谁人不晓,曾经互联网的半边天啊,那个时候什么bt、磁力链、迅雷都还在蛋蛋里哈哈。 😀 可是作为五十多岁的老爷爷,在这黑客肆虐的互联网里真的是若不经风,而且速度不理想,用过的同学应该记得,打开一个目录都要一下下才行,没有嗖嗖的那种快,所以它排到最后,第一个拿来说是对它的致敬。

FTPS:作为ftp的后继者,也是互联网ssl时代的必然产物,传输都是加密的,缺点同上,相比之下安全当然是ssl下大大加强了。不过对于ssl,最近真的事情好多,openssl blood事件爆发,那么多网站沦落也不那么安全了,而且因为依赖ssl,所以还需要ssl证书才能布置服务端,因为这个原因我从来没有架设过它,拿出来说实在有不少人在用。

WebDAV:用这个的人就更多了,一直指导它不安全,想想加上ssl试试,毕竟好多公司都在用它。一定要上ssl哦,否则分分钟变肉鸡。它实在http协议上扩展的,对文件共享那是融入dna里的,同样也摆脱不了http不安全的一面,还有就是状态不可保持。花了点时间配置起来了,需要一个web服务器,微软的iis还会专门提醒你它不安全建议和ssl搭配使用。优点是:因为原生对文件共享的支持,各种顺滑的体验有木有,秒开有木有,一度用的不亦乐乎。缺点:放弃它安全不是主要的问题,毕竟还没发生嘛对嘛,主要是对大文件的支持太差,默认居然只有几MB的文件都不行,闻到死还限制了50mb的大小,跟别说断点续传了。

SFTP:说到这里可能就会想,如果像WebDAV一样快,又能传大文件,还有断点续传就好了,没错这就是今天的主角,sftp,跟ftps的区别是它支持ftp的指令但实际上是用的ssh,ssh有Linux的经验的都知道,它是现在的几个安全堡垒之一,如果关闭了密码登录,就连暴力破解都拿它没办法。它没有上面提到的任何缺点,而且安全,快速,下面是使用步骤。

1 搭建ssh服务器: sudo apt install openssh-server -y

2 用另一台linux或者mac使用ssh-copy-id生成私钥id_rsa,这步请自行百度,生成后拷贝下来:scp root@123.123.123.123:/root/.ssh/id_rsa ~/

3 保存好这份文件,别人拿去了可就可以登录你的服务器了哟。建议使用完就删掉。

4 iphone上的使用,打开itunes链接手机,打开app的文件共享,比如photosync,拖入id_rsa,断开链接后在app内即可配用id_rsa登入凭据的sftp了。

至此,从任何地方都可以愉快的分享咱nas的文件了。

不过在家里刷照片时感觉速度没有以前那么嗖嗖的,当然了,因为要去frps服务器上绕一圈,跟局域网是不能比的。其实从时间上说,咱70%的时间都是在家和公司里度过的,公司里已经不可能在快了,那么在家里,就靠着nas还要绕一圈就说不过去了。

解决办法:dns解析+端口转发

dns解析,做法是在nas上的ubuntu搭建一个dnsmasq服务,接管路由器第一个dns解析。这样穿透时那个访问公网ip的域名比如:home.xxx.com即可转向内网的一台机器,而不必出去绕一圈,起到加速的目的。同时这个dnsmasq还可以开启dnscache,本来也打算架设这个东西的,加速效果感受得到,请求缓存其实浏览器已经做的非常到位了,效果有限,有的路由器支持请求缓存可以打开对比一下。dns缓存就差很多了,浏览器dns缓存有限,nas不仅缓存量大,而且可以异步的更新缓存。效果就是每个请求分分钟省下几百ms。现在从手机app到看视频哪个不要dns解析,加起来就多了。现在好多路由器也有这个组件,可惜俺的小梅林没有,所以。。。同时它也可以解决dns劫持的问题,需要的自行百度哦。

1 安装dnsmasq,只有18kb,有木有,有木有这小又如此大用的东西:sudo apt install dnsmasq -y

2 编辑文件/etc/dnsmasq.conf在最后加下面,后面的ip可以换ipv6,所以呵呵你懂的。cache可以设置大一点,dns几乎很少更新的,缓存大了后命中率很高,加速就更明显了。

address=/home.xxx.com/192.168.1.x

cache-size=8192

3 重启dnsmasq,让配置生效:

service dnsmasq restart

4 端口转发,这里有点复杂,依次执行下面命令,只要记住替换下面命令中的ip即可。大概过程是打开iptable的设置,允许ipv4转发,设置本机转发端口,最后查看是否成功。

sudo -i #切换root用户

sudo apt install iptables-persistent -y #安装iptables持久组件

sudo nano /etc/sysctl.conf #编辑系统配置

net.ipv4.ip_forward=1 #上面文件中找到这一行,删除注释

sudo sysctl -p #使上面的配置生效

sudo sysctl –system

iptables -t nat -L #查看当前nat规则

for i in $( iptables -t nat –line-numbers -L | grep ^[0-9] | awk ‘{ print $1 }’ | tac ); do iptables -t nat -D PREROUTING $i; done #这行不一定需要,用来删除所有nat规则的,执行一下可以清空

iptables -t nat -A PREROUTING -p tcp -d 192.168.1.123  –dport 6666 -j DNAT –to 192.168.1.123:22 #将123端口转发到22端口,这条规则本机无法使用,如果要local使用需要用output指令

iptables -t nat -L #查看是否生效

再次检查家中路由器的dns第一个地址是否改为dnsmasq的ip,最后在不更改photosync设置的情况下回家后会自动直连家里的nas,看看更新速度是否提升了。

 

 

 

群晖双盘更换其中已经损毁的硬盘

某天打算看片的时候,一进DSM,发现app全没了,顿时心里一跳。看消息里:卷2已经损毁。这是第二次碰到这种情况了,群晖是有专门的客服的,第一次沟通那个累,这次打算自己上场。

这次损毁说明了几件事:

  1. 希捷的硬盘不靠谱,刚买就坏过一次,才一年多又坏了。
  2. 查了好多文章,对于廉价备份来说basic型备份足以,否则做raid坏了一块后怎么从另一块里拿出数据是个问题,而且raid恢复很伤硬盘,万一恢复中出现问题那就只能让上帝帮你了。
  3. 硬盘好像是ext4格式的,那么意味着mac和windows的电脑都是读取不出数据的,你需要一台linux电脑你有么?我有。
  4. 同时插上两块硬盘启动不了系统,我的情况是一块是新的,一块是之前没坏的,大家应该差不多跟我一样的情况吧。我的启动方式为卸掉硬盘启动,然后热插上之前没坏的,就可以重装dsm,这里不能用新的硬盘,否则数据全无!!!~装好dsm后才能热插新硬盘。
  5. 为什么那么多人骂群晖,最大原因就在它系统架构的垃圾上,坏了一个硬盘后应用全丢,而不是单独有地方作为系统盘,这也是为什么可以备份应用,这是很奇怪的逻辑,伤不起。
  6. 散热设计不科学,我的是215,双盘的大多这么设计吧,风道很烂,风扇倒是不错,那也不是群晖设计的。
  7. 第三备份很重要,打算拿手头的资源搞一个第三备份了。