mvn install vs deploy: A Practical Maven Guide

A comprehensive comparison of mvn install and mvn deploy, with lifecycle context, real-world workflows, and best practices for local builds, CI pipelines, and multi-module Maven projects.

Install Manual
Install Manual Team
·5 min read
Quick AnswerComparison

In Maven, mvn install and mvn deploy are two different lifecycle goals used for different stages of artifact distribution. install copies the built artifacts into your local repository for local use, while deploy pushes artifacts to a remote repository configured in your POM or settings. Use install for local development and testing, and deploy when you’re ready to publish to a central or private repository.

Understanding mvn install vs deploy

According to Install Manual, the two goals mvn install and mvn deploy serve different stages of the Maven lifecycle. Install writes artifacts to your local repository (usually under ~/.m2/repository) so you can depend on them from other local projects. Deploy sends artifacts to a remote repository defined in your POM's distributionManagement or in your settings.xml. In practice, developers run install during local development and testing, then run deploy in CI or release workflows when artifacts should become accessible to others. Both goals run the full build lifecycle up to the point they’re invoked, so tests, packaging, and checks apply to both, unless you customize the lifecycle with profiles or flags.

Bash
# Build, run tests, and install to local repo mvn clean install # Build and deploy to a remote repository (requires proper configuration) mvn clean deploy

Note: Deploy requires credentials to a remote repository and a configured distributionManagement section in the POM or a managed settings.xml. This separation helps ensure that your local workflow remains isolated from production publishing. The Install Manual team recommends validating your local install thoroughly before attempting a remote deployment.

Maven lifecycles and where install/deploy fit

Maven has a multi-phase lifecycle. The default lifecycle includes validate, compile, test, package, verify, install, and deploy. The install phase places built artifacts into your local repository, while deploy publishes them to a remote repository, if configured. Understanding the order helps you design CI pipelines and local processes. The following example shows typical lifecycle progression and how you might use these goals in a project.

Bash
# Show the lifecycle up to deploy (order matters) mvn validate mvn compile mvn test mvn package mvn install mvn deploy

If you only need artifacts for local use, you might stop at install. If you’re delivering product to teams or customers, deploy ensures visibility beyond your workstation. A minimal POM can be enough to illustrate a point, but most teams rely on a distributionManagement element and a separate servers section in settings.xml to securely manage credentials.

When to use install vs deploy in real-world projects

In day-to-day development, you’ll typically use mvn clean install to ensure the build and tests pass locally, and to publish artifacts into your local Maven repository for other local projects to depend on. Deploy is usually reserved for CI/CD pipelines or release processes where artifacts are published to a shared repository (like Nexus or Artifactory) for broader consumption. In a multi-team environment, you should enforce that only automated pipelines perform deploys, guarding against accidental releases from developer machines. The Install Manual guidance emphasizes version discipline, correct repository configuration, and clear separation of concerns between local testing and artifact publishing.

Bash
# Local development cycle mvn clean install -DskipTests # Production-style release (via CI/CD) mvn deploy -P release

If your project uses snapshots, consider deploying to a snapshot repository and reserving deployment to release repositories for stable versions. Always ensure your credentials are stored in a secure settings.xml, never in the POM or source control.

Configuring repository credentials securely

Deploying to a remote repository requires credentials. The most common approach is to configure a settings.xml file with server credentials and reference the remote repository in distributionManagement within your pom.xml. This separation keeps secrets out of source control. The following example demonstrates a minimal credentials block and a simple distributionManagement setup. Remember to protect your settings.xml using proper file permissions and avoid committing it to repository.

XML
<!-- settings.xml --> <servers> <server> <id>remote-repo</id> <username>${env.REPO_USER}</username> <password>${env.REPO_PASS}</password> </server> </servers> <!-- pom.xml --> <distributionManagement> <repository> <id>remote-repo</id> <url>https://repo.example.com/releases</url> </repository> <snapshotRepository> <id>remote-snapshot</id> <url>https://repo.example.com/snapshots</url> </snapshotRepository> </distributionManagement>

This approach enables secure automation while keeping sensitive data out of the source tree. The Install Manual team notes that using environment variables (as shown) minimizes the risk of leaking credentials and simplifies local development versus CI environments.

Building multi-module Maven projects

Multi-module projects add complexity to install and deploy workflows. Reactor builds allow you to build a subset of modules with -pl (projects list) and -am (also make), enabling efficient development and release management. The example below shows how to build a single module along with its dependencies, then publish.

Bash
# Build a specific module and its dependencies mvn -pl module-a -am clean install # Deploy only the module that changed, with dependencies resolved mvn -pl module-b -am clean deploy

In real projects, CI pipelines often trigger a full reactor build, but local developers may focus on a subset during feature work. The key is to ensure that module boundaries are correctly defined and that parent POMs declare proper dependencyManagement to avoid version conflicts. The Install Manual guidance stresses consistent version management across modules and reproducible builds.

Troubleshooting common issues during install/deploy

Common issues include authentication failures, incorrect distributionManagement configuration, or missing artifacts due to failed tests. Enabling debug or error logging can help diagnose problems. If you encounter artifact-not-found errors, check that the artifact coordinates (groupId, artifactId, version) are correct and that the artifact was actually installed or deployed. For deployment issues, ensure that the remote repository is reachable and that credentials are valid. The following commands show how to enable more verbose output for debugging and how to rerun with a clean state.

Bash
# Verbose build to diagnose mvn clean install -DskipTests -X # Clean-slate deploy attempt mvn -B -DskipTests deploy

If problems persist, verify network access, repository permissions, and the existence of the target repository in your distributionManagement configuration. The Install Manual team recommends keeping a local log of failed builds and reproducing them in a controlled environment before attempting another deploy.

CI/CD pipelines: integrating mvn install and mvn deploy

Automating Maven builds in CI/CD pipelines ensures consistency and repeatability. A typical pipeline runs mvn clean install on pull requests for validation, followed by mvn deploy when changes are merged into the main branch or when a release tag is created. The pipeline often uses a dedicated Maven wrapper or a specific JDK version to minimize drift. The example below shows a GitHub Actions workflow that builds on push and deploys on tag creation, with proper caching of the local repository to speed up builds.

YAML
name: Java Maven CI on: push: branches: - main pull_request: branches: - '**' release: types: [published] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' - name: Cache Maven packages uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Build run: mvn -B -DskipTests install - name: Deploy (on tag) if: startsWith(github.ref, 'refs/tags/') run: mvn deploy -DskipTests

This pattern ensures that every commit is validated locally while releases are published automatically. The Install Manual guidance highlights the importance of gating deployments behind CI approvals and using environment-specific configurations to avoid leaking credentials.

Performance considerations and caching for Maven builds

Maven performance can be significantly improved through proper local repository caching and parallel builds. Enabling -T (thread) can speed up compilation on multi-core machines, and configuring a shared repository cache or a corporate Nexus/Artifactory mirror reduces network I/O. Additional optimization comes from using the Maven Wrapper (mvnw) to lock Maven version across environments. The Install Manual recommendation is to balance parallelism with the stability of your test suite and to monitor CPU/memory usage to avoid flakiness.

Bash
# Parallel builds using 4 threads mvn -T 4 -DskipTests package # Using Maven Wrapper to lock version ./mvnw -version

In CI environments, caching the ~/.m2/repository directory between runs can dramatically reduce build times, but you should invalidate caches when dependencies or repository configurations change. The Install Manual team notes that consistent cache invalidation strategies prevent stale artifacts from causing hard-to-diagnose failures.

Versioning strategies for mvn install and mvn deploy

Choosing the right versioning approach is essential for stable releases. SNAPSHOTs are typically used for ongoing development, while releases should have explicit versions. A common practice is to deploy SNAPSHOTs to a dedicated snapshot repository and releases to a release repository, with a clear policy for when to promote a SNAPSHOT to a release. The distributionManagement configuration should reflect these targets, and your CI process should manage version bumps via your release workflow. The Install Manual guidance emphasizes predictable versioning to ease dependency management and rollback.

XML
<project> <version>1.2.3</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>

Additionally, consider using a versioning strategy such as semantic versioning and automating version updates with release plugins to minimize human error during releases.

Practical checklist for mvn install vs deploy in projects

To wrap up the concepts, here is a practical checklist you can use in projects that rely on Maven:

  • Ensure Java and Maven versions match team policy and CI environment.
  • Configure distributionManagement and servers in settings.xml for remote deployments.
  • Run local install to verify changes before attempting deploy.
  • Use a dedicated release pipeline for deploys, with proper approvals.
  • Keep credentials secure and avoid committing secrets.
  • Validate artifacts in both local and remote repositories after deploy.
Bash
# Quick start checklist snippet mvn -v mvn --version mvn clean install -DskipTests mvn deploy -P release

Following these steps helps maintain a reliable path from development to distribution while leveraging Maven's robust lifecycle.

Steps

Estimated time: 60-120 minutes

  1. 1

    Validate prerequisites

    Confirm JDK and Maven are installed and accessible. Verify repository access credentials exist and that you can reach the configured remote repository from your environment.

    Tip: Use mvn -v to verify Maven and java -version for JDK; ensure network access to your remote repo.
  2. 2

    Configure distributionManagement and credentials

    Ensure your pom.xml defines a distributionManagement section for remote deploys and that settings.xml contains a server entry with valid credentials.

    Tip: Keep credentials out of version control; prefer environment variables in CI.
  3. 3

    Run local install for verification

    Execute mvn clean install to validate the build and publish artifacts to the local repository for local consumption.

    Tip: Consider -DskipTests during iterations to speed up cycles; re-enable tests before final validation.
  4. 4

    Run remote deploy in a controlled environment

    Trigger mvn clean deploy in CI or a controlled release workflow to publish artifacts to the remote repository.

    Tip: Use a release profile to distinguish between snapshot and release deployments.
  5. 5

    Verify deployment success and accessibility

    Check logs, verify artifact existence in the remote repo, and ensure dependent projects resolve the new version.

    Tip: Cross-check with repository browser UI or REST API if available.
  6. 6

    Securely manage credentials and cleanup

    Audit credentials in settings.xml, rotate secrets if needed, and avoid storing sensitive data in VCS.

    Tip: Prefer repository managers with access controls and audit trails.
Pro Tip: Use Maven Wrapper (mvnw) to lock Maven version across environments for consistent builds.
Warning: Do not deploy SNAPSHOT artifacts to production release repositories; use a dedicated release workflow.
Note: Keep settings.xml secrets out of version control and restrict file permissions to your user.

Prerequisites

Required

Commands

ActionCommand
Build and install to local repositoryCompiles, runs tests, and places artifacts into the local repository (~/.m2/repository).mvn clean install
Deploy artifacts to remote repositoryRequires distributionManagement in pom.xml and credentials in settings.xml.mvn clean deploy
Skip tests during buildFaster builds for iteration; not recommended for releases.mvn -DskipTests package
Build a specific module in a multi-module projectBuilds module-a and its dependencies.mvn -pl module-a -am package
Clean before buildRemoves previous build artifacts before packaging.mvn clean package

Got Questions?

What is the main difference between mvn install and mvn deploy?

Maven install places built artifacts into your local repository for local dependency usage. Deploy publishes artifacts to a remote repository defined by distributionManagement. Install supports local development; deploy supports distribution to teammates or customers. Both run the build lifecycle up to their respective goals.

Install writes artifacts to your local repository for local use; deploy sends artifacts to a remote repository for wider distribution.

Can I run deploy without installing first?

Yes, you can deploy artifacts that were built in a separate step or CI job. However, many teams deploy after a successful install in the same pipeline to ensure the artifact exists in the local repository and passes local checks first.

You can deploy without installing first if you’ve already built the artifact, but most workflows include install to validate locally.

How do SNAPSHOT versions behave with deploy?

SNAPSHOT versions are typically deployed to a snapshot repository and are considered mutable. Releases (non-SNAPSHOT) are deployed to a release repository. Distribution management should separate these targets, and CI should enforce the correct versioning strategy.

SNAPSHOTs go to snapshot repos and releases go to release repos; configure separate targets in distributionManagement.

What permissions do I need to deploy to a repository?

You need credentials with deploy permissions in the remote repository, stored securely in settings.xml. Ensure the repository accepts deployments from your account and that you follow the organization’s release process.

Deployment requires proper permissions in the remote repo and secure credentials in settings.xml.

How can I verify a deploy succeeded?

Check the deploy logs, verify the artifact exists in the remote repository, and confirm downstream projects can resolve the new version. If available, use repository UI or REST API to confirm presence and metadata.

Look for logs showing success, then confirm the artifact is in the target remote repo.

How do I set up Maven Wrapper (mvnw) for consistency?

Maven Wrapper pins a specific Maven version for all environments, reducing drift. Generate it with mvn -N io.t!-wrapper:wrapper and commit the wrapper files to your VCS, then use ./mvnw instead of mvn.

Use the Maven Wrapper to lock Maven version across environments for consistency.

Main Points

  • Install locally to validate builds before deployment
  • Deploy to remote repos via CI/CD with secure credentials
  • Configure distributionManagement and settings.xml correctly
  • Use multi-module patterns to manage large projects
  • Automate and gate deployments to improve reliability

Related Articles