A awesome npm cache/proxy server build in go
Go to file
ODIT Renovate Bot 65b3bc4736
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/testpr Pipeline failed
chore(deps): update module github.com/gin-contrib/zap to v0.2.0
2023-12-08 02:18:54 +00:00
.argo Added affinity for amd64 2023-11-07 19:36:04 +01:00
.woodpecker feat(ci): Build cache 2023-11-24 11:35:35 +01:00
cli fix: update org name 2019-05-07 11:05:12 +03:00
proxy fix: update org name 2019-05-07 11:05:12 +03:00
testing Updated package url 2023-02-25 18:03:06 +01:00
.dockerignore fix: remove cli from dockerignore, fix build 2019-04-18 15:18:37 +03:00
.gitignore Ignore build 2023-02-25 17:40:31 +01:00
docker-compose.yaml Default compose to image 2023-02-24 21:29:52 +01:00
Dockerfile chore(deps): update registry.odit.services/hub/library/alpine docker tag to v3.19 2023-12-08 01:47:26 +00:00
go.mod chore(deps): update module github.com/gin-contrib/zap to v0.2.0 2023-12-08 02:18:54 +00:00
go.sum Update module go.uber.org/zap to v1.26.0 2023-09-14 21:12:57 +00:00
license feat: add license 2019-04-16 16:02:42 +03:00
logo.png docs: refresh readme 2019-04-22 22:34:00 +03:00
main.go fix: update org name 2019-05-07 11:05:12 +03:00
Makefile feat: add cli flags 2019-04-21 19:01:49 +03:00
readme.md fix: update org name 2019-05-07 11:05:12 +03:00
renovate.json Switched renovate to automerge 2023-02-25 18:05:59 +01:00

npm-cache-proxy

Current Release CI Build Licence


Introduction

Performance

NCP is a tiny but very fast caching proxy written in Go. It uses Redis for data storage, which in combination with the speed of Go makes it incredibly fast. NCP is well-optimized and can be run on almost any platform, so if you have a Raspberry Pi, you can install NCP as your local cache there.

Modularity

NCP is modular. Now it has only one database adapter which is Redis. If you need support for any other database, feel free to open an issue or implement it on your own and then open a pull request (bonus points).

💡 Simplicity

NCP is very simple. It just proxies requests to an upstream registry, caches response and returns cached response for next requests to the same package. Cached data are stored in Redis with an original request URL as a key.


Installation

NCP binaries for different paltforms can be downloaded can be downloaded on the Releases page. Also, Docker image is provided on Docker Hub.

💫 Quick Start

The quickies way to get started with NCP is to use Docker.

# run proxy inside of docker container in background
docker run -e REDIS_ADDRESS=host.docker.internal:6379 -p 8080:8080 -it -d pkgems/npm-cache-proxy

# configure npm to use caching proxy as registry
npm config set registry http://localhost:8080

CLI

NCP provides command line interface for interaction with a cached data.

Options
Options Env Default Description
--listen <address> LISTEN_ADDRESS locahost:8080 Address to listen
--upstream <address> UPSTREAM_ADDRESS https://registry.npmjs.org Upstream registry address
--silent <address> SILENT 0 Disable logs
--cache-limit <count> CACHE_LIMIT - Cached packages count limit
--cache-ttl <timeout> CACHE_TTL 3600 Cache expiration timeout in seconds
--redis-address <address> REDIS_ADDRESS http://localhost:6379 Redis address
--redis-database <database> REDIS_DATABASE 0 Redis database
--redis-password <password> REDIS_PASSWORD - Redis password
--redis-prefix <prefix> REDIS_PREFIX ncp- Redis keys prefix

ncp

Start NCP server.

ncp list

List cached url paths.

ncp purge

Purge cached url paths.


Benchmark

Benchmark is run on Macbook Pro 15″ 2017, Intel Core i7-7700HQ.

1 1 process

# GOMAXPROCS=1 ncp --silent

$ go-wrk -c 100 -d 6 http://localhost:8080/tiny-tarball
Running 6s test @ http://localhost:8080/tiny-tarball
  100 goroutine(s) running concurrently

70755 requests in 5.998378587s, 91.16MB read

Requests/sec:		11795.69
Transfer/sec:		15.20MB
Avg Req Time:		8.477674ms
Fastest Request:	947.743µs
Slowest Request:	815.787409ms
Number of Errors:	0

♾ unlimited processes

# ncp --silent

$ go-wrk -c 100 -d 6 http://localhost:8080/tiny-tarball
Running 6s test @ http://localhost:8080/tiny-tarball
  100 goroutine(s) running concurrently

115674 requests in 5.98485984s, 149.04MB read

Requests/sec:		19327.77
Transfer/sec:		24.90MB
Avg Req Time:		5.173902ms
Fastest Request:	273.015µs
Slowest Request:	34.777963ms
Number of Errors:	0

Programmatic Usage

NCP provides proxy go package that can be used programmatically. Docs are available on godoc.org.

🤖 Example

package main

import (
	"net/http"
	"time"

	npmproxy "github.com/pkgems/npm-cache-proxy/proxy"
	"github.com/go-redis/redis"
)

func main() {
	// create proxy
	proxy := npmproxy.Proxy{
		// use redis as database
		Database: npmproxy.DatabaseRedis{
			// see github.com/go-redis/redis
			Client: redis.NewClient(&redis.Options{
				Addr:     "localhost:6379",
			}),
		},

		// reuse connections
		HttpClient: &http.Client{},
	}

	// create and start server
	proxy.Server(npmproxy.ServerOptions{
		ListenAddress: "localhost:8080",

		// allow fetching options dynamically on each request
		GetOptions: func() (npmproxy.Options, error) {
			return npmproxy.Options{
				DatabasePrefix:     "ncp-",
				DatabaseExpiration: 1 * time.Hour,
				UpstreamAddress:    "https://registry.npmjs.org",
			}, nil
		},
	}).ListenAndServe()
}

License

MIT