Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ The script will:
### NPM Proxy (npm.mirror.intra) - Optional

- **URL**: `http://npm.mirror.intra`
- **Purpose**: Local npm package registry cache
- **Purpose**: Local npm package registry cache and private package hosting
- **Features**:
- Caches npm packages locally for faster installs
- Reduces bandwidth usage
- Transparent proxy to npmjs.org
- Private package publishing (requires authentication)
- Private packages stored separately and never forwarded to npmjs.org

## Usage

Expand Down Expand Up @@ -142,6 +144,51 @@ The npm proxy will:
- Serve cached packages for subsequent requests
- Automatically fetch from npmjs.org if not cached

### Publishing NPM Packages

The npm proxy supports publishing private packages using standard npm commands.

#### Authentication

**Method 1: Using npm login (recommended)**

For npm 9.x+, use the `--auth-type=legacy` flag:

```bash
npm login --registry=http://npm.mirror.intra --auth-type=legacy
# Enter your username and password when prompted
npm whoami --registry=http://npm.mirror.intra
```

**Method 2: Manual token configuration**

If `npm login` doesn't work, you can manually obtain and configure the token:

```bash
TOKEN=$(curl -X PUT http://npm.mirror.intra/-/user/org.couchdb.user:admin \
-H "Content-Type: application/json" \
-d '{"name": "admin", "password": "your-password"}' \
| jq -r .token)
echo "//npm.mirror.intra/:_authToken=$TOKEN" >> ~/.npmrc
npm whoami --registry=http://npm.mirror.intra
```

#### Publishing Packages

Once authenticated, publish packages normally:

```bash
npm publish
```

**Important Notes:**
- All published packages are treated as private packages
- Private packages are stored in `data/data/npm/private/`
- Public packages (cached from npmjs.org) are stored in `data/data/npm/public/`
- Published packages are **NOT** forwarded to npmjs.org
- Private packages take precedence over cached public packages
- Authentication tokens for npm are JWT-based and valid for 1 year

### File Hosting

Use the file repository at `http://files.mirror.intra` to:
Expand Down
1 change: 1 addition & 0 deletions admin/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmjs.org/
77 changes: 69 additions & 8 deletions admin/app/routes/documentation/documentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ export default function Documentation() {
│ ├── files/ # Custom file repository${
appConfig.isNpmProxyEnabled
? `
│ └── npm/ # NPM package cache`
│ └── npm/ # NPM packages
│ ├── private/ # Private published packages
│ └── public/ # Cached public packages from npmjs.org`
: ''
}
└── logs/
Expand Down Expand Up @@ -108,7 +110,7 @@ export default function Documentation() {
Main data storage directory. apt-mirror/ contains downloaded
package repositories, files/ contains custom file repository
{appConfig.isNpmProxyEnabled
? ', npm/ contains cached npm packages'
? ', npm/ contains npm packages with public/ for cached packages and private/ for published packages'
: ''}
.
</p>
Expand Down Expand Up @@ -295,8 +297,9 @@ export default function Documentation() {
<div className="bg-gray-50 p-4 rounded-lg">
<p className="text-gray-700 mb-3">
The NPM Proxy provides a local caching layer for npm packages,
speeding up installations and reducing bandwidth usage. It acts as
a transparent proxy to the official npm registry.
speeding up installations and reducing bandwidth usage. It also supports
publishing private packages that are stored locally and never forwarded
to the public npm registry.
</p>
<div className="bg-white p-3 rounded border-l-4 border-blue-300">
<h5 className="font-semibold mb-2">Features:</h5>
Expand All @@ -305,6 +308,8 @@ export default function Documentation() {
<li>Automatic package metadata fetching</li>
<li>Bandwidth optimization for repeated installs</li>
<li>Offline package availability</li>
<li>Private package publishing (requires authentication)</li>
<li>Private packages stored separately and never forwarded to npmjs.org</li>
</ul>
</div>
</div>
Expand Down Expand Up @@ -344,19 +349,75 @@ export default function Documentation() {
</div>
</div>

<div>
<h3 className="text-lg font-semibold mb-4">Publishing Private Packages</h3>
<div className="bg-gray-50 p-4 rounded-lg">
<p className="text-gray-700 mb-3">
You can publish private npm packages to this registry. All packages are stored locally and never forwarded to npmjs.org.
</p>

<div className="bg-white p-3 rounded border-l-4 border-green-400 mb-4">
<h5 className="font-semibold mb-2">Method 1: Using npm login</h5>
<p className="text-sm text-gray-600 mb-2">For npm 9.x+, use the --auth-type=legacy flag:</p>
<div className="space-y-2 text-sm">
<div className="bg-gray-100 p-2 rounded font-mono text-xs">
npm login --registry=http://npm.mirror.intra --auth-type=legacy
</div>
<p className="text-gray-600">Enter your username and password when prompted, then verify:</p>
<div className="bg-gray-100 p-2 rounded font-mono text-xs">
npm whoami --registry=http://npm.mirror.intra
</div>
</div>
</div>

<div className="bg-white p-3 rounded border-l-4 border-blue-400 mb-4">
<h5 className="font-semibold mb-2">Method 2: Manual token configuration</h5>
<p className="text-sm text-gray-600 mb-2">If npm login doesn't work, get a token manually:</p>
<div className="space-y-2 text-sm">
<div className="bg-gray-100 p-2 rounded font-mono text-xs overflow-x-auto">
TOKEN=$(curl -X PUT http://npm.mirror.intra/-/user/org.couchdb.user:admin \<br />
&nbsp;&nbsp;-H "Content-Type: application/json" \<br />
&nbsp;&nbsp;-d '&#123;"name": "admin", "password": "your-password"&#125;' \<br />
&nbsp;&nbsp;| jq -r .token)
</div>
<div className="bg-gray-100 p-2 rounded font-mono text-xs">
echo "//npm.mirror.intra/:_authToken=$TOKEN" &gt;&gt; ~/.npmrc
</div>
</div>
</div>

<div className="bg-white p-3 rounded border-l-4 border-purple-400 mb-4">
<h5 className="font-semibold mb-2">Publishing:</h5>
<p className="text-sm text-gray-600 mb-2">Once authenticated, publish normally:</p>
<div className="bg-gray-100 p-2 rounded font-mono text-xs">
npm publish
</div>
</div>

<div className="bg-white p-3 rounded border-l-4 border-amber-400">
<h5 className="font-semibold mb-2">Important Notes:</h5>
<ul className="list-disc list-inside space-y-1 text-sm">
<li>All published packages are private and stored in data/npm/private/</li>
<li>Public packages (cached from npmjs.org) are stored in data/npm/public/</li>
<li>Published packages are never forwarded to npmjs.org</li>
<li>Private packages take precedence over cached public packages</li>
<li>Authentication tokens are JWT-based and valid for 1 year</li>
</ul>
</div>
</div>
</div>

<div>
<h3 className="text-lg font-semibold mb-4">File Management</h3>
<div className="bg-gray-50 p-4 rounded-lg">
<p className="text-gray-700 mb-3">
Cached npm packages are stored in the data/npm/ directory and can
be viewed and managed through the File Manager in the admin
interface.
NPM packages are organized in the data/npm/ directory: public packages (cached from npmjs.org) in data/npm/public/ and private packages (published locally) in data/npm/private/. Both can be viewed and managed through the File Manager.
</p>
<div className="bg-white p-3 rounded border-l-4 border-indigo-300">
<h5 className="font-semibold mb-2">Access:</h5>
<ul className="list-disc list-inside space-y-1 text-sm">
<li>Admin UI → File Manager → NPM Packages view</li>
<li>Browse cached packages by name</li>
<li>Browse cached public and private packages by name</li>
<li>View package metadata and tarballs</li>
<li>Monitor cache usage and growth</li>
</ul>
Expand Down
Loading