在 OSX 上用 openresty 架设自己的 Git Web Service
目录
介绍
openresty
是基于 nginx
的一个集成,选择它主要是因为它增加了对 lua
的支持,你可以轻松地用 lua
编写自己的 web 应用。
本文介绍一种比较独特的应用场景,为 ipad
上的一款开发工具 codea
提供 github
版本管理,ipad
上的客户端程序通过事先架设好的 web service
服务器提交代码到 github.com|bitbucket.org|git.oschina.net
等远程代码仓库。
可以把该 web service
部署运行在外部服务器,也可以让其部署运行在内部服务器上,本文介绍第二种方式。
下载编译安装openresty
首先通过 git
克隆 ngx_openresty
Air:GitHub admin$ git clone https://github.com/agentzh/ngx_openresty
Cloning into 'ngx_openresty'...
remote: Counting objects: 5081, done.
remote: Total 5081 (delta 0), reused 0 (delta 0), pack-reused 5081
Receiving objects: 100% (5081/5081), 1.08 MiB | 67.00 KiB/s, done.
Resolving deltas: 100% (3278/3278), done.
Checking connectivity... done.
Air:GitHub admin$ cd ngx_openresty/
Air:ngx_openresty admin$ ls
FreeBSD README.markdown demo patches t
Makefile clients misc specs util
Air:ngx_openresty admin$
接着第一次运行 make
取包,过程比较长。
Air:ngx_openresty admin$ make
./util/mirror-tarballs
ngx_openresty 1.7.10.2rc0
--2015-06-22 11:47:49-- http://nginx.org/download/nginx-1.7.10.tar.gz
Resolving nginx.org... 206.251.255.63, 2606:7100:1:69::3f
Connecting to nginx.org|206.251.255.63|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 828607 (809K) [application/octet-stream]
Saving to: `nginx-1.7.10.tar.gz'
100%[========================================================================================>] 828,607 125K/s in 7.0s
2015-06-22 11:47:56 (116 KB/s) - `nginx-1.7.10.tar.gz' saved [828607/828607]
[INFO] applying the upstream-pipelining patch for nginx
patching file src/http/ngx_http_upstream.c
Hunk #1 succeeded at 1419 (offset 203 lines).
Hunk #2 succeeded at 1771 (offset 352 lines).
Hunk #3 succeeded at 1827 (offset 340 lines).
patching file src/http/ngx_http_upstream.h
Hunk #1 succeeded at 365 with fuzz 1 (offset 41 lines).
完成后进入目录 nginx-1.7.10.
,运行 configure
进行配置检查,比如指定安装路径,我们要把 openresty
安装到 /opt/openresty
安装目录下,那就加这句参数 --prefix=/opt/openresty/
,如下:
Air:ngx_openresty admin$ ls
FreeBSD misc t
Makefile ngx_openresty-1.7.10.2rc0 util
README.markdown ngx_openresty-1.7.10.2rc0.tar.gz work
clients patches
demo specs
Air:ngx_openresty admin$ cd ngx_openresty-1.7.10.2rc0
Air:ngx_openresty-1.7.10.2rc0 admin$ ls
README.markdown bundle configure
Air:ngx_openresty-1.7.10.2rc0 admin$ ./configure --prefix=/opt/openresty/
最后出现了错误,如下:
Undefined symbols for architecture x86_64:
"_pcre_free_study", referenced from:
_ngx_pcre_free_studies in ngx_regex.o
_ngx_http_lua_ngx_re_match in ngx_http_lua_regex.o
_ngx_http_lua_ngx_re_gmatch in ngx_http_lua_regex.o
_ngx_http_lua_ngx_re_sub_helper in ngx_http_lua_regex.o
_ngx_http_lua_ngx_re_gmatch_cleanup in ngx_http_lua_regex.o
_ngx_http_lua_ngx_re_gmatch_gc in ngx_http_lua_regex.o
_ngx_http_lua_ngx_re_gmatch_iterator in ngx_http_lua_regex.o
...
ld: symbol(s) not found for architecture x86_64
需要手动设置 prce
的位置,如下为我的系统中的设置:
Air:ngx_openresty-1.7.10.2rc0 admin$ ./configure --prefix=/opt/openresty/ --with-cc-opt="-I/usr/local/Cellar/pcre/8.35/include" --with-ld-opt="-L/usr/local/Cellar/pcre/8.35/lib"
有些人的系统可能会提示缺少 OpenSSL
和 PCRE
,可以使用 brew install
安装。
安装好厚再次运行配置检查,确认无误后会显示如下内容:
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library
nginx path prefix: "/opt/openresty//nginx"
nginx binary file: "/opt/openresty//nginx/sbin/nginx"
nginx configuration prefix: "/opt/openresty//nginx/conf"
nginx configuration file: "/opt/openresty//nginx/conf/nginx.conf"
nginx pid file: "/opt/openresty//nginx/logs/nginx.pid"
nginx error log file: "/opt/openresty//nginx/logs/error.log"
nginx http access log file: "/opt/openresty//nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
cd ../..
Type the following commands to build and install:
gmake
gmake install
Air:ngx_openresty-1.7.10.2rc0 admin$
接着在该目录下执行 gmake
和 gmake install
执行 gmake
最后的显示:
...
objs/addon/src/ngx_http_rds_csv_util.o \
objs/addon/src/ngx_http_rds_csv_output.o \
objs/ngx_modules.o \
-L/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/luajit-root/opt/openresty//luajit/lib -Wl,-rpath,/opt/openresty//luajit/lib -L/usr/local/Cellar/pcre/8.35/lib -L/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/luajit-root/opt/openresty//luajit/lib -lluajit-5.1 -lm -pagezero_size 10000 -image_base 100000000 -lpcre -lssl -lcrypto -lz
gmake[2]: Leaving directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10'
gmake -f objs/Makefile manpage
gmake[2]: Entering directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10'
sed -e "s|%%PREFIX%%|/opt/openresty//nginx|" \
-e "s|%%PID_PATH%%|/opt/openresty//nginx/logs/nginx.pid|" \
-e "s|%%CONF_PATH%%|/opt/openresty//nginx/conf/nginx.conf|" \
-e "s|%%ERROR_LOG_PATH%%|/opt/openresty//nginx/logs/error.log|" \
< man/nginx.8 > objs/nginx.8
gmake[2]: Leaving directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10'
gmake[1]: Leaving directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10'
Air:ngx_openresty-1.7.10.2rc0 admin$
```
执行 `sudo gmake install` 最后的显示:
test -d '/opt/openresty//nginx/logs' || mkdir -p '/opt/openresty//nginx/logs' test -d '/opt/openresty//nginx/logs' || mkdir -p '/opt/openresty//nginx/logs' test -d '/opt/openresty//nginx/html' || cp -R html '/opt/openresty//nginx' test -d '/opt/openresty//nginx/logs' || mkdir -p '/opt/openresty//nginx/logs' gmake[2]: Leaving directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10' gmake[1]: Leaving directory '/Users/admin/GitHub/ngx_openresty/ngx_openresty-1.7.10.2rc0/build/nginx-1.7.10' Air:ngx_openresty-1.7.10.2rc0 admin$
这样最后就把 `openresty` 安装到 `/opt/openresty/` 目录下了,目录结构如下所示:
Air:ngx_openresty-1.7.10.2rc0 admin$ cd /opt/openresty/
Air:openresty admin$ ls
bin luajit lualib nginx
Air:openresty admin$ tree
.
├── bin
│ └── resty
├── luajit
│ ├── bin
│ │ └── luajit-2.1.0-alpha
│ ├── include
│ │ └── luajit-2.1
│ │ ├── lauxlib.h
│ │ ├── lua.h
│ │ ├── lua.hpp
│ │ ├── luaconf.h
│ │ ├── luajit.h
│ │ └── lualib.h
│ ├── lib
│ │ ├── libluajit-5.1.2.1.0.dylib
│ │ ├── libluajit-5.1.2.dylib -> libluajit-5.1.2.1.0.dylib
│ │ ├── libluajit-5.1.a
│ │ ├── libluajit-5.1.dylib -> libluajit-5.1.2.1.0.dylib
│ │ ├── lua
│ │ │ └── 5.1
│ │ └── pkgconfig
│ │ └── luajit.pc
│ └── share
│ ├── lua
│ │ └── 5.1
│ ├── luajit-2.1.0-alpha
│ │ └── jit
│ │ ├── bc.lua
│ │ ├── bcsave.lua
│ │ ├── dis_arm.lua
│ │ ├── dis_mips.lua
│ │ ├── dis_mipsel.lua
│ │ ├── dis_ppc.lua
│ │ ├── dis_x64.lua
│ │ ├── dis_x86.lua
│ │ ├── dump.lua
│ │ ├── p.lua
│ │ ├── v.lua
│ │ ├── vmdef.lua
│ │ └── zone.lua
│ └── man
│ └── man1
│ └── luajit.1
├── lualib
│ ├── cjson.so
│ ├── rds
│ │ └── parser.so
│ ├── redis
│ │ └── parser.so
│ └── resty
│ ├── aes.lua
│ ├── core
│ │ ├── base.lua
│ │ ├── base64.lua
│ │ ├── ctx.lua
│ │ ├── exit.lua
│ │ ├── hash.lua
│ │ ├── misc.lua
│ │ ├── regex.lua
│ │ ├── request.lua
│ │ ├── response.lua
│ │ ├── shdict.lua
│ │ ├── time.lua
│ │ ├── uri.lua
│ │ ├── var.lua
│ │ └── worker.lua
│ ├── core.lua
│ ├── dns
│ │ └── resolver.lua
│ ├── lock.lua
│ ├── lrucache
│ │ └── pureffi.lua
│ ├── lrucache.lua
│ ├── md5.lua
│ ├── memcached.lua
│ ├── mysql.lua
│ ├── random.lua
│ ├── redis.lua
│ ├── sha.lua
│ ├── sha1.lua
│ ├── sha224.lua
│ ├── sha256.lua
│ ├── sha384.lua
│ ├── sha512.lua
│ ├── string.lua
│ ├── upload.lua
│ ├── upstream
│ │ └── healthcheck.lua
│ └── websocket
│ ├── client.lua
│ ├── protocol.lua
│ └── server.lua
└── nginx
├── conf
│ ├── fastcgi.conf
│ ├── fastcgi.conf.default
│ ├── fastcgi_params
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf
│ ├── nginx.conf.default
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── html
│ ├── 50x.html
│ └── index.html
├── logs
└── sbin
└── nginx
30 directories, 85 files
Air:openresty admin$
可执行文件是 `./nginx/sbin/nginx`,试着用 `sudo` 启动一下,它会自动调用配置文件 `/conf/nginx.conf`。
Air:openresty admin$ sudo ./nginx/sbin/nginx
Password:
Air:openresty admin$ ps -ef |grep nginx
0 48780 1 0 1:38下午 ?? 0:00.00 nginx: master process ./nginx/sbin/nginx
-2 48781 48780 0 1:38下午 ?? 0:00.00 nginx: worker process
501 48798 389 0 1:38下午 ttys001 0:00.00 grep nginx
Air:openresty admin$
很好,现在我们已经安装了好了 `openresty`,接下来就要安装 `sockproc` 和 `codea-scm` 了。
## 下载编译运行 sockproc守护进程
`sockproc` 是一个守护进程,用来接受转发数据
Air:GitHub admin$ git clone http://github.com/juce/sockproc
Cloning into 'sockproc'...
remote: Counting objects: 76, done.
remote: Total 76 (delta 0), reused 0 (delta 0), pack-reused 76
Unpacking objects: 100% (76/76), done.
Checking connectivity... done.
Air:GitHub admin$ cd sockproc/
Air:sockproc admin$ ls
LICENSE Makefile README.md sockproc.c tests.sh
Air:sockproc admin$
编译:
Air:sockproc admin$ gmake
gcc -Wall -Werror -o sockproc sockproc.c
Air:sockproc admin$ ls
LICENSE Makefile README.md sockproc sockproc.c tests.sh
Air:sockproc admin$
运行:
Air:sockproc admin$ sudo -u nobody ./sockproc /tmp/hello.sock
Password:
Air:sockproc admin$ ps -ef |grep sockproc
-2 48884 1 0 1:43下午 ?? 0:00.00 ./sockproc /tmp/hello.sock
501 48893 389 0 1:43下午 ttys001 0:00.00 grep sockproc
Air:sockproc admin$
## 下载安装运行 codea-scm web 服务
Air:GitHub admin$ git clone https://bitbucket.org/juce/codea-scm
Cloning into 'codea-scm'...
remote: Counting objects: 618, done.
remote: Compressing objects: 100% (569/569), done.
remote: Total 618 (delta 335), reused 0 (delta 0)
Receiving objects: 100% (618/618), 5.19 MiB | 701.00 KiB/s, done.
Resolving deltas: 100% (335/335), done.
Checking connectivity... done.
Air:GitHub admin$ cd codea-scm/
Air:codea-scm admin$ ls
Makefile app etc openresty.sh tools
README.md conf makekey.sh scripts web
Air:codea-scm admin$
安装一下,会安装到 `/opt/codea-scm/`:
Air:codea-scm admin$ sudo gmake
[ -f /opt/openresty/nginx/conf/nginx.conf ] || sudo cp ./conf/nginx.conf /opt/openresty/nginx/conf/
sudo mkdir -p /opt/openresty/nginx/conf/conf.d && sudo chown `whoami` /opt/openresty/nginx/conf/conf.d
[ -L /opt/openresty/nginx/conf/conf.d/"codea-scm".conf ] || \
sudo ln -s `pwd`/conf/conf.d/"codea-scm".conf /opt/openresty/nginx/conf/conf.d/"codea-scm".conf
[ -L /opt/"codea-scm" ] || sudo ln -s `pwd` /opt/"codea-scm"
[ -f ./etc/config.lua ] || cp ./etc/config.lua.sample ./etc/config.lua
Air:codea-scm admin$
可以查看一下 `codea-scm` 的目录结构:
Air:codea-scm-app admin$ cd /opt/codea-scm
Air:codea-scm admin$ tree
.
├── Makefile
├── README.md
├── app
│ ├── commit_and_push.lua
│ ├── get_log.lua
│ ├── get_status.lua
│ ├── git.lua
│ ├── init.lua
│ ├── installer.lua
│ ├── keymaker.lua
│ ├── pull.lua
│ ├── serializer.lua
│ ├── shell.lua
│ ├── sock.lua
│ ├── user.lua
│ ├── util.lua
│ ├── uuid.lua
│ └── whoami.lua
├── conf
│ ├── conf.d
│ │ ├── codea-scm.conf
│ │ └── codea-scm.ssl.conf
│ └── nginx.conf
├── etc
│ ├── config.lua
│ └── config.lua.sample
├── makekey.sh
├── openresty.sh
├── scripts
│ ├── git-ssh
│ └── pipe-to-temp
├── tools
│ └── etc
│ └── logrotate.d
│ └── openresty
└── web
├── index.html
├── screen1.png
├── screen2.png
├── small1.png
└── small2.png
9 directories, 32 files
Air:codea-scm admin$
检查 `/opt/openresty/conf/nginx.conf` 有没有被替换,没有的话就手动换一下:
Air:codea-scm admin$ sudo cp ./conf/nginx.conf /opt/openresty/nginx/conf/nginx.conf
Air:codea-scm admin$
运行报错:
Air:codea-scm admin$ sudo ./openresty.sh start
nginx: [error] init_by_lua_file error: /opt/codea-scm/etc/config.lua:8: '}' expected (to close '{' at line 1) near 'installer_git_ref'
stack traceback:
[C]: in function 'dofile'
/opt/codea-scm/app/init.lua:7: in main chunk
Air:codea-scm admin$
修改一下
Air:codea-scm admin$ sudo vi /opt/codea-scm/etc/config.lua
把原来的:
installer_git_remote = 'https://bitbucket.org/juce/codea-scm-app.git'
installer_git_ref = 'v1.2',}
改为:
installer_git_remote = 'https://bitbucket.org/juce/codea-scm-app.git',
installer_git_ref = 'v1.2'}
再次运行:
Air:codea-scm admin$ cd /opt/codea-scm/
Air:codea-scm admin$ ls
Makefile app etc openresty.sh tools
README.md conf makekey.sh scripts web
Air:codea-scm admin$ ./openresty.sh start
nginx: [alert] could not open error log file: open() "/opt/openresty//nginx/logs/error.log" failed (13: Permission denied)
2015/06/22 13:54:57 [emerg] 49106#0: open() "/opt/openresty//nginx/logs/access.log" failed (13: Permission denied)
Air:codea-scm admin$ sudo ./openresty.sh start
Password:
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] still could not bind()
Air:codea-scm admin$ sudo ./openresty.sh restart
Air:codea-scm admin$ sudo ./openresty.sh stop
Air:codea-scm admin$ sudo ./openresty.sh start
Air:codea-scm admin$
很好,到现在为止就已经把这个 `web service` 服务部署到你自己的电脑上了。
可以用浏览器打开看看:`http://localhost`
如果能够看到 `codea-scm` 的帮助页面,说明已经安装部署成功。
## 在 iPad 上安装 codea-scm-app
最后就是在 `iPad` 上安装 `codea-scm-app`,比较简单,打开 `codea`,新建一个项目,把下述代码拷贝到 `main` 标签页,运行,就会自动从网络安装:
--# Main
-- codea-scm bootstrap installer
function setup()
displayMode(STANDARD)
print("Installing codea-scm ...")
http.request("https://codea-scm.aws.mapote.com/install",
function (data, status, headers)
assert(loadstring(data))()
print("Installation complete. SUCCESS!")
print("Launch the project again to start using codea-scm.")
tween.delay(2.0, close)
end,
function (err)
print("PROBLEM downloading: " .. err)
end)
end
function draw()
background(37, 38, 50, 255)
end
安装好之后就可以在 `iPad` 上进行操作,按照帮助页面上的提示进行项目设置,你在 `codea` 中的项目代码可以快速同步到 `github`、`bitbucket`、`oschina` 等服务器了。
使用本地 `web service` 的一个好处就是速度超快,以前用别人提供的同步一个几百K的项目就要等半天,本地的几秒钟就好了。
[点这里可以直接浏览codea-scm-app的全部代码](https://codea-scm.aws.mapote.com/install)
另外也可以通过 `git` 从 `bitbucket.org` 克隆,命令如下:
Air:GitHub admin$ git clone https://bitbucket.org/juce/codea-scm-app
Cloning into 'codea-scm-app'...
remote: Counting objects: 383, done.
remote: Compressing objects: 100% (293/293), done.
remote: Total 383 (delta 162), reused 0 (delta 0)
Receiving objects: 100% (383/383), 85.12 KiB | 61.00 KiB/s, done.
Resolving deltas: 100% (162/162), done.
Checking connectivity... done.
Air:GitHub admin$ cd codea-scm-app/
Air:codea-scm-app admin$ ls
Icon.png Info.plist tabs
Air:codea-scm-app admin$ tree
.
├── Icon.png
├── Info.plist
└── tabs
├── Button.lua
├── Diff.lua
├── Main.lua
├── Panel.lua
├── Readme.lua
├── Serializer.lua
└── Status.lua
1 directory, 9 files
Air:codea-scm-app admin$
## 其他
几个相关地址:
https://github.com/agentzh/ngx_openresty
https://github.com/juce/sockproc
https://bitbucket.org/juce/codea-scm
https://bitbucket.org/juce/codea-scm-app
版本:2015-06-22
作者:FreeBlues
链接:http://my.oschina.net/freeblues/blog/469393
全文完--