{"id":13776388,"url":"https://github.com/upyun/slardar","last_synced_at":"2026-01-14T12:58:13.479Z","repository":{"id":46703683,"uuid":"65959021","full_name":"upyun/slardar","owner":"upyun","description":"Updating your upstream list and run lua scripts without reloading Nginx.","archived":true,"fork":false,"pushed_at":"2019-11-11T02:33:50.000Z","size":142,"stargazers_count":497,"open_issues_count":13,"forks_count":112,"subscribers_count":41,"default_branch":"master","last_synced_at":"2025-05-27T08:55:00.700Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/upyun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-18T02:37:45.000Z","updated_at":"2025-05-21T16:03:45.000Z","dependencies_parsed_at":"2022-09-04T01:51:27.506Z","dependency_job_id":null,"html_url":"https://github.com/upyun/slardar","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/upyun/slardar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upyun%2Fslardar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upyun%2Fslardar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upyun%2Fslardar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upyun%2Fslardar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/upyun","download_url":"https://codeload.github.com/upyun/slardar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upyun%2Fslardar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:00:24.535Z","updated_at":"2026-01-14T12:58:13.465Z","avatar_url":"https://github.com/upyun.png","language":"Lua","funding_links":[],"categories":["Libraries","Lua"],"sub_categories":[],"readme":"Slardar\n=======\n\nUpdating your upstream list and run lua scripts without reloading Nginx.\n\nTable of Contents\n=================\n\n* [Description](#description)\n* [Installation](#installation)\n\t* [Install From Source](#install-from-source)\n\t* [Build Docker Image](#build-docker-image)\n* [Configuration](#configuration)\n\t* [Lua Configuration](#lua-configuration)\n\t* [Consul Configuration](#consul-configuration)\n\t* [Nginx Configuration](#nginx-configuration)\n* [Interface](#interface)\n\t* [Get Slardar Status](#get-slardar-status)\n\t* [Get Scripts Status](#get-scripts-status)\n\t* [Update Upstream](#update-upstream)\n\t* [Delete Upstream](#delete-upstream)\n\t* [Post Lua Scripts or Modules](#post-lua-scripts-or-modules)\n\t* [Load Lua Scripts or Modules](#load-lua-scripts-or-modules)\n* [Example](#example)\n* [Run Test](#run-test)\n* [Contribution](#contribution)\n* [Copyright \u0026 License](#copyright--license)\n\nDescription\n===========\n\nSlardar is a HTTP load balancer based on [Nginx](http://nginx.org/), [lua-nginx-module](https://github.com/openresty/lua-nginx-module) and [stream-lua-nginx-module](https://github.com/openresty/stream-lua-nginx-module), by which you can update your upstream list and run lua scripts without reloading Nginx.\n\nThis bundle is maintained by UPYUN(又拍云) Inc.\n\nBecause most of the nginx modules are developed by the bundle maintainers, it can ensure\nthat all these modules are played well together.\n\nThe bundled software components are copyrighted by the respective copyright holders.\n\n\n\nInstallation\n============\n\nInstall from source\n-------------------\n\n\n**1. Clone the repository**\n\n\n```\ngit clone https://github.com/upyun/slardar.git\n```\n\n**2. Set installation directory (optional)**\n\nBy default, Slardar will be installed to `/usr/local/slardar`, and you should ensure that you have write permission to the directory.\n\nIf you want to change to another location, you should export the `PREFIX` environment variable to the path you want to install. \n\n```\nexport PREFIX=/path/to/your/dir\n```\n\n**3. Configure**\n\n```\ncd slardar\nmake configure\n```\n\n\n**4. Build and Install**\n\n```\nmake\nmake install\n```\n\n**5. Run**\n\n```\n/usr/local/slardar/nginx/sbin/nginx\n```\n\nor you have changed installation directory in step 2:\n\n```\n$PREFIX/nginx/sbin/nginx\n```\n\n[Back to TOC](#table-of-contents)\n\n\nBuild Docker Image\n------------------\n\n**1. Clone the repository**\n\n```\ngit clone https://github.com/upyun/slardar.git\n```\n\n**2. Build docker image**\n\n```\ncd slardar\ndocker build -t slardar .\n```\n\n**3. Run**\n\n```\ndocker run -d --net=host --name slardar slardar\n```\n\n\n\n[Back to TOC](#table-of-contents)\n\n\nConfiguration\n=============\n\nLua configuration\n-----------------\n\nContiguration file is in `lua` format and located at `/usr/local/slardar/nginx/app/etc/config.lua` or `$PREFIX/nginx/app/etc/config.lua` if you changed your installation location.\n\nExample configuration and the comments are listed as follows.\n\n```\nlocal _M = {}\n\n_M.global = {\n\n    -- checkups send heartbeats to backend servers every 5s.\n    checkup_timer_interval = 5,\n    \n    -- checkups timer key will expire in every 60s.\n    -- In most cases, you don't need to change this value.\n    checkup_timer_overtime = 60,\n    \n    -- checkups will sent heartbeat to servers by default.\n    default_heartbeat_enable = true,\n\n\t-- create upstream syncer for each worker.\n\t-- If set to false, dynamic upstream will not work properly.\n\t-- This switch is used for compatibility purpose only in checkups,\n\t-- don't change this in slardar.\n    checkup_shd_sync_enable = true,\n    \n    -- sync upstream list from shared memory every 1s\n    shd_config_timer_interval = 1,\n}\n\n_M.consul = {\n\t-- connect to consul will timeout in 5s.\n    timeout = 5,\n\n    -- disable checkups heartbeat to consul.\n    enable = false,\n\n\t-- consul k/v prefix.\n\t-- Slardar will read upstream list from config/slardar/upstreams.\n\t-- For more information, please refer to 'Consul configuration'. \n    config_key_prefix = \"config/slardar/\",\n    \n    -- positive cache ttl(in seconds) for dynamic configurations from consul.\n    config_positive_ttl = 10,\n    \n    -- negative cache ttl(in seconds) for dynamic configurations from consul.\n    config_negative_ttl = 5,\n    \n    -- cache dynamic configurations from consul.\n    config_cache_enable = true,\n\n    cluster = {\n        {\n            servers = {\n                -- change these to your own consul http addresses\n                { host = \"10.0.5.108\", port = 8500 },\n                { host = \"10.0.5.109\", port = 8500 },\n            },\n        },\n    },\n}\n\nreturn _M\n```\n\nConsul configuration\n--------------------\n\nSlardar will read persisted configurations, upstream list and lua code from consul on startup. Consul configuration can be customized by setting k/v with the prefix `config_key_prefix`(e.g.`config/slardar/`) configured in `config.lua`. You should ensure that all values behind `config_key_prefix` are in valid `json` format.\n\nAn example Consul keys and their corresponding values are listed as follows,\n\n| consul k/v key \t\t| value     |\n|----------------------|-----------|\n| lua/modules.abc \t\t| `local f = {version=10} return f` |\n| lua/script.test  \t\t| `local f = require(\"modules.abc\") print(f.version)` |\n| upstreams/node-dev.example   | `{\"enable\": true, \"servers\": [{\"host\": \"127.0.0.1\",\"port\": 8001,\"weight\": 1,\"max_fails\": 6,\"fail_timeout\": 30}]}` |\n| myargs \t\t\t\t| `{\"arg0\": 0,\"arg1\": 1}` |\n\nFor the above example, Slardar will load `modules.abc`, `script.test` as lua code and `node-dev.example` as upstream on startup.\n\nYou can set `\"enable\": false`(default is `true`) in your upstream configuration to disable periodical heartbeats to servers by [checkups](https://github.com/upyun/lua-resty-checkups).\n\nWhen Slardar is running, you can use `slardar.myargs.arg0` to get `arg0` and `slardar.myargs.arg1` to get `arg1`. The config will be cached for `config_positive_ttl` seconds. That is to say, when you change the value of `myargs` in consul, it will take effect in `config_positive_ttl` seconds.\n\nDiffers to configurations like `myargs`, keys behind `lua` and `upstreams` will not be cached and you can only update them by Slardar's [HTTP interfaces](#interface).\n\nIf you don't need any preload scripts or upstreams, just leave nothing behind `config_key_prefix` or an empty value.\n\n\nNginx configuration\n-------------------\n\nSlardar is 100% compatible with nginx, so you can change nginx configuration files in the same way you do for Nginx.\n\nConfiguration files for Nginx are located at `/usr/local/slardar/nginx/conf` or `$PREFIX/nginx/conf` if you changed your installation location.\n\n[Back to TOC](#table-of-contents)\n\n\nInterface\n=========\n\nGet Slardar status\n------------------\n\n```\nGET 127.0.0.1:1995/status\n```\n\nSlardar will return its status in json format.\n\n```\n{\n\t-- checkups heartbeat timer is alive.\n\t\"checkup_timer_alive\": true,\n\t\n\t-- last heartbeat time\n\t\"last_check_time\": \"2016-08-12 13:09:40\",\n\t\n\t-- slardar version\n\t\"slardar_version\": \"1.0.0\",\n\t\n\t-- start or reload time.\n\t\"start_time\": \"2016-08-12 13:09:40\",\n\t\n\t-- lua config file version, you can set 'conf_hash = \"your-version\"' in your lua config file.\n\t\"conf_hash\": null,\n\t\n\t-- every time you update upstream, this value will increase.\n\t\"shd_config_version\": 0,\n\t\n\t-- status for consul cluster\n\t\"cls:consul\": [\n\t\t[\n\t\t\t{\n\t\t\t\t\"server\": \"consul:10.0.5.108:8500\",\n\t\t\t\t\"weight\": 1,\n\t\t\t\t\"status\": \"unchecked\"\n\t\t\t}\n\t\t]\n\t],\n\t\n\t-- status for node-dev cluster\n\t\"cls:node-dev\": [\n\t\t[\n\t\t\t{\n\t\t\t\t\"server\": \"node-dev:10.0.5.108:8001\",\n\t\t\t\t\"weight\": 1,\n\t\t\t\t\"fail_timeout\": 30,\n\t\t\t\t\"status\": \"ok\",\n\t\t\t\t\"max_fails\": 6\n\t\t\t}\n\t\t]\n\t]\n}\n```\n\nGet scripts status\n---------------------------\n\n```\nGET 127.0.0.1:1995/lua\n```\n\nSlardar will return loaded lua scripts and modules in json format.\n\n```\n{\n\t-- every time you update lua scripts, this value will increase.\n\t\"version\": 0,\n\t\"modules\": [\n\t\t{\n\t\t\t-- module load time\n\t\t\t\"time\": \"2016-08-12 13:09:40\",\n\t\t\t\n\t\t\t-- md5 value of module file\n\t\t\t\"version\": \"aed4a968ef14f8db732e3602c34dc37a\",\n\t\t\t\n\t\t\t-- module name\n\t\t\t\"name\": \"modules.test\"\n\t\t},\n\t\t{\n\t\t\t\"time\": \"2016-08-12 13:09:40\",\n\t\t\t\"version\": \"302f9bf40fcd3734cab120b97f18edf3\",\n\t\t\t\"name\": \"script.test\"\n\t\t}\n\t]\n}\n```\n\nUpdate upstream\n---------------\n\n```\nPOST 127.0.0.1:1995/upstream/name\n```\n\nThe request body is your new upstream list in json format. For example,\n\n```\ncurl 127.0.0.1:1995/upstream/node-dev.example.com -d \\\n{\"servers\":[{\"host\":\"192.168.1.1\", \"port\": 8080}, {\"host\":\"192.168.1.2\", \"port\": 8080}]}\n```\n\nThe example above will add two servers into upstream named `node-dev.example.com`.\n\nDelete upstream\n---------------\n\n```\nDELETE 127.0.0.1:1995/upstream/name\n```\n\nFor example,\n\n```\ncurl -XDELETE 127.0.0.1:1995/upstream/node-dev.example.com\n```\n\nThe example above will delete the upstream named `node-dev.example.com`.\n\nPost lua scripts or modules\n---------------------------\n\n```\nPOST 127.0.0.1:1995/lua/scripts.name\n```\n\nor post a lua module,\n\n```\nPOST 127.0.0.1:1995/lua/modules.name\n```\n\nThe request body is the lua code of your script or module. For example,\n\n```\ncurl 127.0.0.1:1995/lua/scripts.test -d 'return slardar.exit(errno.EXIT_TRY_CODE)'\ncurl 127.0.0.1:1995/lua/modules.test -d 'local f = {version=10} return f'\n```\n\nLoad lua scripts or modules\n---------------------------\n\n```\nPUT 127.0.0.1:1995/lua/scripts.name\n```\nor load a lua module,\n\n```\nPUT 127.0.0.1:1995/lua/modules.name\n```\nBefore loading lua, you must [post](post-lua-scripts-or-modules) the lua script or module to Slardar.\n\nFor example,\n\n```\ncurl -XPUT 127.0.0.1:1995/lua/scripts.test\ncurl -XPUT 127.0.0.1:1995/lua/modules.test\n```\n\n\n\n[Back to TOC](#table-of-contents)\n\n\nExample\n=======\n\nGet from upstream which does not exist will result in 502. \n\n```\n$ curl 127.0.0.1:8080/ -H \"Host: node-dev.example.com\"\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003e502 Bad Gateway\u003c/title\u003e\u003c/head\u003e\n\u003cbody bgcolor=\"white\"\u003e\n\u003ccenter\u003e\u003ch1\u003e502 Bad Gateway\u003c/h1\u003e\u003c/center\u003e\n\u003chr\u003e\u003ccenter\u003eslardar/1.0\u003c/center\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nAdd one server to `node-dev.example.com`\n\n```\n$ curl 127.0.0.1:1995/upstream/node-dev.example.com -d '{\"servers\":[{\"host\":\"127.0.0.1\", \"port\": 4000}]}'\n{\"status\":200}\n```\n\nNow, we can get the correct result.\n\n```\n$ curl 127.0.0.1:8080/ -H \"Host: node-dev.example.com\"\nhello world\n```\n\nLoad a lua script\n\n```\n$ curl 127.0.0.1:1995/lua/script.node-dev.example.com -d 'if ngx.req.get_method() == \"DELETE\" then return ngx.exit(403) end'\n\"ok\"\n$ curl -XPUT 127.0.0.1:1995/lua/script.node-dev.example.com\n```\n\nThe script is taking effect.\n\n```\n$ curl -XDELETE 127.0.0.1:8080/ -H \"Host: node-dev.example.com\"\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003e403 Forbidden\u003c/title\u003e\u003c/head\u003e\n\u003cbody bgcolor=\"white\"\u003e\n\u003ccenter\u003e\u003ch1\u003e403 Forbidden\u003c/h1\u003e\u003c/center\u003e\n\u003chr\u003e\u003ccenter\u003eslardar/1.0\u003c/center\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n[Back to TOC](#table-of-contents)\n\n\nRun Test\n========\n\nThis bundle contains only tests for Slardar, the bundled components are tested in their own project.\n\nYou can run tests for Slardar by the following commands.\n\n```\ndocker run -d --net=host consul agent -dev -bind=127.0.0.1\nmake dev\nmake test\n```\n\n\n[Back to TOC](#table-of-contents)\n\n\nContribution\n============================\n\nYou're very welcome to report issues on [GitHub](https://github.com/upyun/slardar/issues).\n\nPRs are more than welcome. Just fork, create a feature branch, and open a PR. We love PRs. :)\n\n[Back to TOC](#table-of-contents)\n\n\nCopyright \u0026 License\n===================\n\nThe bundle itself is licensed under the 2-clause BSD license.\n\nCopyright (c) 2016, UPYUN(又拍云) Inc.\n\nThis module is licensed under the terms of the BSD license.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n[Back to TOC](#table-of-contents)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupyun%2Fslardar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fupyun%2Fslardar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupyun%2Fslardar/lists"}