diff --git a/.github/typos.toml b/.github/typos.toml
index f27257a23..7d53f9bf1 100644
--- a/.github/typos.toml
+++ b/.github/typos.toml
@@ -2,6 +2,8 @@
muc = "muc" # For Munich location code
Hashi = "Hashi"
HashiCorp = "HashiCorp"
+mavrickrishi = "mavrickrishi" # Username
+mavrick = "mavrick" # Username
[files]
extend-exclude = ["registry/coder/templates/aws-devcontainer/architecture.svg"] #False positive
\ No newline at end of file
diff --git a/.icons/nexus-repository.svg b/.icons/nexus-repository.svg
new file mode 100644
index 000000000..42875c847
--- /dev/null
+++ b/.icons/nexus-repository.svg
@@ -0,0 +1,84 @@
+
+
+
diff --git a/registry/mavrickrishi/README.md b/registry/mavrickrishi/README.md
new file mode 100644
index 000000000..c240f3bcc
--- /dev/null
+++ b/registry/mavrickrishi/README.md
@@ -0,0 +1,14 @@
+---
+display_name: mavrickrishi
+bio: Coder module contributor
+github: mavrick-1
+status: community
+---
+
+# mavrickrishi
+
+This directory contains Coder modules and templates created by mavrickrishi.
+
+## Modules
+
+- [nexus-repository](./modules/nexus-repository/) - Configure package managers to use Sonatype Nexus Repository
diff --git a/registry/mavrickrishi/modules/nexus-repository/README.md b/registry/mavrickrishi/modules/nexus-repository/README.md
new file mode 100644
index 000000000..6c2c1926c
--- /dev/null
+++ b/registry/mavrickrishi/modules/nexus-repository/README.md
@@ -0,0 +1,149 @@
+---
+display_name: Sonatype Nexus Repository
+description: Configure package managers to use Sonatype Nexus Repository for Maven, npm, PyPI, and Docker registries.
+icon: ../../../../.icons/nexus-repository.svg
+verified: true
+tags: [integration, nexus-repository, maven, npm, pypi, docker]
+---
+
+# Sonatype Nexus Repository
+
+Configure package managers (Maven, npm, Go, PyPI, Docker) to use [Sonatype Nexus Repository](https://help.sonatype.com/en/sonatype-nexus-repository.html) with API token authentication. This module provides secure credential handling, multiple repository support per package manager, and flexible username configuration.
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ maven = ["maven-public", "maven-releases"]
+ npm = ["npm-public", "@scoped:npm-private"]
+ go = ["go-public", "go-private"]
+ pypi = ["pypi-public", "pypi-private"]
+ docker = ["docker-public", "docker-private"]
+ }
+}
+```
+
+## Requirements
+
+- Nexus Repository Manager 3.x
+- Valid API token or user credentials
+- Package managers installed on the workspace (Maven, npm, Go, pip, Docker as needed)
+
+> [!NOTE]
+> This module configures package managers but does not install them. You need to handle the installation of Maven, npm, Go, Python pip, and Docker yourself.
+
+## Examples
+
+### Configure Maven to use Nexus repositories
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ maven = ["maven-public", "maven-releases", "maven-snapshots"]
+ }
+}
+```
+
+### Configure npm with scoped packages
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ npm = ["npm-public", "@mycompany:npm-private"]
+ }
+}
+```
+
+### Configure Go module proxy
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ go = ["go-public", "go-private"]
+ }
+}
+```
+
+### Configure Python PyPI repositories
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ pypi = ["pypi-public", "pypi-private"]
+ }
+}
+```
+
+### Configure Docker registries
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ docker = ["docker-public", "docker-private"]
+ }
+}
+```
+
+### Use custom username
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_username = "custom-user"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ maven = ["maven-public"]
+ }
+}
+```
+
+### Complete configuration for all package managers
+
+```tf
+module "nexus_repository" {
+ source = "registry.coder.com/mavrickrishi/nexus-repository/coder"
+ version = "1.0.0"
+ agent_id = coder_agent.example.id
+ nexus_url = "https://nexus.example.com"
+ nexus_password = var.nexus_api_token
+ package_managers = {
+ maven = ["maven-public", "maven-releases"]
+ npm = ["npm-public", "@company:npm-private"]
+ go = ["go-public", "go-private"]
+ pypi = ["pypi-public", "pypi-private"]
+ docker = ["docker-public", "docker-private"]
+ }
+}
+```
diff --git a/registry/mavrickrishi/modules/nexus-repository/main.test.ts b/registry/mavrickrishi/modules/nexus-repository/main.test.ts
new file mode 100644
index 000000000..a9e7b484d
--- /dev/null
+++ b/registry/mavrickrishi/modules/nexus-repository/main.test.ts
@@ -0,0 +1,135 @@
+import { describe, expect, it } from "bun:test";
+import {
+ executeScriptInContainer,
+ runTerraformApply,
+ runTerraformInit,
+ testRequiredVariables,
+} from "~test";
+
+describe("nexus-repository", async () => {
+ await runTerraformInit(import.meta.dir);
+
+ testRequiredVariables(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-password"
+ });
+
+ it("configures Maven settings", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({
+ maven: ["maven-public"]
+ })
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("☕ Configuring Maven...");
+ expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
+ });
+
+ it("configures npm registry", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({
+ npm: ["npm-public"]
+ })
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("📦 Configuring npm...");
+ expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
+ });
+
+ it("configures PyPI repository", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({
+ pypi: ["pypi-public"]
+ })
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("🐍 Configuring pip...");
+ expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
+ });
+
+ it("configures multiple package managers", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({
+ maven: ["maven-public"],
+ npm: ["npm-public"],
+ pypi: ["pypi-public"]
+ })
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("☕ Configuring Maven...");
+ expect(output.stdout.join("\n")).toContain("📦 Configuring npm...");
+ expect(output.stdout.join("\n")).toContain("🐍 Configuring pip...");
+ expect(output.stdout.join("\n")).toContain("✅ Nexus repository configuration completed!");
+ });
+
+ it("handles empty package managers", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({})
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("🤔 no maven repository is set, skipping maven configuration.");
+ expect(output.stdout.join("\n")).toContain("🤔 no npm repository is set, skipping npm configuration.");
+ expect(output.stdout.join("\n")).toContain("🤔 no pypi repository is set, skipping pypi configuration.");
+ expect(output.stdout.join("\n")).toContain("🤔 no docker repository is set, skipping docker configuration.");
+ });
+
+ it("configures Go module proxy", async () => {
+ const state = await runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({
+ go: ["go-public", "go-private"]
+ })
+ });
+
+ const output = await executeScriptInContainer(state, "ubuntu:20.04");
+ expect(output.stdout.join("\n")).toContain("🐹 Configuring Go...");
+ expect(output.stdout.join("\n")).toContain("Go proxy configured via GOPROXY environment variable");
+ expect(output.stdout.join("\n")).toContain("🥳 Configuration complete!");
+ });
+
+ it("validates nexus_url format", async () => {
+ await expect(
+ runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "invalid-url",
+ nexus_password: "test-token",
+ package_managers: JSON.stringify({})
+ })
+ ).rejects.toThrow();
+ });
+
+ it("validates username_field values", async () => {
+ await expect(
+ runTerraformApply(import.meta.dir, {
+ agent_id: "test-agent",
+ nexus_url: "https://nexus.example.com",
+ nexus_password: "test-token",
+ username_field: "invalid",
+ package_managers: JSON.stringify({})
+ })
+ ).rejects.toThrow();
+ });
+});
\ No newline at end of file
diff --git a/registry/mavrickrishi/modules/nexus-repository/main.tf b/registry/mavrickrishi/modules/nexus-repository/main.tf
new file mode 100644
index 000000000..be573121f
--- /dev/null
+++ b/registry/mavrickrishi/modules/nexus-repository/main.tf
@@ -0,0 +1,137 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 2.5"
+ }
+ }
+}
+
+variable "nexus_url" {
+ type = string
+ description = "The base URL of your Nexus repository manager (e.g. https://nexus.example.com)"
+ validation {
+ condition = can(regex("^(https|http)://", var.nexus_url))
+ error_message = "nexus_url must be a valid URL starting with either 'https://' or 'http://'"
+ }
+}
+
+variable "nexus_username" {
+ type = string
+ description = "Custom username for Nexus authentication. If not provided, defaults to the Coder username based on the username_field setting"
+ default = null
+}
+
+variable "nexus_password" {
+ type = string
+ description = "API token or password for Nexus authentication. This value is sensitive and should be stored securely"
+ sensitive = true
+}
+
+variable "agent_id" {
+ type = string
+ description = "The ID of a Coder agent."
+}
+
+variable "package_managers" {
+ type = object({
+ maven = optional(list(string), [])
+ npm = optional(list(string), [])
+ go = optional(list(string), [])
+ pypi = optional(list(string), [])
+ docker = optional(list(string), [])
+ })
+ default = {
+ maven = []
+ npm = []
+ go = []
+ pypi = []
+ docker = []
+ }
+ description = <<-EOF
+ Configuration for package managers. Each key maps to a list of Nexus repository names:
+ - maven: List of Maven repository names
+ - npm: List of npm repository names (supports scoped packages with "@scope:repo-name")
+ - go: List of Go proxy repository names
+ - pypi: List of PyPI repository names
+ - docker: List of Docker registry names
+ Unused package managers can be omitted.
+ Example:
+ {
+ maven = ["maven-public", "maven-releases"]
+ npm = ["npm-public", "@scoped:npm-private"]
+ go = ["go-public", "go-private"]
+ pypi = ["pypi-public", "pypi-private"]
+ docker = ["docker-public", "docker-private"]
+ }
+ EOF
+}
+
+variable "username_field" {
+ type = string
+ description = "Field to use for username (\"username\" or \"email\"). Defaults to \"username\". Only used when nexus_username is not provided"
+ default = "username"
+ validation {
+ condition = can(regex("^(email|username)$", var.username_field))
+ error_message = "username_field must be either 'email' or 'username'"
+ }
+}
+
+data "coder_workspace" "me" {}
+data "coder_workspace_owner" "me" {}
+
+locals {
+ username = coalesce(var.nexus_username, var.username_field == "email" ? data.coder_workspace_owner.me.email : data.coder_workspace_owner.me.name)
+ nexus_host = split("/", replace(replace(var.nexus_url, "https://", ""), "http://", ""))[0]
+}
+
+locals {
+ # Get first repository name or use default
+ maven_repo = length(var.package_managers.maven) > 0 ? var.package_managers.maven[0] : "maven-public"
+ npm_repo = length(var.package_managers.npm) > 0 ? var.package_managers.npm[0] : "npm-public"
+ go_repo = length(var.package_managers.go) > 0 ? var.package_managers.go[0] : "go-public"
+ pypi_repo = length(var.package_managers.pypi) > 0 ? var.package_managers.pypi[0] : "pypi-public"
+
+ npmrc = <<-EOF
+registry=${var.nexus_url}/repository/${local.npm_repo}/
+//${local.nexus_host}/repository/${local.npm_repo}/:username=${local.username}
+//${local.nexus_host}/repository/${local.npm_repo}/:_password=${base64encode(var.nexus_password)}
+//${local.nexus_host}/repository/${local.npm_repo}/:always-auth=true
+EOF
+}
+
+resource "coder_script" "nexus" {
+ agent_id = var.agent_id
+ display_name = "nexus-repository"
+ icon = "/icon/nexus-repository.svg"
+ script = templatefile("${path.module}/run.sh", {
+ NEXUS_URL = var.nexus_url
+ NEXUS_HOST = local.nexus_host
+ NEXUS_USERNAME = local.username
+ NEXUS_PASSWORD = var.nexus_password
+ HAS_MAVEN = length(var.package_managers.maven) == 0 ? "" : "YES"
+ MAVEN_REPO = local.maven_repo
+ HAS_NPM = length(var.package_managers.npm) == 0 ? "" : "YES"
+ NPMRC = local.npmrc
+ HAS_GO = length(var.package_managers.go) == 0 ? "" : "YES"
+ GO_REPO = local.go_repo
+ HAS_PYPI = length(var.package_managers.pypi) == 0 ? "" : "YES"
+ PYPI_REPO = local.pypi_repo
+ HAS_DOCKER = length(var.package_managers.docker) == 0 ? "" : "YES"
+ REGISTER_DOCKER = join("\n ", formatlist("register_docker \"%s\"", var.package_managers.docker))
+ })
+ run_on_start = true
+}
+
+resource "coder_env" "goproxy" {
+ count = length(var.package_managers.go) == 0 ? 0 : 1
+ agent_id = var.agent_id
+ name = "GOPROXY"
+ value = join(",", [
+ for repo in var.package_managers.go :
+ "https://${local.username}:${var.nexus_password}@${local.nexus_host}/repository/${repo}"
+ ])
+}
+
diff --git a/registry/mavrickrishi/modules/nexus-repository/run.sh b/registry/mavrickrishi/modules/nexus-repository/run.sh
new file mode 100644
index 000000000..3539374b1
--- /dev/null
+++ b/registry/mavrickrishi/modules/nexus-repository/run.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+not_configured() {
+ type=$1
+ echo "🤔 no $type repository is set, skipping $type configuration."
+}
+
+config_complete() {
+ echo "🥳 Configuration complete!"
+}
+
+register_docker() {
+ repo=$1
+ echo -n "${NEXUS_PASSWORD}" | docker login "${NEXUS_HOST}/repository/$${repo}" --username "${NEXUS_USERNAME}" --password-stdin
+}
+
+echo "🚀 Configuring Nexus repository access..."
+
+# Configure Maven
+if [ -n "${HAS_MAVEN}" ]; then
+ echo "☕ Configuring Maven..."
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << 'EOF'
+
+
+
+
+ nexus
+ ${NEXUS_USERNAME}
+ ${NEXUS_PASSWORD}
+
+
+
+
+ nexus-mirror
+ *
+ ${NEXUS_URL}/repository/${MAVEN_REPO}
+
+
+
+EOF
+ config_complete
+else
+ not_configured maven
+fi
+
+# Configure npm
+if [ -n "${HAS_NPM}" ]; then
+ echo "📦 Configuring npm..."
+ cat > ~/.npmrc << 'EOF'
+${NPMRC}
+EOF
+ config_complete
+else
+ not_configured npm
+fi
+
+# Configure Go
+if [ -n "${HAS_GO}" ]; then
+ echo "🐹 Configuring Go..."
+ # Go configuration is handled via GOPROXY environment variable
+ # which is set by the Terraform configuration
+ echo "Go proxy configured via GOPROXY environment variable"
+ config_complete
+else
+ not_configured go
+fi
+
+# Configure pip
+if [ -n "${HAS_PYPI}" ]; then
+ echo "🐍 Configuring pip..."
+ mkdir -p ~/.pip
+ # Create .netrc file for secure credential storage
+ cat > ~/.netrc << EOF
+machine ${NEXUS_HOST}
+login ${NEXUS_USERNAME}
+password ${NEXUS_PASSWORD}
+EOF
+ chmod 600 ~/.netrc
+
+ # Update pip.conf to use index-url without embedded credentials
+ cat > ~/.pip/pip.conf << 'EOF'
+[global]
+index-url = https://${NEXUS_HOST}/repository/${PYPI_REPO}/simple
+EOF
+ config_complete
+else
+ not_configured pypi
+fi
+
+# Configure Docker
+if [ -n "${HAS_DOCKER}" ]; then
+ if command -v docker > /dev/null 2>&1; then
+ echo "🐳 Configuring Docker credentials..."
+ mkdir -p ~/.docker
+ ${REGISTER_DOCKER}
+ config_complete
+ else
+ echo "🤔 Docker is not installed, skipping Docker configuration."
+ fi
+else
+ not_configured docker
+fi
+
+echo "✅ Nexus repository configuration completed!"
\ No newline at end of file