mac 编译 nginx stream

上周搭建的gitlab对于ssh clone存在问题,主要是nginx对于stream默认是不支持的,需要自己重新编译。

对于ubuntu,按照网上教程,还是比较简单的,但是在mac下编译问题会稍微复杂一点,但是网上解决方法也很详尽,
细心一点,多试几次问题也不大。

一般mac的openssl都是比较老的,且存在漏洞,所有要下最新的指定编译就好了
./configure --prefix=/usr/local/nginx --with-stream --with-stream_ssl_module --with-http_stub_status_module --with-openssl=/usr/local/nginx/openssl-1.0.2r

另一个错误类似 ld: symbol(s) not found for architecture x86_64

要在 ./configure 之后
然后在objs里,打开Makefile,找到
./config --prefix=xxx.openssl no-shared

把该段的 ./config 改成 ./Configure darwin64-x86_64-cc 其他后面参数不变,保存

使用方法如下

1
2
3
4
5
6
7
8
9
10
stream {
upstream ssh {
server 192.168.1.12:22;
}
server {
listen 12345;
proxy_pass ssh;

}
}

Creating a Mongo replicaset using docker_ Mongo replicaset + Nodejs + Docker Compose

参考 https://www.youtube.com/watch?v=mlw7vWISaF4

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
version: '3'
services:
mongo-rs0-1:
image: "mongo-start"
build: ./mongo-rs0-1
ports:
- '27017:27017'
volumes:
- ./mongo-rs0-1/data:/data/db
- ./mongo-rs0-1/keyfile:/usr/src/configs/keyfile
- ./mongo-rs0-1/log:/usr/src/configs/logs
- ./mongo-rs0-1/backup:/usr/src/configs/backup
depends_on:
- 'mongo-rs0-2'
- 'mongo-rs0-3'

mongo-rs0-2:
image: 'mongo'
build: ./mongo-rs0-2
ports:
- '27018:27017'
volumes:
- ./mongo-rs0-2/data:/data/db
- ./mongo-rs0-2/keyfile:/usr/src/configs/keyfile
- ./mongo-rs0-2/log:/usr/src/configs/logs

mongo-rs0-3:
image: 'mongo'
build: ./mongo-rs0-3
ports:
- '27019:27017'
volumes:
- ./mongo-rs0-3/data:/data/db
- ./mongo-rs0-3/keyfile:/usr/src/configs/keyfile
- ./mongo-rs0-3/log:/usr/src/configs/logs

setup-rs:
image: "setup-rs"
build: ./setup
volumes:
- ./setup/replicaSet.js:/usr/src/configs/replicaSet.js
- ./setup/setup.sh:/usr/src/configs/setup.sh
depends_on:
- 'mongo-rs0-1'

有几个问题

容器setup-rs执行总是失败,导致副本集无法创建,只能进入容器mongo-rs0-1,执行replicaSet.js里
的内容创建副本集

1
2
3
4
5
6
7
8
9
10
11
rsconf = {
_id: "rs0",
members: [
{_id: 0, host: "mongo-rs0-1:27017"},
{_id: 1, host: "mongo-rs0-2:27017"},
{_id: 2, host: "mongo-rs0-3:27017"}
]
}

rs.initiate(rsconf);
rs.conf();

之后创建用户。
因为在本地你可以不使用keyfile。如果使用要注意权限问题

Visit Web With Frp and Nginx

原因

个人网站 无序野蛮发展导致功能混乱代码臃肿, 原先2台低配阿里云服务器勉强撑起整个站点,费用也要 >1k/台/年还是有限的带宽, 网站并没有什么流量,几乎没有访问量。 这真是太可怕了。
目前系统设计如下:
573054f24a30a60fd0e1ac9d5ed7bd2e.png
新设计将所有应用部署本地运行, 在server部署一个缓存应用来减少与local的通信
ec66de26afc54545b70b49d88b26732f.png

解决方案

通过frp内网穿透技术将请求转发到本地,如此只要一台服务器用于架设frp即可。

优势

  1. 节约成本
  2. 将闲余的mac电脑利用起来,性能贼好
  3. 通过docker部署
  4. 将数据保存本地,阿里云什么都要钱

步骤

原
88a46390f23f75635084ae2f519efddc.png
增加nginx
7eff94988a99a007933afcf1ba88674b.png

问题

  1. 中间增加frp层可能会造成传输堵塞
  2. 本地环境(网络,电)的稳定性

待续

原计划通过在本地添加3个从库之后直接切换,因为用了docker无法直接加入副本集,
所有准备用docker直接创建新副本集,整个数据迁移

Deploying ReactJS With Docker

自行选择测试项目,或新建项目

  • 创建

    1
    2
    npx create-react-app reactdocker;
    cd reactdocker;
  • 运行

    1
    npm start;
  • 关闭

    1
    ctrl + c

创建环境

1
2
3
4
5
6
7
8

# 在当前项目下执行
docker run -it -p 3001:3000 -p 80:80 -v $PWD:/var/www/localhost/htdocs --name reactdocker alpine /bin/sh

-p 3001:3000 # 虚拟机3000端口 映射 宿主机3001端口
-v $PWD 宿主机当前目录 映射到 /var/www/localhost/htdocs,也就是在虚拟机中自动创建/var/www/localhost/htdocs并映射
-—name reactdocker reactdocker为别名
alpine 虚拟机镜像

安装nodejs和npm

1
2
apk add nodejs;
apk add npm;

重新安装包

1
2
3
4
5
cd /var/www/localhost/htdocs;
# 原文中删除包再重新安装,可能是规避nodejs版本或者包存在差异
# 笔者建议可以先尝试 步骤5
rm -rf node_modules;
npm install;

启动

1
2
3
4
5
6
npm start;
# 访问 http://localhost:3001/
# press ctrl + c 关闭
npm run build; # 构建
cd build;
ls -al;

安装 nginx,nano

1
2
3
4
apk add nginx; # 代理服务器
apk add nano; # 字符终端的文本编辑器

nano /etc/nginx/conf.d/default.conf # 编辑代理服务器配置
  • default.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # This is a default site configuration which will simply return 404, preventing
    # chance access to any other virtualhost.
    server {
    listen 80 default_server;
    listen [::]:80 default_server;4
    location / {
    root /var/www/localhost/htdocs/build;
    # this will make so all routes will lead to
    # index.html so that react handles the routes
    try_files $uri $uri/ /index.html;
    }
    # You may need this to prevent return 404 recursion.
    location = /404.html {
    internal;
    }
    }

创建目录以允许nginx在进程ID上运行

1
2
3
4
mkdir /run/nginx;
nginx -t; # 测试配置
nginx;
# 访问 http://localhost/

创建 Dockerfile

1
2
3
4
5
6
7
8
9
10
退出容器  
ctrl + p
ctrl + q
# 创建config 文件夹
mkdir config;
# 拷贝 default.conf 到 config/default.conf
docker cp reactdocker:/etc/nginx/conf.d/default.conf config/default.conf;
# 销毁容器
docker rm -f reactdocker;
docker ps -a # 查看所有容器
  • 在项目根目录下创建基础 Dockerfile
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    FROM alpine
    EXPOSE 80
    ADD config/default.conf /etc/nginx/conf.d/default.conf
    COPY . /var/www/localhost/htdocs
    RUN apk add nginx && \
    mkdir /run/nginx && \
    apk add nodejs && \
    apk add npm && \
    cd /var/www/localhost/htdocs && \
    rm -rf node_modules && \
    npm install && \
    npm run build;
    CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;';"]
    WORKDIR /var/www/localhost/htdocs
1
2
3
4
5
6
# 构建
docker build . -t reactdocker
# 运行
docker run -it -d -p 80:80 --name rdocker reactdocker;
# 访问 http://localhost/
# 现在我们的容器已准备好推送到Docker Hub并准备好部署。

优化Docker镜像

  • 添加 .dockerignore 文件,来移除一下不再需要到依赖文件

    1
    node_modules
  • 接下来修改 Dockerfile来移除我们不需要的依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    FROM alpine
    EXPOSE 80
    ADD config/default.conf /etc/nginx/conf.d/default.conf
    COPY . /var/www/localhost/htdocs
    RUN apk add nginx && \
    mkdir /run/nginx && \
    apk add nodejs && \
    apk add npm && \
    cd /var/www/localhost/htdocs && \
    npm install && \
    npm run build && \
    apk del nodejs && \
    apk del npm && \
    mv /var/www/localhost/htdocs/build /var/www/localhost && \
    cd /var/www/localhost/htdocs && \
    rm -rf * && \
    mv /var/www/localhost/build /var/www/localhost/htdocs;
    CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;';"]
    WORKDIR /var/www/localhost/htdocs
  • 让我们看一下之前构建的容器大小

    1
    2
    $ docker images | grep "reactdocker";
    reactdocker latest d10ec33f5720 3 minutes ago 560MB
  • 现在我们重新构建

    1
    2
    3
    4
    docker build . -t reactdocker;
    # 查看容器大小
    docker images | grep "reactdocker";
    reactdocker latest f5b6a627f188 5 minutes ago 79.7MB
  • 再次运行容器

    1
    2
    docker run -it -d -p 80:80 --name rdocker reactdocker
    # 访问 http://localhost/

现在我们已经有了优化过的Docker镜像,让我们将它推送到Docker Hub。

1
2
docker tag reactdocker yuluhuang/reactdocker;
docker push yuluhuang/reactdocker;

下载

1
docker run -it -d -p 80:80 --name rdocker yuluhuang/reactdocker;

参考资料 https://medium.com/@mannycodes/deploying-reactjs-with-docker-ac16728c0896

elasticsearch + kafka + zookeeper + frp 案例

众所周知 elasticsearch 想要发挥最大功效所占内存也不小,即使是单节点,对于小网站或个人网站而言 1核2G的阿里云也是十分昂贵的支出应该用在刀刃上。

在本地通过 docker 启动 ES:6.4.2 + Kibana:6.4.2 + Logstash:6.4.2(发现它们都有6.4.2这个版本~), 本地是一台2011年的老mac(我是个念旧的人),以前自己动手升过配置: 8G内存 + 256G固态 + 320G机械, mac 的质量杠杠的,用docker的好处就是隔离,通过docker-compose方便快捷,以后如果架设集群也更加容易,一键就能将环境架设好。

现在把 ES 架好后,通过云上架设的frp(打开一条tcp通道)将数据传到本地存储或搜索。

1
2
3
4
5
[elasticsearch_mac]
type = tcp
auth_token = xxx
bind_addr = 0.0.0.0
listen_port = 9300

kafka + zookeeper 为了防止请求数据丢失,本地环境不稳定性或frp阻塞都有可能造成请求失败。

首先我通过 java 服务(spring boot) 将数据写入消息队列(kafka),通过消费kafka的消息并把数据保存到ES上。

1
2018-11-14 13:42:54.952 DEBUG 5460 --- [ntainer#0-0-C-1] c.y.e.a.s.f.impl.FeedSearchServiceImpl   : {"query":{"term":{"id":{"value":"5bebb5dea2ed430a4a6dfebc","boost":1.0}}}}

以上只是提供一个可行的思路,学习es顺便给自己网站多添加一个搜索功能,目前主要还是用的solr

通过 nginx 配置基本的安全验证

以前我也有个疑问 像solr, elasticsearch 我布置好之后如果我想远程访问只能开放端口,而他们本身并没有验证,当然有其他策略比如,配置一台跳板机,只允许特定的跳板机访问, 自己没那么好条件也不想弄那么麻烦就采用简单的方法做验证

步骤

  1. 在 nginx 配置目录下创建密码
1
2
3
4
5
mkdir password
cd password/
printf "root:$(openssl passwd -crypt password)\n" > passwords # 密码不超过8位
pwd
/etc/nginx/password # 在 nginx中 使用
  1. 配置nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upstream elasticsearch {
server 127.0.0.1:9200 weight=10;

}
server {
listen 19200;
server_name localhost;
auth_basic "Protection";
auth_basic_user_file /etc/nginx/password/passwords;

location / {
proxy_pass http://elasticsearch;
proxy_redirect off;
}
}
  1. 重启nginx, 打开 localhost:19200

这让我想起给solr做验证时采用非常麻烦的方法真是蛋蛋疼
如果你的解决方案很复杂你要相信一定还有更好的你不知道的解决方案,去寻找吧少年

mysql with docker

  1. 通过 kitematic 安装 mysql8 镜像不能直接使用
  2. 设置root密码
    docker-mysql-1

  3. 修改固定端口
    docker-mysql-2

  4. 映射本地目录
    docker-mysql-3
  5. 连接本地数据库
    docker-mysql-4
    问题
    1
    Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so, 2): image not found

解决

  1. 进入终端
    docker-mysql-5

  2. 执行

    1
    2
    mysql -uroot -proot
    ALTER USER 'root’@'%' IDENTIFIED WITH mysql_native_password BY 'root';

docker-mysql-6

docker 使用场景之测试

参考: https://www.youtube.com/watch?v=k5iwKUZY9tk

测试环境 mac

1 Get docker image.

$ docker pull chusiang/takaojs1607

1.1 原镜像较老 如果要用自己的镜像安装环境(略过)

  1. 安装selenium
    sudo pip install selenium

  2. 安装Chrome浏览器
    sudo apt-get install libxss1 libappindicator1 libindicator7
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    sudo dpkg -i google-chrome*.deb
    sudo apt-get install -f

  3. 安装ChromeDriver
    在运行过程中ChromeDriver会与Chrome浏览器不兼容,重新下载ChromeDriver地址

sudo apt-get install unzip
wget -N http://chromedriver.storage.googleapis.com/2.42/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
chmod +x chromedriver
sudo mv -f chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

2 Get vnc port

docker port $(docker run –name e2e -d -P chusiang/takaojs1607) 5900
or
docker run –name e2e -d -P chusiang/takaojs1607
docker port e2e 5900

返回 0.0.0.0:32768

3 打开 Remote with VNC client(看测试效果)

open vnc://:secret@127.0.0.1:32768

开始测试

1 Enter e2e container.

$ docker exec -it e2e bash

2 Switch user wget

su - seluser
该用户下已经有测试代码

3 进入安装环境 并运行

ls && cd angular-seed/ && npm run start &

4 Run e2e test 运行测试

npm run protractor

Github 授权登录 让你的网站更轻巧

例图
github_authorize

1 注册 github 账号
2 Settings -> Developer applications -> new OAuth App
github_new_OAuth

Authorization callback URL--后端回调url, github 会调用这个url 将code发送给你,你需要获取这个code 之后,再去获取 access_token ,再通过 access_token 获取用户信息

3 你已创建好 OAuth Apps 我们开始使用
3.1 你的网站上需要一个登录按钮
github_logo

1
2
3
4
5
6
7
8
<a class="btn btn-light btn-sm" href="https://github.com/login/oauth/authorize?client_id=xxx&state=xxx&redirect_uri=xxx">
<svg height="14" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="14"
aria-hidden="true">
<path fill-rule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
<span style="font-size: 16px;">登录</span>
</a>

注意他的 href 中client_id 从你创建的 OAuth Apps 找到,redirect_uri 即 Authorization callback URL(注: 要使用公网ip地址)

3.2 上一步你拿到code,现在获取 access_token

"https://github.com/login/oauth/access_token?client_id=xxx&client_secret=xxx&code=" + code + "&redirect_uri=xxx";
注:每个参数都是必须的具体参考文档 https://developer.github.com/v3/
client_id 和 client_secret 从应用中拿到即可 redirect_uri 即上一步中的一样即可

3.3获取用户信息

1
2
3
4
5
6
7
8
9
let access_token_url = "https://api.github.com/?access_token=" + access_token;
let headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3571.0 Safari/537.36'};
// GET
request(access_token_url, {headers}, function (err, rs, userInfo) {
if (err) {
logger.error(err)
}
logger.info(userInfo);
});

注:* 请求头里必须有 User-Agent

* 必须用 get 请求

结果

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
{
"login": "yuluhuang",
"id": 5743499,
"node_id": "MDQ6VXNlcjU3NDM0OTk=",
"avatar_url": "https://avatars1.githubusercontent.com/u/5743499?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/yuluhuang",
"html_url": "https://github.com/yuluhuang",
"followers_url": "https://api.github.com/users/yuluhuang/followers",
"following_url": "https://api.github.com/users/yuluhuang/following{/other_user}",
"gists_url": "https://api.github.com/users/yuluhuang/gists{/gist_id}",
"starred_url": "https://api.github.com/users/yuluhuang/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/yuluhuang/subscriptions",
"organizations_url": "https://api.github.com/users/yuluhuang/orgs",
"repos_url": "https://api.github.com/users/yuluhuang/repos",
"events_url": "https://api.github.com/users/yuluhuang/events{/privacy}",
"received_events_url": "https://api.github.com/users/yuluhuang/received_events",
"type": "User",
"site_admin": false,
"name": "luhuang",
"company": null,
"blog": "https://yuluhuang.com",
"location": null,
"email": "504367857@qq.com",
"hireable": null,
"bio": null,
"public_repos": 30,
"public_gists": 4,
"followers": 5,
"following": 5,
"created_at": "2013-10-22T04:31:11Z",
"updated_at": "2018-09-30T03:25:01Z"
}

2018-9-22 记

昨天吃的太好拉肚子了,短期记忆深刻,可以记上好久。

晚上回家惯例打开阿里云app看一眼波动,香港的服务器需要续费了,一年1k多,三年便宜点但是我不会续那么久,且不说曾经被封过一段时间,单单每个月一封警告邮件看着都蛋疼。
所以尝试一下 搬瓦工,去官网一看赶巧 9.20 补货$19.9/年的方案,叠加优惠券花了130元不到,还是人民币贬值后。听说3年前的套餐只要$3.9/年,羡慕老套餐用户,当然配置低点

1
2
3
10G ssd
512M 内存
500G/m 流量

目前阿里云配置

1
2
3
40G 云盘
1G 内存
不限流 下载速度 100k/s 全天候一个月能攒 500G吗~

价格老贵,当时活动价350左右的样子,现在续费要1000多,我又不傻果断放弃

##
晚上注册付费,支持支付宝很方便,架设方便,顺便跑了个小程序才占了一点点资源,下载速度有1M,150mm的延迟,阿里云56mm, 大体上相差不大,毕竟一个在香港一个在美国

##
今天把公司这边的客户端搞搞,装个ubuntu-desktop, 试试 anbox
此处省略n操作,结论根本不好时,之前我就想mac里使用android apk, 当时应该问一下辅导,在网上瞎找,
之后用的都是以前玩过的东西 Genymotion 模拟器,搞到第二天3,4点好像又熬夜了,搞那么久一个是摸索造成,一个是眼贱浪费了好多时间Genymotion-ARM-Translation也是一个,
两天就做了这么几件事,好吧接下来还有点时间

效果图