JFrog Artifactory: Setup, Repository Configuration, and Pipeline Integration
Artifactory vs Nexus
Both Artifactory and Nexus are universal artifact repositories. The key differences:
- Artifactory has broader ecosystem integration (Artifactory CLI, JFrog Pipelines, Xray)
- Artifactory supports 30+ package types natively, including Conan (C++) and Conda
- JFrog Cloud (SaaS) is a mature option; Nexus doesn't have a comparable hosted offering
- Xray (JFrog's security scanner) integrates deeply with Artifactory at the artifact level
Artifactory's free OSS tier covers most use cases. Pro and Enterprise add features like replication, access federation, and release lifecycle management.
Installation
Docker Compose (Recommended for Self-Hosted)
# docker-compose.yml
version: '3'
services:
artifactory:
image: releases-docker.jfrog.io/jfrog/artifactory-oss:latest
container_name: artifactory
restart: unless-stopped
ports:
- "8081:8081" # Artifactory UI
- "8082:8082" # Artifactory access
volumes:
- /opt/artifactory/data:/var/opt/jfrog/artifactory
environment:
- JF_ROUTER_ENTRYPOINTS_EXTERNALPORT=8082
ulimits:
nproc: 65535
nofile:
soft: 32000
hard: 40000
mkdir -p /opt/artifactory/data
chown -R 1030:1030 /opt/artifactory/data # UID 1030 = artifactory user
docker-compose up -d
Access at http://your-server:8082/ui. Default credentials: admin / password (change immediately).
Kubernetes via Helm
helm repo add jfrog https://charts.jfrog.io
helm repo update
helm upgrade --install artifactory jfrog/artifactory \
--namespace artifactory \
--create-namespace \
--set artifactory.persistence.size=100Gi \
--set postgresql.postgresqlPassword=strong_password
Repository Types
Artifactory has three repository types (same concept as Nexus):
| Type | Purpose |
|---|---|
| Local | Store artifacts you produce |
| Remote | Proxy and cache an external repository |
| Virtual | Aggregate local + remote under one URL |
Creating Repositories via REST API
# Create a local Docker repository
curl -u admin:password -X PUT \
"http://artifactory.example.com:8082/artifactory/api/repositories/docker-local" \
-H "Content-Type: application/json" \
-d '{
"rclass": "local",
"packageType": "docker",
"description": "Internal Docker images"
}'
# Create a remote (proxy) for Docker Hub
curl -u admin:password -X PUT \
"http://artifactory.example.com:8082/artifactory/api/repositories/docker-hub-remote" \
-H "Content-Type: application/json" \
-d '{
"rclass": "remote",
"packageType": "docker",
"url": "https://registry-1.docker.io/",
"description": "Docker Hub proxy"
}'
# Create a virtual combining both
curl -u admin:password -X PUT \
"http://artifactory.example.com:8082/artifactory/api/repositories/docker" \
-H "Content-Type: application/json" \
-d '{
"rclass": "virtual",
"packageType": "docker",
"repositories": ["docker-local", "docker-hub-remote"],
"defaultDeploymentRepo": "docker-local"
}'
Docker Registry
Configure Docker to use Artifactory:
# Login (using the virtual repo)
docker login artifactory.example.com:8082 -u developer -p yourpassword
# Tag and push
docker tag myapp:latest artifactory.example.com:8082/docker-local/myapp:latest
docker push artifactory.example.com:8082/docker-local/myapp:latest
# Pull (routes through virtual repo — checks local first, then remote)
docker pull artifactory.example.com:8082/docker/nginx:alpine
For HTTP (non-SSL dev environments):
{
"insecure-registries": ["artifactory.example.com:8082"]
}
Maven Integration
Configure ~/.m2/settings.xml:
<settings>
<mirrors>
<mirror>
<id>central</id>
<mirrorOf>*</mirrorOf>
<url>http://artifactory.example.com:8082/artifactory/maven-virtual/</url>
</mirror>
</mirrors>
<servers>
<server>
<id>central</id>
<username>developer</username>
<password>yourpassword</password>
</server>
<server>
<id>snapshots</id>
<username>developer</username>
<password>yourpassword</password>
</server>
</servers>
</settings>
pom.xml:
<distributionManagement>
<repository>
<id>central</id>
<name>releases</name>
<url>http://artifactory.example.com:8082/artifactory/libs-release-local/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>snapshots</name>
<url>http://artifactory.example.com:8082/artifactory/libs-snapshot-local/</url>
</snapshotRepository>
</distributionManagement>
JFrog CLI: The Preferred Integration Method
The JFrog CLI (jf) handles authentication, publishing, build info, and promotion:
# Install
curl -fL https://install-cli.jfrog.io | sh
# Configure
jf config add myserver \
--url http://artifactory.example.com:8082 \
--user admin \
--password yourpassword
# Upload artifacts
jf rt upload "target/*.jar" libs-release-local/com/example/myapp/1.0.0/
# Download artifacts
jf rt download libs-release-local/com/example/myapp/1.0.0/ ./downloads/
# Publish build info (links artifacts to CI build)
jf rt build-publish myapp-build 42
# Promote a build from staging to production
jf rt build-promote myapp-build 42 libs-production-local \
--source-repo libs-staging-local \
--status Deployed \
--comment "QA approved"
CLI in GitHub Actions
- name: Setup JFrog CLI
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: ${{ secrets.ARTIFACTORY_URL }}
JF_ACCESS_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
- name: Build and publish
run: |
jf mvn clean deploy
jf rt build-publish ${{ github.repository }} ${{ github.run_number }}
Artifactory Query Language (AQL)
AQL is how you search Artifactory programmatically — useful for finding artifacts, checking what's deployed, or building promotion logic:
# Find all Docker images tagged "latest" newer than 7 days
curl -u admin:password \
-H "Content-Type: text/plain" \
-d 'items.find({
"repo": "docker-local",
"name": {"$match": "manifest.json"},
"created": {"$gt": "2026-03-25T00:00:00.000Z"}
}).include("name", "repo", "path", "created", "size")' \
http://artifactory.example.com:8082/artifactory/api/search/aql
# Find artifacts never downloaded (orphan cleanup candidates)
curl -u admin:password \
-H "Content-Type: text/plain" \
-d 'items.find({
"repo": "libs-snapshot-local",
"stat.downloads": {"$eq": null},
"created": {"$lt": "2025-10-01T00:00:00.000Z"}
}).include("name", "repo", "path", "created")' \
http://artifactory.example.com:8082/artifactory/api/search/aql
Access Control
Artifactory uses Permission Targets → Groups → Users:
# Create a group via REST API
curl -u admin:password -X PUT \
"http://artifactory.example.com:8082/artifactory/api/security/groups/developers" \
-H "Content-Type: application/json" \
-d '{"name":"developers","description":"Developer team"}'
# Create permission target (read on all repos for developers)
curl -u admin:password -X PUT \
"http://artifactory.example.com:8082/artifactory/api/security/permissions/developer-read" \
-H "Content-Type: application/json" \
-d '{
"name": "developer-read",
"repositories": ["ANY"],
"principals": {
"groups": {
"developers": ["r", "n"]
}
}
}'
Privilege codes: r=read, n=annotate, d=delete, w=deploy/cache, m=manage, managedXrayMeta=Xray metadata.
Cleanup Policies
# Delete artifacts not downloaded in 90 days from snapshots repo
jf rt delete "libs-snapshot-local/*" \
--spec '{"files":[{"aql":"items.find({\"repo\":\"libs-snapshot-local\",\"stat.downloads\":{\"$eq\":null},\"created\":{\"$lt\":\"relative_to=-90d\"}})"}]}'
# Or use the built-in Artifactory Cleanup job in the UI:
# Admin → Maintenance → Cleanup → Create cleanup policy
Was this article helpful?
CI/CD Engineering Lead
Automation evangelist who believes no deployment should require a human. I write pipelines, break pipelines, and write about both. Code-first, always.
Related Articles
Integrating Nexus Repository with CI/CD Pipelines: GitHub Actions, Jenkins, and Security Scanning
How to integrate Nexus Repository Manager into GitHub Actions and Jenkins pipelines — publishing artifacts, pulling from proxy repos, tagging releases, and using Nexus IQ for security scanning.
Nexus Repository Manager: Setup, Docker Registry, and Maven/npm Proxy
How to install and configure Sonatype Nexus Repository Manager 3 — setting up hosted, proxy, and group repositories for Docker, Maven, and npm, with access control and cleanup policies.
JFrog Artifactory: Repository Setup and Access Control
Install JFrog Artifactory, configure local, remote, and virtual repositories, set up Docker registries, and manage permissions with access control.
JFrog Xray: Artifact Security Scanning, License Compliance, and Policy Enforcement
How to use JFrog Xray to scan Docker images, Maven JARs, and npm packages for CVEs and license violations — setting up security policies, watching repositories, and blocking builds with policy violations.
JFrog Artifactory as Your Docker Registry: Setup and Security
Configure JFrog Artifactory as a production Docker registry with virtual repos, access control, image promotion, and cleanup policies.
Container Supply Chain Security With Sigstore and Cosign
Sign and verify your container images with Sigstore Cosign to prevent supply chain attacks — with keyless signing, SBOM attestation, and Kubernetes admission enforcement.