Skip to main content

Configuring the Moderne agent

In order to securely communicate with the Moderne SaaS, you will need to set up an on-premise agent in your environment. To assist you with that process and provide you with information about the agent, this guide will:

tip

Looking for a complete, working example? Check out the moderne-agent-example repository which contains all the configuration files and setup code in one place for deploying the Moderne agent.

High-level agent information

What does the agent do?

The Moderne on-premise agent:

  • Encrypts and ships LST and recipe artifacts from your artifact repository (e.g., Artifactory) to the Moderne SaaS
  • Provides the symmetric key that Moderne needs to decrypt your artifacts
  • Forwards requests from the Moderne SaaS to your SCM(s) (e.g., GitHub)
  • Forwards requests from the Moderne SaaS to the organization service (if configured)

Agent setup instructions

Step 1: Generate your symmetric key

The Moderne agent requires customers to create a hex-encoded 256-bit AES encryption key. This key will be used to encrypt LST and recipe artifacts before they are sent to your SaaS tenant. To generate a key, please run the following openssl command:

openssl enc -aes-256-cbc -k secret -P

This will return a salt, key, and iv. Please copy the key and save it for use in step 3 as the symmetricKey.

Step 2: Determine how you will run the agent

Moderne offers two ways of running the agent:

  1. An OCI image that can be run using any OCI runtime (e.g., Docker, Podman)
  2. A Spring Boot executable JAR that can be run with Java
info

Regardless of which one you pick, you'll want a minimum system spec of 2 CPU cores, 8 GB of memory, and at least 10 GB of persistent or local storage.

If you deploy to Kubernetes or any other containerized environment like AWS ECS, you'll want to use the OCI image to run the agent.

If you deploy to a PaaS environment such as Cloud Foundry, you'll want to use the JAR to run the agent.

The table below provides the core command for running the agent. However, in order for the agent to function correctly, additional variables will need to be added based on your environment (such as what SCM(s) your company uses, what artifact repositories you have configured). We'll walk through each of those in the following steps.

How to build the Docker image

docker build -t moderne-agent:latest .

How to run the Docker image with an environment file

docker run --env-file=moderne-agent.env moderne-agent:latest

How to run the image with command line arguments

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...

docker run \
# Example environment variables. These will be explained in step 3.
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
# ... Additional environment variables
-p 8080:8080
moderne-agent:latest

Example Dockerfile

info

You are responsible for creating this Dockerfile and your own base image. It is your responsibility to keep this up-to-date when vulnerabilities arise. The below one is a suggestion for getting started - but yours will differ from this as it should point to and use your own tools and services.

FROM eclipse-temurin:17-jdk
RUN apt-get update && apt-get install -y libxml2-utils

# Set the environment variable MODERNE_AGENT_VERSION
ARG MODERNE_AGENT_VERSION
ENV MODERNE_AGENT_VERSION=${MODERNE_AGENT_VERSION}

WORKDIR /app
USER root

# If necessary, download the Moderne tenant SSL certificate and add it to the default Java TrustStore.
# RUN openssl s_client -showcerts -connect <tenant_name>.moderne.io:443 </dev/null 2>/dev/null | openssl x509 -outform DER > moderne_cert.der
# RUN /opt/java/openjdk/bin/keytool -import -trustcacerts -keystore /opt/java/openjdk/lib/security/cacerts -storepass changeit -noprompt -alias moderne-cert -file moderne_cert.der

RUN groupadd -r app && useradd --no-log-init -r -m -g app app && chown -R app:app /app
USER app

# Download the specified version of moderne-agent JAR file if MODERNE_AGENT_VERSION is provided,
# otherwise download the latest version
RUN if [ -n "${MODERNE_AGENT_VERSION}" ]; then \
echo "Downloading version: ${MODERNE_AGENT_VERSION}"; \
curl -s --insecure --request GET --url "https://repo1.maven.org/maven2/io/moderne/moderne-agent/${MODERNE_AGENT_VERSION}/moderne-agent-${MODERNE_AGENT_VERSION}.jar" --output agent.jar; \
else \
LATEST_VERSION=$(curl -s --insecure --request GET --url "https://repo1.maven.org/maven2/io/moderne/moderne-agent/maven-metadata.xml" | xmllint --xpath 'string(/metadata/versioning/latest)' -); \
if [ -z "${LATEST_VERSION}" ]; then \
echo "Failed to retrieve the latest version"; \
exit 1; \
fi; \
echo "Downloading latest version: ${LATEST_VERSION}"; \
curl -s --insecure --request GET --url "https://repo1.maven.org/maven2/io/moderne/moderne-agent/${LATEST_VERSION}/moderne-agent-${LATEST_VERSION}.jar" --output agent.jar; \
fi

ENTRYPOINT ["java"]
CMD ["-XX:-OmitStackTraceInFastThrow", \
"-XX:MaxRAMPercentage=65.0", \
"-XX:MaxDirectMemorySize=2G", \
"-XX:+HeapDumpOnOutOfMemoryError", \
"-XX:+UseStringDeduplication", \
"-jar", "/app/agent.jar"]

Example environment variables file

# Set the environment variables for the MODERNE_AGENT
MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket
MODERNE_AGENT_CRYPTO_SYMMETRICKEY=${SYMMETRIC_KEY}
MODERNE_AGENT_TOKEN=${MODERNE_AGENT_TOKEN}
MODERNE_AGENT_NICKNAME=prod-1

# Set the environment variables for your SCM (E.g. Github, Bitbucket, Gitlab)
MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID=${GITHUB_CLIENT_ID}
MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET=${GITHUB_CLIENT_SECRET}
MODERNE_AGENT_GITHUB_0_URL=https://myorg.github.com
MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_0=moderne
MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_1=openrewrite
MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true

# Set the environment variables for your artifactory
# Remove this part if you can not use the artifactory repository configuration (see step 5)
MODERNE_AGENT_ARTIFACTORY_0_URL=https://myartifactory.example.com/artifactory/
MODERNE_AGENT_ARTIFACTORY_0_USERNAME=${ARTIFACTORY_USERNAME}
MODERNE_AGENT_ARTIFACTORY_0_PASSWORD=${ARTIFACTORY_PASSWORD}
MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_0='"name":{"$match":"*-ast.jar"}'
MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_1='"repo":{"$eq":"example-maven"}'

# Set the environment variables for your artifactory recipe access or your maven repository access
# Remove the `MODERNE_AGENT_MAVEN_0_ASTSOURCE line if you do not use the artifactory repository configuration
MODERNE_AGENT_MAVEN_0_URL=https://myartifactory.example.com/artifactory/libs-releases-local
MODERNE_AGENT_MAVEN_0_ASTSOURCE=false
MODERNE_AGENT_MAVEN_0_LOCALREPOSITORY=~/.moderne-maven
MODERNE_AGENT_MAVEN_0_USERNAME=${MAVEN_USERNAME}
MODERNE_AGENT_MAVEN_0_PASSWORD=${MAVEN_PASSWORD}

Step 3: Configure the agent with the core variables/arguments

All agents must be configured with the variables listed as required below:

Environment variables:

Variable NameRequiredDefaultDescription
MODERNE_AGENT_APIGATEWAYRSOCKETURItrueThe URI used to connect to the Moderne API, provided by Moderne.
MODERNE_AGENT_CRYPTO_SYMMETRICKEYtrueA 256-bit AES encryption key, hex encoded. Used to encrypt your artifacts.
MODERNE_AGENT_NICKNAMEtrueA name used to identify your agent in the SaaS agent dashboard UI.
MODERNE_AGENT_TOKENtrueThe Moderne SaaS agent connection token, provided by Moderne.
MODERNE_AGENT_DOWNLOADPARALLELISMfalse2 threadsHow many threads are used to download LSTs.
MODERNE_AGENT_ARTIFACTINDEXINTERVALSECONDSfalse120 secondsHow frequently LSTs will be indexed.
MODERNE_AGENT_DEFAULTCOMMITOPTIONS_{index}falseAll options available.Use to restrict which commit options are available in Moderne. Acceptable values: Direct, Branch, Fork, PullRequest, ForkAndPullRequest.

Example:

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...

docker run \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
-e MODERNE_AGENT_DEFAULTCOMMITOPTIONS_0=PullRequest \
-e MODERNE_AGENT_DEFAULTCOMMITOPTIONS_1=ForkAndPullRequest \
# ... Additional variables
-p 8080:8080
moderne-agent:latest

Step 4: Configure the agent to work with your SCM(s)

Connecting the agent to your SCM enables Moderne to display recipe results in the UI and commit changes from recipes back to your SCM (in the form of PRs, forks, commits, etc).

For every SCM that you want to connect to Moderne, please follow the instructions in the following guides. These guides will explain how to configure an SCM to talk to the Moderne agent and they will provide you with a list of variables to add to the agent run command. You can configure one agent with multiple SCMs.

SCM configuration:

Below is an example of what an agent run command might look like at the end of this step.

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET=...

docker run \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET \
-e MODERNE_AGENT_GITHUB_0_URL=https://myorg.github.com \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_0=moderne \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_1=openrewrite \
-e MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true \
# ... Additional variables to come
-p 8080:8080
moderne-agent:latest

Step 5: Configure the agent to connect to your artifact repositories

The Moderne agent needs to connect to your artifact repositories for two reasons:

  1. To obtain your LST artifacts so that recipes can be run on your code.
  2. To obtain your recipe artifacts (if any exist). These recipe artifacts contain custom recipes, defined by your team, that perform transformations against your LST artifacts.

Your company might have many artifact repositories, potentially in different products, that you wish to connect the Moderne agent to. Each of these artifact repositories could contain LST artifacts, recipe artifacts, or a combination of both. The setup instructions differ based on what product you use to store your artifact repositories and what artifacts you wish to send to Moderne.

Moderne offers several options for connecting to your artifact storage:

  • Artifactory: Uses AQL (Artifact Query Language) to be able to see your repos in the platform within two minutes after publishing. (recommended for Artifactory users)
  • Maven repository: A generic connection that works with any Maven-formatted repository (Artifactory, Nexus, etc.). Serves both LST and recipe artifacts.
  • Amazon S3: Store and retrieve LST artifacts directly from S3 or S3-compatible storage (e.g., MinIO).
info

For Maven and Artifactory configurations, the Moderne agent connects to Maven formatted artifact repositories. There are a variety of open-source and commercial products that exist that can serve artifacts in this format (such as Artifactory and Sonatype Nexus).

Choosing your artifact source:

The below table shows the key differences between the Maven and Artifactory configurations:

Maven repository configurationArtifactory repository configuration
Is not tied to a particular vendor.Can only be used with Artifactory.
Serves BOTH recipe artifacts and LST artifacts.Serves ONLY LST artifacts. Requires Maven configuration to serve recipe artifacts.
Recipe artifacts are immediately available for deployment to Moderne upon publishing to the Maven formatted repository.Can not serve recipe artifacts without Maven configuration.
LST artifacts may be served if an index in the Maven Indexer format is regularly published to the repository. There will be a considerable delay between when an LST is published to the Maven repository and when it shows up in Moderne. This delay is approximately the delay between updates to the index – which is controlled by a batch process that your artifact repository executes on a schedule.LST artifacts will show up in near-real time (within a minute or two) in the Moderne Platform when they are published to Artifactory. This is because Artifactory configuration uses Artifactory Query Language (AQL) to identify recently published artifacts. AQL queries Artifactory's internal relational database for information about artifacts rather than using an index produced in a batch process.

Please ensure you've followed either the Maven or Artifactory instructions before continuing.

Below is an example of what an agent run command might look like at the end of this step.

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET=...
export MODERNE_AGENT_ARTIFACTORY_0_USERNAME=...
export MODERNE_AGENT_ARTIFACTORY_0_PASSWORD=...
export MODERNE_AGENT_MAVEN_0_USERNAME=...
export MODERNE_AGENT_MAVEN_0_PASSWORD=...

docker run \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET \
-e MODERNE_AGENT_GITHUB_0_URL=https://myorg.github.com \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_0=moderne \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_1=openrewrite \
-e MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true \
-e MODERNE_AGENT_ARTIFACTORY_0_URL=https://myartifactory.example.com/artifactory/ \
-e MODERNE_AGENT_ARTIFACTORY_0_USERNAME \
-e MODERNE_AGENT_ARTIFACTORY_0_PASSWORD \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_0='"name":{"$match":"*-ast.jar"}' \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_1='"repo":{"$eq":"example-maven"}' \
-e MODERNE_AGENT_MAVEN_0_URL=https://myartifactory.example.com/artifactory/libs-releases-local \
-e MODERNE_AGENT_MAVEN_0_LOCALREPOSITORY=~/.moderne-maven \
-e MODERNE_AGENT_MAVEN_0_USERNAME \
-e MODERNE_AGENT_MAVEN_0_PASSWORD \
# ... Additional variables to come
-p 8080:8080
mmoderne-agent:latest

Step 6: (Optionally) Use strict recipe sources.

Some organizations want recipe artifacts to only come from locations configured in the Moderne agent. If you want to configure that, please follow the strict recipe sources instructions.

Below is an example of what an agent run command might look like at the end of this step if you configured the agent to use only configured recipe sources.

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET=...
export MODERNE_AGENT_ARTIFACTORY_0_USERNAME=...
export MODERNE_AGENT_ARTIFACTORY_0_PASSWORD=...
export MODERNE_AGENT_MAVEN_0_USERNAME=...
export MODERNE_AGENT_MAVEN_0_PASSWORD=...

docker run \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET \
-e MODERNE_AGENT_GITHUB_0_URL=https://myorg.github.com \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_0=moderne \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_1=openrewrite \
-e MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true \
-e MODERNE_AGENT_ARTIFACTORY_0_URL=https://myartifactory.example.com/artifactory/ \
-e MODERNE_AGENT_ARTIFACTORY_0_USERNAME \
-e MODERNE_AGENT_ARTIFACTORY_0_PASSWORD \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_0='"name":{"$match":"*-ast.jar"}' \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_1='"repo":{"$eq":"example-maven"}' \
-e MODERNE_AGENT_MAVEN_0_URL=https://myartifactory.example.com/artifactory/libs-releases-local \
-e MODERNE_AGENT_MAVEN_0_LOCALREPOSITORY=~/.moderne-maven \
-e MODERNE_AGENT_MAVEN_0_USERNAME \
-e MODERNE_AGENT_MAVEN_0_PASSWORD \
-e MODERNE_AGENT_RECIPE_USEONLYCONFIGURED=true \
-p 8080:8080
moderne-agent:latest

Step 7: (Optionally) Configure LLM support for Moddy

If you want to enable Moddy (Moderne's AI agent) in your platform, you'll need to configure LLM support. Moddy allows users to interact with their codebase using natural language. Please follow the Moddy configuration instructions to set this up.

If you would like to have an organizational hierarchy available inside of the Moderne Platform, you can provide this information using a repos.csv file.

Using a repos.csv file

A repos.csv file defines your repositories and their organizational structure. The agent can load this file to create organizations in the Moderne Platform.

Required columns:

  • cloneUrl - The URL of the repository
  • branch - The branch to check out
  • origin - The host domain of the repository
  • path - The organization and repository name portion of the clone URL

Optional hierarchy columns:

  • org1, org2, org3, ... - Define parent-child organizational relationships

Organizations on the left are children of organizations on the right. For example, if you have org1=Team1, org2=DirectorA, org3=ALL, then Team1 is a child of DirectorA, which is a child of ALL.

Example repos.csv:

cloneUrl,branch,origin,path,org1,org2,org3
https://github.com/apache/maven-doxia,master,github.com,apache/maven-doxia,Team 1,Director A,ALL
https://github.com/Netflix/photon,main,github.com,Netflix/photon,Team 2,Director A,ALL
https://github.com/Netflix/ribbon,master,github.com,Netflix/ribbon,Director A,ALL

Loading the repos.csv file:

You can provide the file to the agent in two ways:

  1. Remote URL: Set the environment variable to point to a hosted CSV file
  2. Local file: Mount the file into the container and configure the path

Option 1: Remote URL

docker run \
-e MODERNE_AGENT_ORGANIZATION_REPOSCSV=https://example.com/repos.csv \
# ... other environment variables
moderne-agent:latest

Option 2: Local file mount

docker run \
-v /path/to/repos.csv:/app/repos.csv \
-e MODERNE_AGENT_ORGANIZATION_REPOSCSV=/app/repos.csv \
# ... other environment variables
moderne-agent:latest
tip

For detailed information about creating and formatting a repos.csv file, including how to handle different SCM providers and define complex organizational hierarchies, see the creating a repos.csv file guide.

Alternative configuration:

If you need more advanced organizational configuration options, you can also configure an organizational hierarchy using other methods and let the agent know about it.

Step 9: (Optionally) Create an Organizations service

You should create an Organizations service if you want to:

  • Limit access to the organizations you've previously defined so that some users only have access to some repositories OR
  • Customize commit messages by repository (e.g., adding a JIRA ticket to your commit messages based on the repository)

To do so, please follow the instructions in our creating an Organizations service guide and then let the agent know about it.

Step 10: (Optionally) Configure a DevCenter

The DevCenter is the mission-control dashboard of the Moderne Platform. If you wish to have DevCenters available inside of the Moderne Platform, you will need to ensure you've defined an organizational hierarchy and then follow the instructions for configuring a DevCenter.

Step 11: (Optionally) Provide SSL client keystore

If you have configured any services that require client SSL certificates (such as Maven or Artifactory), you will need to provide a KeyStore with these certificates. Please follow these instructions to configure the KeyStore.

Step 12: Run the agent

At this point, you should have configured everything needed to run the Moderne agent. If you run into issues running the command, please don't hesitate to reach out.

Below is a table that has instructions for how to run the agent in combination with some examples of the variables/arguments provided in the previous steps:

How to build the Docker image

docker build -t moderne-agent:latest .

How to run the Docker image with an environment file

docker run --env-file=moderne-agent.env moderne-agent:latest

Run the docker run command in combination with all of the environment variables you've added in the previous steps:

# Please note that if you create environment variables for secrets, you still need to let Docker
# know that these variables exist by including it via: `-e ENV_VAR_NAME`.
export MODERNE_AGENT_CRYPTO_SYMMETRICKEY=...
export MODERNE_AGENT_TOKEN=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID=...
export MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET=...
export MODERNE_AGENT_ARTIFACTORY_0_USERNAME=...
export MODERNE_AGENT_ARTIFACTORY_0_PASSWORD=...
export MODERNE_AGENT_MAVEN_0_USERNAME=...
export MODERNE_AGENT_MAVEN_0_PASSWORD=...

docker run \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
-e MODERNE_AGENT_CRYPTO_SYMMETRICKEY \
-e MODERNE_AGENT_NICKNAME=prod-1 \
-e MODERNE_AGENT_TOKEN \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID \
-e MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET \
-e MODERNE_AGENT_GITHUB_0_URL=https://myorg.github.com \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_0=moderne \
-e MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_1=openrewrite \
-e MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true \
-e MODERNE_AGENT_ARTIFACTORY_0_URL=https://myartifactory.example.com/artifactory/ \
-e MODERNE_AGENT_ARTIFACTORY_0_USERNAME \
-e MODERNE_AGENT_ARTIFACTORY_0_PASSWORD \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_0='"name":{"$match":"*-ast.jar"}' \
-e MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_1='"repo":{"$eq":"example-maven"}' \
-e MODERNE_AGENT_MAVEN_0_URL=https://myartifactory.example.com/artifactory/libs-releases-local \
-e MODERNE_AGENT_MAVEN_0_LOCALREPOSITORY=~/.moderne-maven \
-e MODERNE_AGENT_MAVEN_0_USERNAME \
-e MODERNE_AGENT_MAVEN_0_PASSWORD \
-p 8080:8080
moderne-agent:latest

Health endpoints

Once the agent is running, you can verify its health and readiness using the following endpoints:

  • /actuator/health - Returns the overall health status of the agent
  • /actuator/health/liveness - Kubernetes liveness probe endpoint
  • /actuator/health/readiness - Kubernetes readiness probe endpoint

Example health check:

curl http://localhost:8080/actuator/health

Expected response:

{"status":"UP"}

These endpoints are particularly useful for:

  • Kubernetes/Docker health checks and readiness probes
  • Load balancer health checks
  • Monitoring system integration
  • Automated deployment verification

Monitoring

The Moderne agent exposes Prometheus-compatible metrics that can be used for monitoring and observability.

Prometheus metrics endpoint

The agent exposes metrics at /actuator/prometheus on port 8080.

Example Prometheus scrape configuration:

scrape_configs:
- job_name: 'moderne-agent'
static_configs:
- targets: ['localhost:8080']
metrics_path: '/actuator/prometheus'

Grafana dashboard

A pre-built Grafana dashboard is available in the moderne-agent-example repository. The dashboard provides visualizations for:

  • Agent connectivity status
  • LST indexing performance
  • Artifact download metrics
  • Resource utilization
  • Error rates

To use the dashboard:

  1. Import moderne-agent-dashboard-v1.json into your Grafana instance
  2. Select your Prometheus datasource when prompted
  3. The dashboard will automatically populate with metrics from your agent(s)

Scaling considerations

For high availability and increased throughput, you can run multiple Moderne agent instances concurrently.

Key requirements for multi-instance deployment:

  • Each agent instance must have a unique MODERNE_AGENT_NICKNAME
  • Each instance requires its own port mapping (e.g., 8080, 8081, 8082)
  • All instances should use the same MODERNE_AGENT_CRYPTO_SYMMETRICKEY
  • All instances should connect to the same MODERNE_AGENT_APIGATEWAYRSOCKETURI

Example multi-instance deployment:

# First agent instance
docker run -d \
--name moderne-agent-1 \
-p 8080:8080 \
-e MODERNE_AGENT_NICKNAME=prod-agent-1 \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
# ... other environment variables
moderne-agent:latest

# Second agent instance
docker run -d \
--name moderne-agent-2 \
-p 8081:8080 \
-e MODERNE_AGENT_NICKNAME=prod-agent-2 \
-e MODERNE_AGENT_APIGATEWAYRSOCKETURI=https://api.tenant.moderne.io/rsocket \
# ... other environment variables
moderne-agent:latest

Multiple agent instances will automatically distribute the workload and provide redundancy in case of individual agent failures.

Troubleshooting

Connection failures

Symptoms: Agent fails to connect to Moderne API or shows connection errors in logs.

Common causes and solutions:

  • Invalid API endpoint: Verify the MODERNE_AGENT_APIGATEWAYRSOCKETURI matches the URI provided by Moderne
  • Invalid authentication token: Confirm the MODERNE_AGENT_TOKEN is correct and has not expired
  • Network connectivity: Ensure the agent can reach the Moderne API endpoint (check firewalls, proxies, and outbound HTTPS access)
  • SSL/TLS issues: If using custom certificates, verify they are properly configured in the Java truststore

DNS resolution failures in Podman containers

Symptoms: Agent fails to start with errors like:

WebClientRequestException: Failed to resolve 'hostname' [A(1)] and search domain query for configured domains failed as well: [dns.podman]

Cause: The agent uses Netty's async DNS resolver, which directly queries DNS servers via UDP. In Podman's bridged networking mode, this can bypass Podman's DNS forwarding mechanism.

Solution: Use host networking mode when running the agent container:

podman run --network host ...

This allows the agent to use the host's network stack directly, including its DNS resolution.

Missing repositories

Symptoms: Expected repositories do not appear in the Moderne Platform.

Common causes and solutions:

  • SCM OAuth configuration: Verify OAuth credentials (MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTID, MODERNE_AGENT_GITHUB_0_OAUTH_CLIENTSECRET, etc.) are correct
  • Organization allowlists: Check that MODERNE_AGENT_GITHUB_0_ALLOWABLE_ORGANIZATIONS_* includes all necessary organizations
  • OAuth app permissions: Ensure the OAuth application has been granted access to the repositories (may require organization admin approval)
  • Private repository access: Verify MODERNE_AGENT_GITHUB_0_OAUTH_INCLUDEPRIVATEREPOS=true is set if accessing private repositories

Absent LSTs

Symptoms: Repositories appear in Moderne but LST artifacts are not available for running recipes.

Common causes and solutions:

  • Artifact repository configuration: Verify Maven or Artifactory repository settings (URLs, credentials)
  • AQL filters (Artifactory): Check that MODERNE_AGENT_ARTIFACTORY_0_ASTQUERYFILTERS_* correctly matches your LST artifacts
  • Maven indexing: If using Maven repository configuration, ensure the Maven index is being published and updated regularly
  • Artifact publication: Confirm LST artifacts are actually being published to the configured repository
  • Network access: Verify the agent can reach the artifact repository from its network location

Checking agent logs

Most issues can be diagnosed by examining the agent logs. Look for:

  • Connection errors or authentication failures
  • Repository discovery issues
  • Artifact indexing errors
  • Network timeouts or connectivity problems

Updating your agent

If you want to update the Moderne agent over time, please follow the instructions in the table below:

If you're running the commands provided in this guide, you should see that the last line of every agent run command is moderne-agent:latest.

If that's true, then you can rebuild the agent image and it should pick up the latest version. If you've decided to pin the version to something else instead of latest, please see our releases page for the versions.