How to setup JFrog Artifactory and Publish maven artifacts
Here in this article we will try to setup JFrog Artifactory using the OSS package and publish a sample maven artifacts to the JFrog Artifactory repository.
Test Environment
- Fedora 41 server
Procedure
Step1: Ensure Docker installed
As a pre-requisite step ensure that docker and docker-compose is installed and running.
admin@fedser:~$ docker -v
Docker version 23.0.1, build a5ee5b1
admin@fedser:~$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
admin@fedser:~$ sudo systemctl status docker.service
[sudo] password for admin:
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; preset: disabled)
Active: active (running) since Tue 2023-02-28 11:53:22 IST; 4h 30min ago
Step2: Ensure Maven installed
Here we will install maven which is a build tool we will be using to build pom based java project.
admin@fedser:~$ sudo dnf install maven
Step3: Setup JFROG Home directory
Let’s first create a JFROG home directory for data persistence and export it as environment variable by updated the .bashrc file.
admin@fedser:~$ sudo mkdir -p /usr/local/jfrog
admin@fedser:~$ cat ~/.bashrc | grep JFROG
## JFROG Home
export JFROG_HOME=/usr/local/jfrog
Step4: Download and Extract JFROG docker compose archive
Now let’s download and extract the JFROG docker compose archive package. Here we are downloading the OSS type package for this demo.
admin@fedser:~$ curl -g -L -O -J 'https://releases.jfrog.io/artifactory/bintray-artifactory/org/artifactory/oss/docker/jfrog-artifactory-oss/7.133.17/jfrog-artifactory-oss-7.133.17-compose.tar.gz'
admin@fedser:~$ tar -xvf jfrog-artifactory-oss-7.133.17-compose.tar.gz
Step5: Setup Folders for data persistence
Let’s create sub directories within the JFROG home directory and update the ownership as shown below. JFROG service uses (uid: 1030 and gid: 1030) within the container.
admin@fedser:~$ mkdir -p $JFROG_HOME/artifactory/var
admin@fedser:~$ mkdir -p $JFROG_HOME/artifactory/var/data
admin@fedser:~$ mkdir -p $JFROG_HOME/artifactory/var/etc
Update ownership for the folder structure as below.
admin@fedser:~$ sudo chown -R 1030:1030 $JFROG_HOME/artifactory/var
admin@fedser:~$ sudo chown -R 1030:1030 $JFROG_HOME/artifactory/var/data
admin@fedser:~$ sudo chown -R 1030:1030 $JFROG_HOME/artifactory/var/etc
Step6: Update .env hidden file
Here in this step we are going the updated .env file with “ROOT_DATA_DIR” and node ip and name details as shown below. Update it with your respective hostname and ip address.
admin@fedser:artifactory-oss-7.133.17$ cat .env
## This file contains environment variables used by the docker-compose yaml files
## IMPORTANT: During installation, this file may be updated based on user choices or existing configuration
## Docker registry to fetch images from
DOCKER_REGISTRY=releases-docker.jfrog.io
## Version of artifactory to install
ARTIFACTORY_VERSION=7.133.17
## The Installation directory for Artifactory. IF not entered, the script will prompt you for this input. Default [$HOME/.jfrog/artifactory]
ROOT_DATA_DIR=$JFROG_HOME/artifactory
## Router external port mapping. This property may be overridden from the system.yaml (router.entrypoints.externalPort)
JF_ROUTER_ENTRYPOINTS_EXTERNALPORT=8082
## Nginx logrotation configuration
NGINX_LOG_ROTATE_COUNT=
NGINX_LOG_ROTATE_SIZE=
JF_SHARED_NODE_IP=192.168.29.117
JF_SHARED_NODE_ID=fedser.stack.com
JF_SHARED_NODE_NAME=fedser.stack.com
Step7: Create and Update system.yaml
Ensure that you create a system.yaml file with the following ownership (ie. artifactory uid: 1030 and gid: 1030) as shown below.
admin@fedser:artifactory-oss-7.133.17$ ls -ltr system.yaml
-rw-r--r--. 1 1030 1030 2605 Apr 14 08:14 system.yaml
Update the system.yaml file such that jfconnect service is disabled to ensure entitlement checks are not carried out as we are using the OSS type of JFROG package.
admin@fedser:artifactory-oss-7.133.17$ cat system.yaml
## @formatter:off
## JFROG ARTIFACTORY SYSTEM CONFIGURATION FILE
## HOW TO USE: comment-out any field and keep the correct yaml indentation by deleting only the leading '#' character.
configVersion: 1
## NOTE: JFROG_HOME is a place holder for the JFrog root directory containing the deployed product, the home directory for all JFrog products.
## Replace JFROG_HOME with the real path! For example, in RPM install, JFROG_HOME=/opt/jfrog
## NOTE: Sensitive information such as passwords and join key are encrypted on first read.
## NOTE: The provided commented key and value is the default.
## SHARED CONFIGURATIONS
## A shared section for keys across all services in this config
shared:
## Java 21 distribution to use
#javaHome: "JFROG_HOME/artifactory/app/third-party/java"
## Extra Java options to pass to the JVM. These values add to or override the defaults.
#extraJavaOpts: "-Xms512m -Xmx2g"
## Security Configuration
security:
## Join key value for joining the cluster (takes precedence over 'joinKeyFile')
# joinKey: "<Your joinKey>"
## Join key file location
# joinKeyFile: "<For example: JFROG_HOME/artifactory/var/etc/security/join.key>"
## Master key file location
## Generated by the product on first startup if not provided
# masterKeyFile: "<For example: JFROG_HOME/artifactory/var/etc/security/master.key>"
## Maximum time to wait for key files (master.key and join.key)
# bootstrapKeysReadTimeoutSecs: 120
#
## Node Settings
node:
## A unique id to identify this node.
## Default auto generated at startup.
id: "fedser.stack.com"
## Default auto resolved by startup script
ip: 192.168.29.117
## Sets this node as primary in HA installation
# primary: true
## Sets this node as part of HA installation
# haEnabled: true
## Database Configuration
database:
## To run Artifactory with any database other than PostgreSQL allowNonPostgresql set to true.
# allowNonPostgresql: false
## One of mysql, oracle, mssql, postgresql, mariadb
## Default Embedded derby
## Example for postgresql
# type: postgresql
# driver: org.postgresql.Driver
# url: "jdbc:postgresql://<your db url, for example: localhost:5432>/artifactory"
# username: artifactory
# password: password
access:
## Extra Java options to pass to the JVM. These values add to or override the defaults.
#extraJavaOpts: "-XX:InitialRAMPercentage=20 -XX:MaxRAMPercentage=25"
## JFCONNECT TEMPLATE
jfconnect:
enabled: false
Step8: Copy and Update Docker Compose file
In this step switch to the directory where the JFROG archive package is extracted and copy the following template docker compose file to the root directory location.
admin@fedser:artifactory-oss-7.133.17$ cp templates/docker-compose-volumes.yaml docker-compose.yaml
Now we need to update the docker-compose.yaml file volumes section such that it uses the manually created host level folder structure for the data persistence rather than docker volumes. Also we need to volume mount the system.yaml file into the artifactory service to disable entitlement checks.
admin@fedser:artifactory-oss-7.133.17$ cat docker-compose.yaml
version: '3'
services:
postgres:
image: ${DOCKER_REGISTRY}/postgres:17.6-alpine
container_name: postgresql
environment:
- POSTGRES_DB=artifactory
- POSTGRES_USER=artifactory
- POSTGRES_PASSWORD=password
ports:
- 5432:5432
volumes:
- ${ROOT_DATA_DIR}/var/data/postgres/data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
#restart: always
logging:
driver: json-file
options:
max-size: "50m"
max-file: "10"
ulimits:
nproc: 65535
nofile:
soft: 32000
hard: 40000
artifactory:
image: ${DOCKER_REGISTRY}/jfrog/artifactory-oss:${ARTIFACTORY_VERSION}
container_name: artifactory
volumes:
- ${ROOT_DATA_DIR}/var:/var/opt/jfrog/artifactory
- ./system.yaml:/var/opt/jfrog/artifactory/etc/system.yaml
- /etc/localtime:/etc/localtime:ro
#restart: always
depends_on:
- postgres
ulimits:
nproc: 65535
nofile:
soft: 32000
hard: 40000
environment:
- ENABLE_MIGRATION=y
- JF_SHARED_DATABASE_TYPE=postgresql
# The following must match the POSTGRES_USER and POSTGRES_PASSWORD values passed to PostgreSQL
- JF_SHARED_DATABASE_USERNAME=artifactory
- JF_SHARED_DATABASE_PASSWORD=password
- JF_SHARED_DATABASE_URL=jdbc:postgresql://postgresql:5432/artifactory
- JF_SHARED_DATABASE_DRIVER=org.postgresql.Driver
- JF_SHARED_NODE_IP=${JF_SHARED_NODE_IP}
- JF_SHARED_NODE_ID=${JF_SHARED_NODE_ID}
- JF_SHARED_NODE_NAME=${JF_SHARED_NODE_NAME}
- JF_ROUTER_ENTRYPOINTS_EXTERNALPORT=${JF_ROUTER_ENTRYPOINTS_EXTERNALPORT}
ports:
- ${JF_ROUTER_ENTRYPOINTS_EXTERNALPORT}:${JF_ROUTER_ENTRYPOINTS_EXTERNALPORT} # for router communication
- 8081:8081 # for artifactory communication
logging:
driver: json-file
options:
max-size: "50m"
max-file: "10"
volumes:
artifactory_data:
external: true
postgres_data:
external: true
Step9: Instantiate JFROG and Postgres services
It’s time to start up our JFROG service as shown below.
admin@fedser:artifactory-oss-7.133.17$ docker compose up -d
Step10: Validate JFROG service
We can validate the JFROG service with the default credentials.
user: admin
pass: password
URL: http://fedser.stack.com:8082/ui
Step11: Create a JFROG maven repository
Let’s now create a maven repository from the JFROG portal as shown below.

Step12: Generate a sample maven project
Here we are going to generate a sample maven project using the mvn build tool.
admin@fedser:~$ mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
Step13: Update pom.xml and settings.xml
Let’s now update the pom.xml with “dependencyManagement” section details which we can get from the respository deploy section.

admin@fedser:my-app$ cat pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<!-- Optionally: parameterized tests support -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.6.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<distributionManagement>
<repository>
<id>central</id>
<name>fedser-maventest-releases</name>
<url>http://fedser.stack.com:8081/artifactory/maventest</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>fedser-maventest-snapshots</name>
<url>http://fedser.stack.com:8081/artifactory/maventest</url>
</snapshotRepository>
</distributionManagement>
</project>
Create and Update “~/.m2/settings.xml” file with the releases and snapshots repository credentials to connect. As we have created the repository with Stage as DEV, we will be using this repository to upload snapshot artifacts. Ensure snapshotRepository id and server id matches.
admin@fedser:~$ cat ~/.m2/settings.xml
<settings>
<servers>
<server>
<id>releases</id>
<username>admin</username>
<password>password</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>password</password>
</server>
</servers>
</settings>
Step14: Publish maven artifact
Now let’s try to deploy the application which basically will build the jar package and upload it to the connected JFROG artifactory repository.
admin@fedser:my-app$ mvn deploy
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.mycompany.app:my-app >----------------------
[INFO] Building my-app 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ my-app ---
[INFO] skip non existing resourceDirectory /home/admin/middleware/stack/vscodeprojects/my-app/src/main/resources
[INFO]
[INFO] --- compiler:3.13.0:compile (default-compile) @ my-app ---
[INFO] Nothing to compile - all classes are up to date.
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ my-app ---
[INFO] skip non existing resourceDirectory /home/admin/middleware/stack/vscodeprojects/my-app/src/test/resources
[INFO]
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ my-app ---
[INFO] Nothing to compile - all classes are up to date.
[INFO]
[INFO] --- surefire:3.3.0:test (default-test) @ my-app ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.mycompany.app.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.034 s -- in com.mycompany.app.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jar:3.4.2:jar (default-jar) @ my-app ---
[INFO]
[INFO] --- install:3.1.2:install (default-install) @ my-app ---
[INFO] Installing /home/admin/middleware/stack/vscodeprojects/my-app/pom.xml to /home/admin/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.pom
[INFO] Installing /home/admin/middleware/stack/vscodeprojects/my-app/target/my-app-1.0-SNAPSHOT.jar to /home/admin/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- deploy:3.1.2:deploy (default-deploy) @ my-app ---
Downloading from snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/maven-metadata.xml
Downloaded from snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/maven-metadata.xml (767 B at 8.4 kB/s)
Uploading to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20260414.074426-3.pom
Uploaded to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20260414.074426-3.pom (3.5 kB at 53 kB/s)
Uploading to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20260414.074426-3.jar
Uploaded to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20260414.074426-3.jar (2.9 kB at 62 kB/s)
Downloading from snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/maven-metadata.xml
Downloaded from snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/maven-metadata.xml (370 B at 46 kB/s)
Uploading to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/maven-metadata.xml
Uploaded to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/1.0-SNAPSHOT/maven-metadata.xml (767 B at 51 kB/s)
Uploading to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/maven-metadata.xml
Uploaded to snapshots: http://fedser.stack.com:8081/artifactory/maventest/com/mycompany/app/my-app/maven-metadata.xml (315 B at 17 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.638 s
[INFO] Finished at: 2026-04-14T09:44:28+02:00
[INFO] ------------------------------------------------------------------------
Step15: Validate maven artifact in JFROG
Here you can navigate in the JFROG portal to the Artifacts section and verify that the artifact has been uploaded.

Hope you enjoyed reading this article. Thank you..
Leave a Reply
You must be logged in to post a comment.