From aea3b9ddaf0595875316303018caa0672bed1a7c Mon Sep 17 00:00:00 2001 From: Juan Picado Date: Tue, 14 Jun 2022 18:33:27 +0200 Subject: [PATCH] add docker examples to use plugins with docker files (#3217) * add docker examples to use plugins at docker * Update Dockerfile * chore: add v6 examples --- .eslintignore | 1 + docker-examples/v5/README.md | 9 + .../docker-build-install-plugin/Dockerfile | 25 ++ .../docker-build-install-plugin/README.md | 46 ++++ .../docker-build-install-plugin/docker.yaml | 197 ++++++++++++++++ .../v5/plugins/docker-local-plugin/Dockerfile | 26 +++ .../v5/plugins/docker-local-plugin/README.md | 42 ++++ .../plugins/docker-local-plugin/docker.yaml | 199 ++++++++++++++++ .../docker-local-plugin/plugins/.eslintrc | 8 + .../verdaccio-docker-memory/lib/index.js | 17 ++ .../lib/local-memory.js | 96 ++++++++ .../lib/memory-handler.js | 182 +++++++++++++++ .../verdaccio-docker-memory/package.json | 19 ++ docker-examples/v6/README.md | 22 +- .../docker-build-install-plugin/Dockerfile | 25 ++ .../docker-build-install-plugin/README.md | 46 ++++ .../docker-build-install-plugin/docker.yaml | 197 ++++++++++++++++ .../v6/plugins/docker-local-plugin/Dockerfile | 26 +++ .../v6/plugins/docker-local-plugin/README.md | 42 ++++ .../plugins/docker-local-plugin/docker.yaml | 199 ++++++++++++++++ .../docker-local-plugin/plugins/.eslintrc | 8 + .../verdaccio-docker-memory/lib/index.js | 22 ++ .../lib/local-memory.js | 141 ++++++++++++ .../lib/memory-handler.js | 214 ++++++++++++++++++ .../verdaccio-docker-memory/lib/utils.js | 16 ++ .../verdaccio-docker-memory/package.json | 56 +++++ .../v6/{ => proxy}/apache-verdaccio/README.md | 0 .../apache-verdaccio/apache_proxy/Dockerfile | 0 .../apache_proxy/conf/000-default.conf | 0 .../apache_proxy/conf/env.load | 0 .../apache-verdaccio/docker-compose.yaml | 0 .../https-portal-example/README.md | 0 .../https-portal-example/conf/config.yaml | 0 .../https-portal-example/conf/htpasswd | 0 .../https-portal-example/docker-compose.yml | 0 .../storage/@scope/example/example-1.0.0.tgz | Bin .../storage/@scope/example/package.json | 0 .../storage/jquery/package.json | 0 website/docs/programmatically.md | 2 +- 39 files changed, 1878 insertions(+), 5 deletions(-) create mode 100644 docker-examples/v5/plugins/docker-build-install-plugin/Dockerfile create mode 100644 docker-examples/v5/plugins/docker-build-install-plugin/README.md create mode 100644 docker-examples/v5/plugins/docker-build-install-plugin/docker.yaml create mode 100644 docker-examples/v5/plugins/docker-local-plugin/Dockerfile create mode 100644 docker-examples/v5/plugins/docker-local-plugin/README.md create mode 100644 docker-examples/v5/plugins/docker-local-plugin/docker.yaml create mode 100644 docker-examples/v5/plugins/docker-local-plugin/plugins/.eslintrc create mode 100644 docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js create mode 100644 docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js create mode 100644 docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js create mode 100644 docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json create mode 100644 docker-examples/v6/plugins/docker-build-install-plugin/Dockerfile create mode 100644 docker-examples/v6/plugins/docker-build-install-plugin/README.md create mode 100644 docker-examples/v6/plugins/docker-build-install-plugin/docker.yaml create mode 100644 docker-examples/v6/plugins/docker-local-plugin/Dockerfile create mode 100644 docker-examples/v6/plugins/docker-local-plugin/README.md create mode 100644 docker-examples/v6/plugins/docker-local-plugin/docker.yaml create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/.eslintrc create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/utils.js create mode 100644 docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json rename docker-examples/v6/{ => proxy}/apache-verdaccio/README.md (100%) rename docker-examples/v6/{ => proxy}/apache-verdaccio/apache_proxy/Dockerfile (100%) rename docker-examples/v6/{ => proxy}/apache-verdaccio/apache_proxy/conf/000-default.conf (100%) rename docker-examples/v6/{ => proxy}/apache-verdaccio/apache_proxy/conf/env.load (100%) rename docker-examples/v6/{ => proxy}/apache-verdaccio/docker-compose.yaml (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/README.md (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/conf/config.yaml (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/conf/htpasswd (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/docker-compose.yml (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/storage/@scope/example/example-1.0.0.tgz (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/storage/@scope/example/package.json (100%) rename docker-examples/v6/{ => proxy}/https-portal-example/storage/jquery/package.json (100%) diff --git a/.eslintignore b/.eslintignore index cd0aa034e..af1589dea 100644 --- a/.eslintignore +++ b/.eslintignore @@ -11,3 +11,4 @@ wiki/ dist/ docs/ test/functional/store/* +docker-examples/**/lib/**/*.js diff --git a/docker-examples/v5/README.md b/docker-examples/v5/README.md index 6938440b7..3bdd54cd7 100644 --- a/docker-examples/v5/README.md +++ b/docker-examples/v5/README.md @@ -3,3 +3,12 @@ > Before run examples, build the local image by running `pnpm docker`. - [Docker + Nginx + Verdaccio](reverse_proxy/nginx/README.md) + +## Using Plugins with Docker + +List of different approaches + +> Note these options could be improved, feel free to submit upgrades + +- [Docker + Install plugins from a registry](plugins/docker-build-install-plugin/README.md) +- [Docker + Install local plugin](plugins/docker-local-plugin/README.md) diff --git a/docker-examples/v5/plugins/docker-build-install-plugin/Dockerfile b/docker-examples/v5/plugins/docker-build-install-plugin/Dockerfile new file mode 100644 index 000000000..38c2eb238 --- /dev/null +++ b/docker-examples/v5/plugins/docker-build-install-plugin/Dockerfile @@ -0,0 +1,25 @@ +# Docs based on https://github.com/xlts-dev/verdaccio-prometheus-middleware#installation + +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +# Install the metrics middleware plugin +# npm docs +# --global-style https://docs.npmjs.com/cli/v7/commands/npm-install#global-style +# --no-bin-links https://docs.npmjs.com/cli/v7/commands/npm-install#bin-links +# --omit=optional +RUN mkdir -p /verdaccio/plugins \ + && cd /verdaccio/plugins \ + && npm install --global-style --no-bin-links --omit=optional verdaccio-auth-memory@latest + +# The final built image will be based on the standard Verdaccio docker image. +FROM verdaccio/verdaccio:5 + +# Copy the plugin files over from the 'builder' node image. +# The `$VERDACCIO_USER_UID` env variable is defined in the base `verdaccio/verdaccio` image. +# Refer to: https://github.com/verdaccio/verdaccio/blob/v5.2.0/Dockerfile#L32 +ADD docker.yaml /verdaccio/conf/config.yaml +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/node_modules/verdaccio-auth-memory \ + /verdaccio/plugins/verdaccio-auth-memory diff --git a/docker-examples/v5/plugins/docker-build-install-plugin/README.md b/docker-examples/v5/plugins/docker-build-install-plugin/README.md new file mode 100644 index 000000000..2f440cff4 --- /dev/null +++ b/docker-examples/v5/plugins/docker-build-install-plugin/README.md @@ -0,0 +1,46 @@ +# Installing a plugin with Docker build + +On this small tutorial (based on [`verdaccio-prometheus-middleware`](https://github.com/xlts-dev/verdaccio-prometheus-middleware) example) you will be able to use a published package in any random registry (npmjs by default) and use it withing a docker image without mapping need it. + +> Since verdaccio:5 uses `yarn@2` to run the application, this tutorial is a workaround but future prove since verdaccio 6 uses `pnpm` to build the docker image. + +There are two main steps to highlight: + +- `docker.yaml`: This is a copy of the original configuration file for docker and with small modifications to use the plugin [`verdaccio-auth-memory`](https://www.npmjs.com/package/verdaccio-auth-memory) and custom web title for demonstration. +- The `Dockerfile` take advance of the docker multi-stage build to install the plugin into the `verdaccio/plugins` folder withing the image, then we apply the right permissions `--chown=$VERDACCIO_USER_UID:root` so the plugin is recognized. + +## Run it + +Build this image. + +```bash +docker build -t verdaccio/verdaccio:local . +``` + +and to run it + +```bash +docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio:local +``` + +## Usage + +```dockerfile +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +RUN mkdir -p /verdaccio/plugins \ + && cd /verdaccio/plugins \ + && npm install --global-style --no-bin-links --omit=optional verdaccio-auth-memory@latest + +FROM verdaccio/verdaccio:5 + +# copy your modified config.yaml into the image +ADD docker.yaml /verdaccio/conf/config.yaml + +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/node_modules/verdaccio-auth-memory \ + /verdaccio/plugins/verdaccio-auth-memory + +``` diff --git a/docker-examples/v5/plugins/docker-build-install-plugin/docker.yaml b/docker-examples/v5/plugins/docker-build-install-plugin/docker.yaml new file mode 100644 index 000000000..3bc70a146 --- /dev/null +++ b/docker-examples/v5/plugins/docker-build-install-plugin/docker.yaml @@ -0,0 +1,197 @@ +# +# This is the default configuration file. It allows all users to do anything, +# please read carefully the documentation and best practices to +# improve security. +# +# Do not configure host and port under `listen` in this file +# as it will be ignored when using docker. +# see https://verdaccio.org/docs/en/docker#docker-and-custom-port-configuration +# +# Look here for more config file examples: +# https://github.com/verdaccio/verdaccio/tree/5.x/conf +# +# Read about the best practices +# https://verdaccio.org/docs/best + +# path to a directory with all packages +storage: /verdaccio/storage/data +# path to a directory with plugins to include +plugins: /verdaccio/plugins + +# https://verdaccio.org/docs/webui +web: + title: Verdaccio Publish Config Test + # comment out to disable gravatar support + # gravatar: false + # by default packages are ordercer ascendant (asc|desc) + # sort_packages: asc + # convert your UI to the dark side + # darkMode: true + # html_cache: true + # by default all features are displayed + # login: true + # showInfo: true + # showSettings: true + # In combination with darkMode you can force specific theme + # showThemeSwitch: true + # showFooter: true + # showSearch: true + # showRaw: true + # showDownloadTarball: true + # HTML tags injected after manifest + # scriptsBodyAfter: + # - '' + # HTML tags injected before ends + # metaScripts: + # - '' + # - '' + # - '' + # HTML tags injected first child at + # bodyBefore: + # - '
html before webpack scripts
' + # Public path for template manifest scripts (only manifest) + # publicPath: http://somedomain.org/ + +# https://verdaccio.org/docs/configuration#authentication +auth: + auth-memory: + users: + foo: + name: foo + password: s3cret + bar: + name: bar + password: s3cret + +# https://verdaccio.org/docs/configuration#uplinks +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + +# Learn how to protect your packages +# https://verdaccio.org/docs/protect-your-dependencies/ +# https://verdaccio.org/docs/configuration#packages +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + unpublish: $authenticated + proxy: npmjs + + '**': + # allow all users (including non-authenticated users) to read and + # publish all packages + # + # you can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # allow all known users to publish/publish packages + # (anyone can register by default, remember?) + publish: $authenticated + unpublish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: npmjs + +# To improve your security configuration and avoid dependency confusion +# consider removing the proxy property for private packages +# https://verdaccio.org/docs/best#remove-proxy-to-increase-security-at-private-packages + +# https://verdaccio.org/docs/configuration#server +# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. +# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout. +# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. +server: + keepAliveTimeout: 60 + +# https://verdaccio.org/docs/configuration#offline-publish +# publish: +# allow_offline: false + +# https://verdaccio.org/docs/configuration#url-prefix +# url_prefix: /verdaccio/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/my_prefix' +# // url -> https://somedomain.org/my_prefix/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/' +# // url -> https://somedomain.org/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org/first_prefix'; +# url_prefix: '/second_prefix' +# // url -> https://somedomain.org/second_prefix/' + +# https://verdaccio.org/docs/configuration#security +# security: +# api: +# legacy: true +# jwt: +# sign: +# expiresIn: 29d +# verify: +# someProp: [value] +# web: +# sign: +# expiresIn: 1h # 1 hour by default +# verify: +# someProp: [value] + +# https://verdaccio.org/docs/configuration#user-rate-limit +# userRateLimit: +# windowMs: 50000 +# max: 1000 + +# https://verdaccio.org/docs/configuration#max-body-size +# max_body_size: 10mb + +# https://verdaccio.org/docs/configuration#listen-port +# listen: +# - localhost:4873 # default value +# - http://localhost:4873 # same thing +# - 0.0.0.0:4873 # listen on all addresses (INADDR_ANY) +# - https://example.org:4873 # if you want to use https +# - "[::1]:4873" # ipv6 +# - unix:/tmp/verdaccio.sock # unix socket + +# The HTTPS configuration is useful if you do not consider use a HTTP Proxy +# https://verdaccio.org/docs/configuration#https +# https: +# key: ./path/verdaccio-key.pem +# cert: ./path/verdaccio-cert.pem +# ca: ./path/verdaccio-csr.pem + +# https://verdaccio.org/docs/configuration#proxy +# http_proxy: http://something.local/ +# https_proxy: https://something.local/ + +# https://verdaccio.org/docs/configuration#notifications +# notify: +# method: POST +# headers: [{ "Content-Type": "application/json" }] +# endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken +# content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' + +middlewares: + audit: + enabled: true + +# https://verdaccio.org/docs/logger +# log settings +logs: { type: stdout, format: pretty, level: http } +#experiments: +# # support for npm token command +# token: false +# # enable tarball URL redirect for hosting tarball with a different server, the tarball_url_redirect can be a template string +# tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}' +# # the tarball_url_redirect can be a function, takes packageName and filename and returns the url, when working with a js configuration file +# tarball_url_redirect(packageName, filename) { +# const signedUrl = // generate a signed url +# return signedUrl; +# } + +# translate your registry, api i18n not available yet +# i18n: +# list of the available translations https://github.com/verdaccio/verdaccio/blob/master/packages/plugins/ui-theme/src/i18n/ABOUT_TRANSLATIONS.md +# web: en-US diff --git a/docker-examples/v5/plugins/docker-local-plugin/Dockerfile b/docker-examples/v5/plugins/docker-local-plugin/Dockerfile new file mode 100644 index 000000000..1c9d67723 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/Dockerfile @@ -0,0 +1,26 @@ +# Docs based on https://github.com/xlts-dev/verdaccio-prometheus-middleware#installation +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +RUN mkdir -p /verdaccio/plugins + +# Copy the local plugin into the docker image +ADD plugins/verdaccio-docker-memory /verdaccio/plugins/verdaccio-docker-memory +# Install the production dependencies (be careful install devDependencies here) +RUN cd /verdaccio/plugins/verdaccio-docker-memory \ + && npm install --production + +# The final built image will be based on the standard Verdaccio docker image. +FROM verdaccio/verdaccio:5 + +# Copy the plugin files over from the 'builder' node image. +# The `$VERDACCIO_USER_UID` env variable is defined in the base `verdaccio/verdaccio` image. +# Refer to: https://github.com/verdaccio/verdaccio/blob/v5.2.0/Dockerfile#L32 +# The local verdaccio-docker-memory is setup as storage +ADD docker.yaml /verdaccio/conf/config.yaml + +# Copy the plugin into the /verdaccio/plugins +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/verdaccio-docker-memory \ + /verdaccio/plugins/verdaccio-docker-memory diff --git a/docker-examples/v5/plugins/docker-local-plugin/README.md b/docker-examples/v5/plugins/docker-local-plugin/README.md new file mode 100644 index 000000000..afc12e9a1 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/README.md @@ -0,0 +1,42 @@ +# Installing a local plugin with Docker build + +On this small tutorial (based on [`verdaccio-prometheus-middleware`](https://github.com/xlts-dev/verdaccio-prometheus-middleware) example) you will be able to use a published package in any random registry (npmjs by default) and use it withing a docker image without mapping need it. + +> Since verdaccio:5 uses `yarn@2` to run the application, this tutorial is a workaround but future prove since verdaccio 6 uses `pnpm` to build the docker image. + +There are three main steps to highlight: + +- Note the custom plugin at `plugins/verdaccio-docker-memory` under the name `verdaccio-docker-memory`. +- Install the _production_ dependencies for the plugin `verdaccio-docker-memory` +- `docker.yaml`: This is a copy of the original configuration file for docker and with small modifications to use the local plugin `verdaccio-docker-memory`. +- The `Dockerfile` take advance of the docker multi-stage build to copy the local plugin into the `verdaccio/plugins` folder withing the image, then we apply the right permissions `--chown=$VERDACCIO_USER_UID:root` so the plugin is recognized. + +## Run it + +Build this image. + +```bash +docker build -t verdaccio/verdaccio:local . +``` + +and to run it + +```bash +docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio:local +``` + +## Usage + +```dockerfile +FROM node:lts-alpine as builder +RUN mkdir -p /verdaccio/plugins +ADD plugins/verdaccio-docker-memory /verdaccio/plugins/verdaccio-docker-memory +RUN cd /verdaccio/plugins/verdaccio-docker-memory \ + && ls -ls \ + && npm install --production +FROM verdaccio/verdaccio:5 +ADD docker.yaml /verdaccio/conf/config.yaml +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/verdaccio-docker-memory \ + /verdaccio/plugins/verdaccio-docker-memory +``` diff --git a/docker-examples/v5/plugins/docker-local-plugin/docker.yaml b/docker-examples/v5/plugins/docker-local-plugin/docker.yaml new file mode 100644 index 000000000..aa779b5d9 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/docker.yaml @@ -0,0 +1,199 @@ +# +# This is the default configuration file. It allows all users to do anything, +# please read carefully the documentation and best practices to +# improve security. +# +# Do not configure host and port under `listen` in this file +# as it will be ignored when using docker. +# see https://verdaccio.org/docs/en/docker#docker-and-custom-port-configuration +# +# Look here for more config file examples: +# https://github.com/verdaccio/verdaccio/tree/5.x/conf +# +# Read about the best practices +# https://verdaccio.org/docs/best + +# path to a directory with all packages +storage: /verdaccio/storage/data + +store: + # dummy copy of https://www.npmjs.com/package/verdaccio-memory + docker-memory: + limit: 1000 + +# path to a directory with plugins to include +plugins: /verdaccio/plugins + +# https://verdaccio.org/docs/webui +web: + title: Verdaccio This is a Test + # comment out to disable gravatar support + # gravatar: false + # by default packages are ordercer ascendant (asc|desc) + # sort_packages: asc + # convert your UI to the dark side + # darkMode: true + # html_cache: true + # by default all features are displayed + # login: true + # showInfo: true + # showSettings: true + # In combination with darkMode you can force specific theme + # showThemeSwitch: true + # showFooter: true + # showSearch: true + # showRaw: true + # showDownloadTarball: true + # HTML tags injected after manifest + # scriptsBodyAfter: + # - '' + # HTML tags injected before ends + # metaScripts: + # - '' + # - '' + # - '' + # HTML tags injected first child at + # bodyBefore: + # - '
html before webpack scripts
' + # Public path for template manifest scripts (only manifest) + # publicPath: http://somedomain.org/ + +auth: + htpasswd: + file: ./htpasswd + # Maximum amount of users allowed to register, defaults to "+inf". + # You can set this to -1 to disable registration. + # max_users: 1000 + +# https://verdaccio.org/docs/configuration#uplinks +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + +# Learn how to protect your packages +# https://verdaccio.org/docs/protect-your-dependencies/ +# https://verdaccio.org/docs/configuration#packages +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + unpublish: $authenticated + proxy: npmjs + + '**': + # allow all users (including non-authenticated users) to read and + # publish all packages + # + # you can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # allow all known users to publish/publish packages + # (anyone can register by default, remember?) + publish: $authenticated + unpublish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: npmjs + +# To improve your security configuration and avoid dependency confusion +# consider removing the proxy property for private packages +# https://verdaccio.org/docs/best#remove-proxy-to-increase-security-at-private-packages + +# https://verdaccio.org/docs/configuration#server +# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. +# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout. +# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. +server: + keepAliveTimeout: 60 + +# https://verdaccio.org/docs/configuration#offline-publish +# publish: +# allow_offline: false + +# https://verdaccio.org/docs/configuration#url-prefix +# url_prefix: /verdaccio/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/my_prefix' +# // url -> https://somedomain.org/my_prefix/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/' +# // url -> https://somedomain.org/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org/first_prefix'; +# url_prefix: '/second_prefix' +# // url -> https://somedomain.org/second_prefix/' + +# https://verdaccio.org/docs/configuration#security +# security: +# api: +# legacy: true +# jwt: +# sign: +# expiresIn: 29d +# verify: +# someProp: [value] +# web: +# sign: +# expiresIn: 1h # 1 hour by default +# verify: +# someProp: [value] + +# https://verdaccio.org/docs/configuration#user-rate-limit +# userRateLimit: +# windowMs: 50000 +# max: 1000 + +# https://verdaccio.org/docs/configuration#max-body-size +# max_body_size: 10mb + +# https://verdaccio.org/docs/configuration#listen-port +# listen: +# - localhost:4873 # default value +# - http://localhost:4873 # same thing +# - 0.0.0.0:4873 # listen on all addresses (INADDR_ANY) +# - https://example.org:4873 # if you want to use https +# - "[::1]:4873" # ipv6 +# - unix:/tmp/verdaccio.sock # unix socket + +# The HTTPS configuration is useful if you do not consider use a HTTP Proxy +# https://verdaccio.org/docs/configuration#https +# https: +# key: ./path/verdaccio-key.pem +# cert: ./path/verdaccio-cert.pem +# ca: ./path/verdaccio-csr.pem + +# https://verdaccio.org/docs/configuration#proxy +# http_proxy: http://something.local/ +# https_proxy: https://something.local/ + +# https://verdaccio.org/docs/configuration#notifications +# notify: +# method: POST +# headers: [{ "Content-Type": "application/json" }] +# endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken +# content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' + +middlewares: + audit: + enabled: true + +# https://verdaccio.org/docs/logger +# log settings +logs: { type: stdout, format: pretty, level: http } +#experiments: +# # support for npm token command +# token: false +# # enable tarball URL redirect for hosting tarball with a different server, the tarball_url_redirect can be a template string +# tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}' +# # the tarball_url_redirect can be a function, takes packageName and filename and returns the url, when working with a js configuration file +# tarball_url_redirect(packageName, filename) { +# const signedUrl = // generate a signed url +# return signedUrl; +# } + +# translate your registry, api i18n not available yet +# i18n: +# list of the available translations https://github.com/verdaccio/verdaccio/blob/master/packages/plugins/ui-theme/src/i18n/ABOUT_TRANSLATIONS.md +# web: en-US diff --git a/docker-examples/v5/plugins/docker-local-plugin/plugins/.eslintrc b/docker-examples/v5/plugins/docker-local-plugin/plugins/.eslintrc new file mode 100644 index 000000000..010393ec7 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/plugins/.eslintrc @@ -0,0 +1,8 @@ +{ + "rules": { + "max-len": 0, + "@typescript-eslint/prefer-optional-chain": 0, + "@typescript-eslint/no-unused-vars": 0, + "@typescript-eslint/explicit-member-accessibility": 0 + } +} diff --git a/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js new file mode 100644 index 000000000..7144ba061 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js @@ -0,0 +1,17 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +exports.LocalMemory = undefined; + +let _localMemory = require('./local-memory'); + +let _localMemory2 = _interopRequireDefault(_localMemory); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +exports.LocalMemory = _localMemory2.default; +exports.default = _localMemory2.default; diff --git a/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js new file mode 100644 index 000000000..cffa40882 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js @@ -0,0 +1,96 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); + +let _memoryHandler = require('./memory-handler'); + +let _memoryHandler2 = _interopRequireDefault(_memoryHandler); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +const DEFAULT_LIMIT = 1000; + +class LocalMemory { + constructor(config, options) { + this.config = config; + this.limit = config.limit || DEFAULT_LIMIT; + this.logger = options.logger; + this.data = this._createEmtpyDatabase(); + } + + getSecret() { + return Promise.resolve(this.data.secret); + } + + setSecret(secret) { + return new Promise((resolve, reject) => { + this.data.secret = secret; + resolve(null); + }); + } + + add(name, cb) { + const list = this.data.list; + + if (list.length < this.limit) { + if (list.indexOf(name) === -1) { + list.push(name); + } + cb(null); + } else { + this.logger.info( + { limit: this.limit }, + 'Storage memory has reached limit of @{limit} packages' + ); + cb(new Error('Storage memory has reached limit of limit packages')); + } + } + + search(onPackage, onEnd, validateName) { + // TODO: pending to implement + onEnd(); + } + + remove(name, cb) { + const list = this.data.list; + + const item = list.indexOf(name); + + if (item !== -1) { + list.splice(item, 1); + } + + cb(null); + } + + get(cb) { + cb(null, this.data.list); + } + + sync() { + // nothing to do + } + + getPackageStorage(packageInfo) { + // eslint-disable-next-line new-cap + return new _memoryHandler2.default(packageInfo, this.data.files, this.logger); + } + + _createEmtpyDatabase() { + const list = []; + const files = {}; + const emptyDatabase = { + list, + files, + secret: '', + }; + + return emptyDatabase; + } +} + +exports.default = LocalMemory; diff --git a/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js new file mode 100644 index 000000000..f597aa887 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js @@ -0,0 +1,182 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +exports.fileExist = exports.noSuchFile = undefined; + +let _httpErrors = require('http-errors'); + +let _httpErrors2 = _interopRequireDefault(_httpErrors); + +let _memoryFs = require('memory-fs'); + +let _memoryFs2 = _interopRequireDefault(_memoryFs); + +let _streams = require('@verdaccio/streams'); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +// $FlowFixMe +const noSuchFile = (exports.noSuchFile = 'ENOENT'); + +const fileExist = (exports.fileExist = 'EEXISTS'); + +const fSError = function fSError(message, code = 404) { + const err = (0, _httpErrors2.default)(code, message); + // $FlowFixMe + err.code = message; + + return err; +}; + +const noPackageFoundError = function noPackageFoundError(message = 'no such package') { + const err = (0, _httpErrors2.default)(404, message); + // $FlowFixMe + err.code = noSuchFile; + return err; +}; + +// eslint-disable-next-line new-cap +const fs = new _memoryFs2.default(); + +class MemoryHandler { + constructor(packageName, data, logger) { + // this is not need it + this.data = data; + this.name = packageName; + this.logger = logger; + } + + updatePackage(pkgFileName, updateHandler, onWrite, transformPackage, onEnd) { + let json = this._getStorage(pkgFileName); + + try { + json = JSON.parse(json); + } catch (err) { + return onEnd(err); + } + + updateHandler(json, (err) => { + if (err) { + return onEnd(err); + } + try { + onWrite(pkgFileName, transformPackage(json), onEnd); + } catch (err) { + return onEnd(fSError('error on parse', 500)); + } + }); + } + + deletePackage(pkgName, callback) { + delete this.data[pkgName]; + callback(null); + } + + removePackage(callback) { + callback(null); + } + + createPackage(name, value, cb) { + this.savePackage(name, value, cb); + } + + savePackage(name, value, cb) { + try { + const json = JSON.stringify(value, null, '\t'); + + this.data[name] = json; + } catch (err) { + cb(fSError(err.message, 500)); + } + + cb(null); + } + + readPackage(name, cb) { + const json = this._getStorage(name); + const isJson = typeof json === 'undefined'; + + try { + cb(isJson ? noPackageFoundError() : null, JSON.parse(json)); + } catch (err) { + cb(noPackageFoundError()); + } + } + + writeTarball(name) { + const uploadStream = new _streams.UploadTarball(); + const temporalName = `/${name}`; + + process.nextTick(function () { + fs.exists(temporalName, function (exists) { + if (exists) { + return uploadStream.emit('error', fSError(fileExist)); + } + + try { + const file = fs.createWriteStream(temporalName); + + uploadStream.pipe(file); + + uploadStream.done = function () { + const onEnd = function onEnd() { + uploadStream.emit('success'); + }; + + uploadStream.on('end', onEnd); + }; + + uploadStream.abort = function () { + uploadStream.emit('error', fSError('transmision aborted', 400)); + file.end(); + }; + + uploadStream.emit('open'); + } catch (err) { + uploadStream.emit('error', err); + } + }); + }); + + return uploadStream; + } + + readTarball(name) { + const pathName = `/${name}`; + + const readTarballStream = new _streams.ReadTarball(); + + process.nextTick(function () { + fs.exists(pathName, function (exists) { + if (!exists) { + readTarballStream.emit('error', noPackageFoundError()); + } else { + const readStream = fs.createReadStream(pathName); + + readTarballStream.emit('content-length', fs.data[name].length); + readTarballStream.emit('open'); + readStream.pipe(readTarballStream); + readStream.on('error', (error) => { + readTarballStream.emit('error', error); + }); + + readTarballStream.abort = function () { + readStream.destroy(fSError('read has been aborted', 400)); + }; + } + }); + }); + + return readTarballStream; + } + + _getStorage(name = '') { + return this.data[name]; + } +} + +exports.default = MemoryHandler; diff --git a/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json new file mode 100644 index 000000000..7379c60d4 --- /dev/null +++ b/docker-examples/v5/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json @@ -0,0 +1,19 @@ +{ + "name": "verdaccio-docker-memory", + "version": "1.0.3", + "description": "storage implementation in memory", + "main": "lib/index.js", + "dependencies": { + "@verdaccio/streams": "1.0.0", + "http-errors": "1.6.3", + "memory-fs": "0.4.1" + }, + "keywords": [ + "verdaccio", + "plugin", + "storage" + ], + "author": "Juan Picado ", + "private": true, + "license": "MIT" +} diff --git a/docker-examples/v6/README.md b/docker-examples/v6/README.md index c97913931..f58ebc9a9 100644 --- a/docker-examples/v6/README.md +++ b/docker-examples/v6/README.md @@ -1,8 +1,22 @@ -# Verdaccio 6 +# Verdaccio 6 Examples > We recommend to have installed [docker-compose >= 1.29.0](https://github.com/docker/compose/releases/tag/1.29.2) -- [Docker + Nginx + Verdaccio](reverse_proxy/nginx/README.md) -- [Docker + Apache + Verdaccio](apache-verdaccio/README.md) +## Mapping Volumes + - [Docker + Local Storage Volume + Verdaccio](docker-local-storage-volume/README.md) -- [Docker + HTTPS Portal + Verdaccio](https-portal-example/README.md) + +## Proxy + +- [Docker + Nginx + Verdaccio](proxy/reverse_proxy/nginx/README.md) +- [Docker + Apache + Verdaccio](proxy/apache-verdaccio/README.md) +- [Docker + HTTPS Portal + Verdaccio](proxy/https-portal-example/README.md) + +> Looking forward more examples with proxies. + +## Plugins + +Using plugins without `docker-compose` mapping volumes, all withing the `Dockerfile`. + +- [Docker + Local Build Auth Plugin (local development)](plugins/docker-build-install-plugin/README.md) +- [Docker + Auth Plugin (from a registry)](plugins/docker-local-plugin/README.md) diff --git a/docker-examples/v6/plugins/docker-build-install-plugin/Dockerfile b/docker-examples/v6/plugins/docker-build-install-plugin/Dockerfile new file mode 100644 index 000000000..691a2f4a9 --- /dev/null +++ b/docker-examples/v6/plugins/docker-build-install-plugin/Dockerfile @@ -0,0 +1,25 @@ +# Docs based on https://github.com/xlts-dev/verdaccio-prometheus-middleware#installation + +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +# Install the metrics middleware plugin +# npm docs +# --global-style https://docs.npmjs.com/cli/v7/commands/npm-install#global-style +# --no-bin-links https://docs.npmjs.com/cli/v7/commands/npm-install#bin-links +# --omit=optional +RUN mkdir -p /verdaccio/plugins \ + && cd /verdaccio/plugins \ + && npm install --global-style --no-bin-links --omit=optional verdaccio-auth-memory@latest + +# The final built image will be based on the standard Verdaccio docker image. +FROM verdaccio/verdaccio:nightly-master + +# Copy the plugin files over from the 'builder' node image. +# The `$VERDACCIO_USER_UID` env variable is defined in the base `verdaccio/verdaccio` image. +# Refer to: https://github.com/verdaccio/verdaccio/blob/v5.2.0/Dockerfile#L32 +ADD docker.yaml /verdaccio/conf/config.yaml +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/node_modules/verdaccio-auth-memory \ + /verdaccio/plugins/verdaccio-auth-memory diff --git a/docker-examples/v6/plugins/docker-build-install-plugin/README.md b/docker-examples/v6/plugins/docker-build-install-plugin/README.md new file mode 100644 index 000000000..2f440cff4 --- /dev/null +++ b/docker-examples/v6/plugins/docker-build-install-plugin/README.md @@ -0,0 +1,46 @@ +# Installing a plugin with Docker build + +On this small tutorial (based on [`verdaccio-prometheus-middleware`](https://github.com/xlts-dev/verdaccio-prometheus-middleware) example) you will be able to use a published package in any random registry (npmjs by default) and use it withing a docker image without mapping need it. + +> Since verdaccio:5 uses `yarn@2` to run the application, this tutorial is a workaround but future prove since verdaccio 6 uses `pnpm` to build the docker image. + +There are two main steps to highlight: + +- `docker.yaml`: This is a copy of the original configuration file for docker and with small modifications to use the plugin [`verdaccio-auth-memory`](https://www.npmjs.com/package/verdaccio-auth-memory) and custom web title for demonstration. +- The `Dockerfile` take advance of the docker multi-stage build to install the plugin into the `verdaccio/plugins` folder withing the image, then we apply the right permissions `--chown=$VERDACCIO_USER_UID:root` so the plugin is recognized. + +## Run it + +Build this image. + +```bash +docker build -t verdaccio/verdaccio:local . +``` + +and to run it + +```bash +docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio:local +``` + +## Usage + +```dockerfile +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +RUN mkdir -p /verdaccio/plugins \ + && cd /verdaccio/plugins \ + && npm install --global-style --no-bin-links --omit=optional verdaccio-auth-memory@latest + +FROM verdaccio/verdaccio:5 + +# copy your modified config.yaml into the image +ADD docker.yaml /verdaccio/conf/config.yaml + +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/node_modules/verdaccio-auth-memory \ + /verdaccio/plugins/verdaccio-auth-memory + +``` diff --git a/docker-examples/v6/plugins/docker-build-install-plugin/docker.yaml b/docker-examples/v6/plugins/docker-build-install-plugin/docker.yaml new file mode 100644 index 000000000..3bc70a146 --- /dev/null +++ b/docker-examples/v6/plugins/docker-build-install-plugin/docker.yaml @@ -0,0 +1,197 @@ +# +# This is the default configuration file. It allows all users to do anything, +# please read carefully the documentation and best practices to +# improve security. +# +# Do not configure host and port under `listen` in this file +# as it will be ignored when using docker. +# see https://verdaccio.org/docs/en/docker#docker-and-custom-port-configuration +# +# Look here for more config file examples: +# https://github.com/verdaccio/verdaccio/tree/5.x/conf +# +# Read about the best practices +# https://verdaccio.org/docs/best + +# path to a directory with all packages +storage: /verdaccio/storage/data +# path to a directory with plugins to include +plugins: /verdaccio/plugins + +# https://verdaccio.org/docs/webui +web: + title: Verdaccio Publish Config Test + # comment out to disable gravatar support + # gravatar: false + # by default packages are ordercer ascendant (asc|desc) + # sort_packages: asc + # convert your UI to the dark side + # darkMode: true + # html_cache: true + # by default all features are displayed + # login: true + # showInfo: true + # showSettings: true + # In combination with darkMode you can force specific theme + # showThemeSwitch: true + # showFooter: true + # showSearch: true + # showRaw: true + # showDownloadTarball: true + # HTML tags injected after manifest + # scriptsBodyAfter: + # - '' + # HTML tags injected before ends + # metaScripts: + # - '' + # - '' + # - '' + # HTML tags injected first child at + # bodyBefore: + # - '
html before webpack scripts
' + # Public path for template manifest scripts (only manifest) + # publicPath: http://somedomain.org/ + +# https://verdaccio.org/docs/configuration#authentication +auth: + auth-memory: + users: + foo: + name: foo + password: s3cret + bar: + name: bar + password: s3cret + +# https://verdaccio.org/docs/configuration#uplinks +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + +# Learn how to protect your packages +# https://verdaccio.org/docs/protect-your-dependencies/ +# https://verdaccio.org/docs/configuration#packages +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + unpublish: $authenticated + proxy: npmjs + + '**': + # allow all users (including non-authenticated users) to read and + # publish all packages + # + # you can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # allow all known users to publish/publish packages + # (anyone can register by default, remember?) + publish: $authenticated + unpublish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: npmjs + +# To improve your security configuration and avoid dependency confusion +# consider removing the proxy property for private packages +# https://verdaccio.org/docs/best#remove-proxy-to-increase-security-at-private-packages + +# https://verdaccio.org/docs/configuration#server +# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. +# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout. +# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. +server: + keepAliveTimeout: 60 + +# https://verdaccio.org/docs/configuration#offline-publish +# publish: +# allow_offline: false + +# https://verdaccio.org/docs/configuration#url-prefix +# url_prefix: /verdaccio/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/my_prefix' +# // url -> https://somedomain.org/my_prefix/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/' +# // url -> https://somedomain.org/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org/first_prefix'; +# url_prefix: '/second_prefix' +# // url -> https://somedomain.org/second_prefix/' + +# https://verdaccio.org/docs/configuration#security +# security: +# api: +# legacy: true +# jwt: +# sign: +# expiresIn: 29d +# verify: +# someProp: [value] +# web: +# sign: +# expiresIn: 1h # 1 hour by default +# verify: +# someProp: [value] + +# https://verdaccio.org/docs/configuration#user-rate-limit +# userRateLimit: +# windowMs: 50000 +# max: 1000 + +# https://verdaccio.org/docs/configuration#max-body-size +# max_body_size: 10mb + +# https://verdaccio.org/docs/configuration#listen-port +# listen: +# - localhost:4873 # default value +# - http://localhost:4873 # same thing +# - 0.0.0.0:4873 # listen on all addresses (INADDR_ANY) +# - https://example.org:4873 # if you want to use https +# - "[::1]:4873" # ipv6 +# - unix:/tmp/verdaccio.sock # unix socket + +# The HTTPS configuration is useful if you do not consider use a HTTP Proxy +# https://verdaccio.org/docs/configuration#https +# https: +# key: ./path/verdaccio-key.pem +# cert: ./path/verdaccio-cert.pem +# ca: ./path/verdaccio-csr.pem + +# https://verdaccio.org/docs/configuration#proxy +# http_proxy: http://something.local/ +# https_proxy: https://something.local/ + +# https://verdaccio.org/docs/configuration#notifications +# notify: +# method: POST +# headers: [{ "Content-Type": "application/json" }] +# endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken +# content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' + +middlewares: + audit: + enabled: true + +# https://verdaccio.org/docs/logger +# log settings +logs: { type: stdout, format: pretty, level: http } +#experiments: +# # support for npm token command +# token: false +# # enable tarball URL redirect for hosting tarball with a different server, the tarball_url_redirect can be a template string +# tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}' +# # the tarball_url_redirect can be a function, takes packageName and filename and returns the url, when working with a js configuration file +# tarball_url_redirect(packageName, filename) { +# const signedUrl = // generate a signed url +# return signedUrl; +# } + +# translate your registry, api i18n not available yet +# i18n: +# list of the available translations https://github.com/verdaccio/verdaccio/blob/master/packages/plugins/ui-theme/src/i18n/ABOUT_TRANSLATIONS.md +# web: en-US diff --git a/docker-examples/v6/plugins/docker-local-plugin/Dockerfile b/docker-examples/v6/plugins/docker-local-plugin/Dockerfile new file mode 100644 index 000000000..db4dc45df --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/Dockerfile @@ -0,0 +1,26 @@ +# Docs based on https://github.com/xlts-dev/verdaccio-prometheus-middleware#installation +# Docker multi-stage build - https://docs.docker.com/develop/develop-images/multistage-build/ +# Use an alpine node image to install the plugin +FROM node:lts-alpine as builder + +RUN mkdir -p /verdaccio/plugins + +# Copy the local plugin into the docker image +ADD plugins/verdaccio-docker-memory /verdaccio/plugins/verdaccio-docker-memory +# Install the production dependencies (be careful install devDependencies here) +RUN cd /verdaccio/plugins/verdaccio-docker-memory \ + && npm install --production + +# The final built image will be based on the standard Verdaccio docker image. +FROM verdaccio/verdaccio:nightly-master + +# Copy the plugin files over from the 'builder' node image. +# The `$VERDACCIO_USER_UID` env variable is defined in the base `verdaccio/verdaccio` image. +# Refer to: https://github.com/verdaccio/verdaccio/blob/v5.2.0/Dockerfile#L32 +# The local verdaccio-docker-memory is setup as storage +ADD docker.yaml /verdaccio/conf/config.yaml + +# Copy the plugin into the /verdaccio/plugins +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/verdaccio-docker-memory \ + /verdaccio/plugins/verdaccio-docker-memory diff --git a/docker-examples/v6/plugins/docker-local-plugin/README.md b/docker-examples/v6/plugins/docker-local-plugin/README.md new file mode 100644 index 000000000..afc12e9a1 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/README.md @@ -0,0 +1,42 @@ +# Installing a local plugin with Docker build + +On this small tutorial (based on [`verdaccio-prometheus-middleware`](https://github.com/xlts-dev/verdaccio-prometheus-middleware) example) you will be able to use a published package in any random registry (npmjs by default) and use it withing a docker image without mapping need it. + +> Since verdaccio:5 uses `yarn@2` to run the application, this tutorial is a workaround but future prove since verdaccio 6 uses `pnpm` to build the docker image. + +There are three main steps to highlight: + +- Note the custom plugin at `plugins/verdaccio-docker-memory` under the name `verdaccio-docker-memory`. +- Install the _production_ dependencies for the plugin `verdaccio-docker-memory` +- `docker.yaml`: This is a copy of the original configuration file for docker and with small modifications to use the local plugin `verdaccio-docker-memory`. +- The `Dockerfile` take advance of the docker multi-stage build to copy the local plugin into the `verdaccio/plugins` folder withing the image, then we apply the right permissions `--chown=$VERDACCIO_USER_UID:root` so the plugin is recognized. + +## Run it + +Build this image. + +```bash +docker build -t verdaccio/verdaccio:local . +``` + +and to run it + +```bash +docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio:local +``` + +## Usage + +```dockerfile +FROM node:lts-alpine as builder +RUN mkdir -p /verdaccio/plugins +ADD plugins/verdaccio-docker-memory /verdaccio/plugins/verdaccio-docker-memory +RUN cd /verdaccio/plugins/verdaccio-docker-memory \ + && ls -ls \ + && npm install --production +FROM verdaccio/verdaccio:5 +ADD docker.yaml /verdaccio/conf/config.yaml +COPY --chown=$VERDACCIO_USER_UID:root --from=builder \ + /verdaccio/plugins/verdaccio-docker-memory \ + /verdaccio/plugins/verdaccio-docker-memory +``` diff --git a/docker-examples/v6/plugins/docker-local-plugin/docker.yaml b/docker-examples/v6/plugins/docker-local-plugin/docker.yaml new file mode 100644 index 000000000..2c38d745f --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/docker.yaml @@ -0,0 +1,199 @@ +# +# This is the default configuration file. It allows all users to do anything, +# please read carefully the documentation and best practices to +# improve security. +# +# Do not configure host and port under `listen` in this file +# as it will be ignored when using docker. +# see https://verdaccio.org/docs/en/docker#docker-and-custom-port-configuration +# +# Look here for more config file examples: +# https://github.com/verdaccio/verdaccio/tree/5.x/conf +# +# Read about the best practices +# https://verdaccio.org/docs/best + +# path to a directory with all packages +storage: /verdaccio/storage/data + +store: + # dummy copy of https://www.npmjs.com/package/verdaccio-memory + docker-memory: + limit: 1000 + +# path to a directory with plugins to include +plugins: /verdaccio/plugins + +# https://verdaccio.org/docs/webui +web: + title: Verdaccio This is a Test + # comment out to disable gravatar support + # gravatar: false + # by default packages are ordercer ascendant (asc|desc) + # sort_packages: asc + # convert your UI to the dark side + # darkMode: true + # html_cache: true + # by default all features are displayed + # login: true + # showInfo: true + # showSettings: true + # In combination with darkMode you can force specific theme + # showThemeSwitch: true + # showFooter: true + # showSearch: true + # showRaw: true + # showDownloadTarball: true + # HTML tags injected after manifest + # scriptsBodyAfter: + # - '' + # HTML tags injected before ends + # metaScripts: + # - '' + # - '' + # - '' + # HTML tags injected first child at + # bodyBefore: + # - '
html before webpack scripts
' + # Public path for template manifest scripts (only manifest) + # publicPath: http://somedomain.org/ + +auth: + htpasswd: + file: ./htpasswd + # Maximum amount of users allowed to register, defaults to "+inf". + # You can set this to -1 to disable registration. + # max_users: 1000 + +# https://verdaccio.org/docs/configuration#uplinks +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + +# Learn how to protect your packages +# https://verdaccio.org/docs/protect-your-dependencies/ +# https://verdaccio.org/docs/configuration#packages +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + unpublish: $authenticated + proxy: npmjs + + '**': + # allow all users (including non-authenticated users) to read and + # publish all packages + # + # you can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # allow all known users to publish/publish packages + # (anyone can register by default, remember?) + publish: $authenticated + unpublish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: npmjs + +# To improve your security configuration and avoid dependency confusion +# consider removing the proxy property for private packages +# https://verdaccio.org/docs/best#remove-proxy-to-increase-security-at-private-packages + +# https://verdaccio.org/docs/configuration#server +# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. +# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout. +# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. +server: + keepAliveTimeout: 60 + +# https://verdaccio.org/docs/configuration#offline-publish +# publish: +# allow_offline: false + +# https://verdaccio.org/docs/configuration#url-prefix +# url_prefix: /verdaccio/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/my_prefix' +# // url -> https://somedomain.org/my_prefix/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org'; +# url_prefix: '/' +# // url -> https://somedomain.org/ +# VERDACCIO_PUBLIC_URL='https://somedomain.org/first_prefix'; +# url_prefix: '/second_prefix' +# // url -> https://somedomain.org/second_prefix/' + +# https://verdaccio.org/docs/configuration#security +# security: +# api: +# legacy: true +# jwt: +# sign: +# expiresIn: 29d +# verify: +# someProp: [value] +# web: +# sign: +# expiresIn: 1h # 1 hour by default +# verify: +# someProp: [value] + +# https://verdaccio.org/docs/configuration#user-rate-limit +# userRateLimit: +# windowMs: 50000 +# max: 1000 + +# https://verdaccio.org/docs/configuration#max-body-size +# max_body_size: 10mb + +# https://verdaccio.org/docs/configuration#listen-port +# listen: +# - localhost:4873 # default value +# - http://localhost:4873 # same thing +# - 0.0.0.0:4873 # listen on all addresses (INADDR_ANY) +# - https://example.org:4873 # if you want to use https +# - "[::1]:4873" # ipv6 +# - unix:/tmp/verdaccio.sock # unix socket + +# The HTTPS configuration is useful if you do not consider use a HTTP Proxy +# https://verdaccio.org/docs/configuration#https +# https: +# key: ./path/verdaccio-key.pem +# cert: ./path/verdaccio-cert.pem +# ca: ./path/verdaccio-csr.pem + +# https://verdaccio.org/docs/configuration#proxy +# http_proxy: http://something.local/ +# https_proxy: https://something.local/ + +# https://verdaccio.org/docs/configuration#notifications +# notify: +# method: POST +# headers: [{ "Content-Type": "application/json" }] +# endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken +# content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' + +middlewares: + audit: + enabled: true + +# https://verdaccio.org/docs/logger +# log settings +log: { type: stdout, format: pretty, level: http } +#experiments: +# # support for npm token command +# token: false +# # enable tarball URL redirect for hosting tarball with a different server, the tarball_url_redirect can be a template string +# tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}' +# # the tarball_url_redirect can be a function, takes packageName and filename and returns the url, when working with a js configuration file +# tarball_url_redirect(packageName, filename) { +# const signedUrl = // generate a signed url +# return signedUrl; +# } + +# translate your registry, api i18n not available yet +# i18n: +# list of the available translations https://github.com/verdaccio/verdaccio/blob/master/packages/plugins/ui-theme/src/i18n/ABOUT_TRANSLATIONS.md +# web: en-US diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/.eslintrc b/docker-examples/v6/plugins/docker-local-plugin/plugins/.eslintrc new file mode 100644 index 000000000..010393ec7 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/.eslintrc @@ -0,0 +1,8 @@ +{ + "rules": { + "max-len": 0, + "@typescript-eslint/prefer-optional-chain": 0, + "@typescript-eslint/no-unused-vars": 0, + "@typescript-eslint/explicit-member-accessibility": 0 + } +} diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js new file mode 100644 index 000000000..0c4aa4760 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/index.js @@ -0,0 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +Object.defineProperty(exports, 'LocalMemory', { + enumerable: true, + get: function () { + return _localMemory.default; + }, +}); +exports.default = void 0; + +var _localMemory = _interopRequireDefault(require('./local-memory')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +var _default = _localMemory.default; +exports.default = _default; +//# sourceMappingURL=index.js.map diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js new file mode 100644 index 000000000..8c1b1b6fc --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/local-memory.js @@ -0,0 +1,141 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +exports.default = void 0; + +var _debug = _interopRequireDefault(require('debug')); + +var _core = require('@verdaccio/core'); + +var _memoryHandler = _interopRequireDefault(require('./memory-handler')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +const debug = (0, _debug.default)('verdaccio:plugin:storage:local-memory'); +const DEFAULT_LIMIT = 1000; + +class LocalMemory { + constructor(config, options) { + this.config = config; + this.limit = config.limit || DEFAULT_LIMIT; + this.logger = options.logger; + this.data = this._createEmtpyDatabase(); + this.path = '/'; + debug('start plugin'); + } + + init() { + return Promise.resolve(); + } + + getSecret() { + return Promise.resolve(this.data.secret); + } + + setSecret(secret) { + return new Promise((resolve) => { + this.data.secret = secret; + resolve(null); + }); + } + + async add(name) { + return new Promise((resolve, reject) => { + const { list } = this.data; + + if (list.length < this.limit) { + if (list.indexOf(name) === -1) { + list.push(name); + } + + resolve(); + } else { + this.logger.info( + { + limit: this.limit, + }, + 'Storage memory has reached limit of @{limit} packages' + ); + reject(new Error('Storage memory has reached limit of limit packages')); + } + }); + } // eslint-disable-next-line @typescript-eslint/no-unused-vars + + search(onPackage, onEnd) { + this.logger.warn('[verdaccio/memory]: search method not implemented, PR is welcome'); + onEnd(); + } + + async remove(name) { + return new Promise((resolve) => { + const { list } = this.data; + const item = list.indexOf(name); + + if (item !== -1) { + list.splice(item, 1); + } + + return resolve(); + }); + } + + async get() { + var _this$data, _this$data$list, _this$data2; + + debug( + 'data list length %o', + (_this$data = this.data) === null || _this$data === void 0 + ? void 0 + : (_this$data$list = _this$data.list) === null || _this$data$list === void 0 + ? void 0 + : _this$data$list.length + ); + return Promise.resolve( + (_this$data2 = this.data) === null || _this$data2 === void 0 ? void 0 : _this$data2.list + ); + } + + getPackageStorage(packageInfo) { + return new _memoryHandler.default(packageInfo, this.data.files, this.logger); + } + + _createEmtpyDatabase() { + const list = []; + const files = {}; + const emptyDatabase = { + list, + files, + secret: '', + }; + return emptyDatabase; + } + + saveToken() { + this.logger.warn('[verdaccio/memory][saveToken] save token has not been implemented yet'); + return Promise.reject(_core.errorUtils.getServiceUnavailable('method not implemented')); + } + + deleteToken(user, tokenKey) { + this.logger.warn( + { + tokenKey, + user, + }, + '[verdaccio/memory][deleteToken] delete token has not been implemented yet @{user}' + ); + return Promise.reject(_core.errorUtils.getServiceUnavailable('method not implemented')); + } + + readTokens() { + this.logger.warn('[verdaccio/memory][readTokens] read tokens has not been implemented yet '); + return Promise.reject(_core.errorUtils.getServiceUnavailable('method not implemented')); + } +} + +var _default = LocalMemory; +exports.default = _default; +//# sourceMappingURL=local-memory.js.map diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js new file mode 100644 index 000000000..db5b45a38 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/memory-handler.js @@ -0,0 +1,214 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +exports.default = void 0; + +var _debug = _interopRequireDefault(require('debug')); + +var _memfs = require('memfs'); + +var _path = _interopRequireDefault(require('path')); + +var _core = require('@verdaccio/core'); + +var _streams = require('@verdaccio/streams'); + +var _utils = require('./utils'); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +const debug = (0, _debug.default)('verdaccio:plugin:storage:memory-storage'); + +class MemoryHandler { + constructor(packageName, data, logger) { + // this is not need it + this.data = data; + this.name = packageName; + this.logger = logger; + this.path = `/${packageName}`; + debug('initialized'); + } + + updatePackage(pkgFileName, updateHandler, onWrite, transformPackage, onEnd) { + const json = this._getStorage(pkgFileName); + + let pkg; + + try { + pkg = (0, _utils.parsePackage)(json); + } catch (err) { + return onEnd(err); + } + + updateHandler(pkg, (err) => { + if (err) { + return onEnd(err); + } + + try { + onWrite(pkgFileName, transformPackage(pkg), onEnd); + } catch (err) { + return onEnd(_core.errorUtils.getInternalError('error on parse the metadata')); + } + }); + } + + deletePackage(pkgName) { + delete this.data[pkgName]; + return Promise.resolve(); + } + + removePackage() { + return Promise.resolve(); + } + + createPackage(name, value, cb) { + debug('create package %o', name); + this.savePackage(name, value, cb); + } + + savePackage(name, value, cb) { + try { + debug('save package %o', name); + this.data[name] = (0, _utils.stringifyPackage)(value); + return cb(null); + } catch (err) { + return cb(_core.errorUtils.getInternalError(err.message)); + } + } + + async readPackageNext(name) { + const json = this._getStorage(name); + + try { + return ( + typeof json === 'undefined' ? _core.errorUtils.getNotFound() : null, + (0, _utils.parsePackage)(json) + ); + } catch (err) { + throw _core.errorUtils.getNotFound(); + } + } + + readPackage(name, cb) { + debug('read package %o', name); + + const json = this._getStorage(name); + + const isJson = typeof json === 'undefined'; + + try { + return cb(isJson ? _core.errorUtils.getNotFound() : null, (0, _utils.parsePackage)(json)); + } catch (err) { + return cb(_core.errorUtils.getNotFound()); + } + } + + writeTarball(name) { + const uploadStream = new _streams.UploadTarball({}); + const temporalName = `${this.path}/${name}`; + debug('write tarball %o', temporalName); + process.nextTick(function () { + _memfs.fs.mkdirp(_path.default.dirname(temporalName), (mkdirpError) => { + if (mkdirpError) { + return uploadStream.emit('error', mkdirpError); + } + + _memfs.fs.stat(temporalName, function (fileError, stats) { + if (!fileError && stats) { + return uploadStream.emit('error', _core.errorUtils.getConflict()); + } + + try { + const file = _memfs.fs.createWriteStream(temporalName); + + uploadStream.pipe(file); + + uploadStream.done = function () { + const onEnd = function () { + uploadStream.emit('success'); + }; + + uploadStream.on('end', onEnd); + }; + + uploadStream.abort = function () { + uploadStream.emit('error', _core.errorUtils.getBadRequest('transmision aborted')); + file.end(); + }; + + uploadStream.emit('open'); + return; + } catch (err) { + uploadStream.emit('error', err); + return; + } + }); + }); + }); + return uploadStream; + } + + readTarball(name) { + const pathName = `${this.path}/${name}`; + debug('read tarball %o', pathName); + const readTarballStream = new _streams.ReadTarball({}); + process.nextTick(function () { + _memfs.fs.stat(pathName, function (error, stats) { + if (error && !stats) { + return readTarballStream.emit('error', _core.errorUtils.getNotFound()); + } + + try { + const readStream = _memfs.fs.createReadStream(pathName); + + readTarballStream.emit( + 'content-length', + stats === null || stats === void 0 ? void 0 : stats.size + ); + readTarballStream.emit('open'); + readStream.pipe(readTarballStream); + readStream.on('error', (error) => { + readTarballStream.emit('error', error); + }); + + readTarballStream.abort = function () { + readStream.destroy(_core.errorUtils.getBadRequest('read has been aborted')); + }; + + return; + } catch (err) { + readTarballStream.emit('error', err); + return; + } + }); + }); + return readTarballStream; + } + + _getStorage(name = '') { + debug('get storage %o', name); + return this.data[name]; + } // migration pending + + async updatePackageNext(packageName, handleUpdate) { + debug(packageName); // @ts-expect-error + + await handleUpdate({}); // @ts-expect-error + + return Promise.resolve({}); + } + + async savePackageNext(name, value) { + debug(name); + debug(value); + } +} + +var _default = MemoryHandler; +exports.default = _default; +//# sourceMappingURL=memory-handler.js.map diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/utils.js b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/utils.js new file mode 100644 index 000000000..95062b8a6 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/lib/utils.js @@ -0,0 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true, +}); +exports.parsePackage = parsePackage; +exports.stringifyPackage = stringifyPackage; + +function stringifyPackage(pkg) { + return JSON.stringify(pkg, null, '\t'); +} + +function parsePackage(pkg) { + return JSON.parse(pkg); +} +//# sourceMappingURL=utils.js.map diff --git a/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json new file mode 100644 index 000000000..b1faa7b72 --- /dev/null +++ b/docker-examples/v6/plugins/docker-local-plugin/plugins/verdaccio-docker-memory/package.json @@ -0,0 +1,56 @@ +{ + "name": "verdaccio-docker-memory", + "version": "11.0.0-6-next.10", + "description": "Storage implementation in memory", + "keywords": [ + "private", + "package", + "repository", + "registry", + "enterprise", + "modules", + "proxy", + "server", + "verdaccio" + ], + "author": "Juan Picado ", + "license": "MIT", + "homepage": "https://verdaccio.org", + "repository": { + "type": "https", + "url": "https://github.com/verdaccio/verdaccio", + "directory": "packages/plugins/memory" + }, + "bugs": { + "url": "https://github.com/verdaccio/verdaccio/issues" + }, + "main": "lib/index.js", + "types": "lib/index.d.ts", + "engines": { + "node": ">=14", + "npm": ">=6" + }, + "dependencies": { + "@verdaccio/core": "6.0.0-6-next.5", + "@verdaccio/streams": "11.0.0-6-next.5", + "memory-fs": "0.5.0", + "debug": "4.3.3", + "memfs": "3.4.1" + }, + "devDependencies": { + "@verdaccio/types": "11.0.0-6-next.12" + }, + "scripts": { + "clean": "rimraf ./build", + "type-check": "tsc --noEmit -p tsconfig.build.json", + "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json", + "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps", + "build": "pnpm run build:js && pnpm run build:types", + "watch": "pnpm build:js -- --watch", + "test": "cross-env NODE_ENV=test BABEL_ENV=test jest" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } +} diff --git a/docker-examples/v6/apache-verdaccio/README.md b/docker-examples/v6/proxy/apache-verdaccio/README.md similarity index 100% rename from docker-examples/v6/apache-verdaccio/README.md rename to docker-examples/v6/proxy/apache-verdaccio/README.md diff --git a/docker-examples/v6/apache-verdaccio/apache_proxy/Dockerfile b/docker-examples/v6/proxy/apache-verdaccio/apache_proxy/Dockerfile similarity index 100% rename from docker-examples/v6/apache-verdaccio/apache_proxy/Dockerfile rename to docker-examples/v6/proxy/apache-verdaccio/apache_proxy/Dockerfile diff --git a/docker-examples/v6/apache-verdaccio/apache_proxy/conf/000-default.conf b/docker-examples/v6/proxy/apache-verdaccio/apache_proxy/conf/000-default.conf similarity index 100% rename from docker-examples/v6/apache-verdaccio/apache_proxy/conf/000-default.conf rename to docker-examples/v6/proxy/apache-verdaccio/apache_proxy/conf/000-default.conf diff --git a/docker-examples/v6/apache-verdaccio/apache_proxy/conf/env.load b/docker-examples/v6/proxy/apache-verdaccio/apache_proxy/conf/env.load similarity index 100% rename from docker-examples/v6/apache-verdaccio/apache_proxy/conf/env.load rename to docker-examples/v6/proxy/apache-verdaccio/apache_proxy/conf/env.load diff --git a/docker-examples/v6/apache-verdaccio/docker-compose.yaml b/docker-examples/v6/proxy/apache-verdaccio/docker-compose.yaml similarity index 100% rename from docker-examples/v6/apache-verdaccio/docker-compose.yaml rename to docker-examples/v6/proxy/apache-verdaccio/docker-compose.yaml diff --git a/docker-examples/v6/https-portal-example/README.md b/docker-examples/v6/proxy/https-portal-example/README.md similarity index 100% rename from docker-examples/v6/https-portal-example/README.md rename to docker-examples/v6/proxy/https-portal-example/README.md diff --git a/docker-examples/v6/https-portal-example/conf/config.yaml b/docker-examples/v6/proxy/https-portal-example/conf/config.yaml similarity index 100% rename from docker-examples/v6/https-portal-example/conf/config.yaml rename to docker-examples/v6/proxy/https-portal-example/conf/config.yaml diff --git a/docker-examples/v6/https-portal-example/conf/htpasswd b/docker-examples/v6/proxy/https-portal-example/conf/htpasswd similarity index 100% rename from docker-examples/v6/https-portal-example/conf/htpasswd rename to docker-examples/v6/proxy/https-portal-example/conf/htpasswd diff --git a/docker-examples/v6/https-portal-example/docker-compose.yml b/docker-examples/v6/proxy/https-portal-example/docker-compose.yml similarity index 100% rename from docker-examples/v6/https-portal-example/docker-compose.yml rename to docker-examples/v6/proxy/https-portal-example/docker-compose.yml diff --git a/docker-examples/v6/https-portal-example/storage/@scope/example/example-1.0.0.tgz b/docker-examples/v6/proxy/https-portal-example/storage/@scope/example/example-1.0.0.tgz similarity index 100% rename from docker-examples/v6/https-portal-example/storage/@scope/example/example-1.0.0.tgz rename to docker-examples/v6/proxy/https-portal-example/storage/@scope/example/example-1.0.0.tgz diff --git a/docker-examples/v6/https-portal-example/storage/@scope/example/package.json b/docker-examples/v6/proxy/https-portal-example/storage/@scope/example/package.json similarity index 100% rename from docker-examples/v6/https-portal-example/storage/@scope/example/package.json rename to docker-examples/v6/proxy/https-portal-example/storage/@scope/example/package.json diff --git a/docker-examples/v6/https-portal-example/storage/jquery/package.json b/docker-examples/v6/proxy/https-portal-example/storage/jquery/package.json similarity index 100% rename from docker-examples/v6/https-portal-example/storage/jquery/package.json rename to docker-examples/v6/proxy/https-portal-example/storage/jquery/package.json diff --git a/website/docs/programmatically.md b/website/docs/programmatically.md index b69001aa0..c5520c658 100644 --- a/website/docs/programmatically.md +++ b/website/docs/programmatically.md @@ -1,6 +1,6 @@ --- id: verdaccio-programmatically -title: "Using Verdaccio Programmatically" +title: "Node.js API" --- Verdaccio is a binary command which is available in your enviroment when you install globally the package eg `npm i -g verdaccio`, but also can be dependency in your project and use it programmatically.