Skip to content

Instantly share code, notes, and snippets.

@wadoon
Forked from EronWright/README.md
Last active December 4, 2018 11:34
Show Gist options
  • Save wadoon/889176bca29511aeaaf666a4d9564090 to your computer and use it in GitHub Desktop.
Save wadoon/889176bca29511aeaaf666a4d9564090 to your computer and use it in GitHub Desktop.
Simple Maven repository hosted on Apache httpd web server

Simple Maven Repository

Hosting a shared Maven repository on a remote server may be accomplished with a simple web server such as Apache HTTP server. This works because most of the resolution and publishing logic of Maven is implemented in the client.
By using a small helper, this solution works fully automatically.

Caution: this example exposes a writable directory without any authentication. You need protect the PUT method via the apache configuration.

Configure Apache HTTP

Briefly, the idea is GET request are handled by apache default mechanism, PUT requests are handled by our helper script.

(Here we assume Fedora.)

Define a virtual host for your repository. Create a configuration file named /etc/httpd/conf.d/httpd-maven2.conf:

VirtualHost *:80>
    DocumentRoot "/var/repository/root"
    ErrorLog "/var/repository/log/error_log"
    CustomLog "/var/repository/log/access_log" common
    
    <Directory /var/repository/root>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

	<RequireAny>
            Require method GET PUT DELETE POST OPTIONS
        </RequireAny>
    
	RewriteEngine on
	RewriteCond %{REQUEST_METHOD} =PUT
	RewriteRule ^(.*) /cgi-bin/submit.py/$1
     </Directory>
</VirtualHost>

Adjust the port number 80 as appropriate, or add the directory to an already exsisting host.

Ensure Unix permission on /var/repository/root and also SELinux permission:

semanage fcontext -a -t httpd_sys_rw_content_t "/var/repository/root"
restorecon -R /var/repository/root/

Store the submit.py script into /var/www/cgi-bin/.

You can test your setup with:

$ curl -X PUT http://<host>:<port>/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20180918.221651-1.jar 
              --upload-file target/my-app-1.0-SNAPSHOT.jar    

The file should be stored under /var/repository/root/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-20180918.221651-1.jar.

Configure your Maven project

Configure your project to upload to your server. In pom.xml:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>my-app</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>


  <distributionManagement>
    <repository>
      <id>myrepo</id>
      <name>My Repository</name>
      <url>http://<host>:<ip></url>
    </repository>
  </distributionManagement>
</project>

Publish

At last you should be able to publish to the server.

$ mvn deploy
#!/usr/bin/python
REPOSITORY_BASE = "/var/repository/root/"
print("Content-Type: text/html")
print("")
import cgi, sys, os, cgitb
cgitb.enable()
file_content = sys.stdin.read()
rel_path = os.environ["REDIRECT_URL"]
store_path = os.path.abspath(os.path.join(REPOSITORY_BASE, rel_path[1:]))
print("Store path:", store_path)
# security check: store path needs to be in the repository
if store_path[:len(REPOSITORY_BASE)] != REPOSITORY_BASE:
print("Security check hit", store_path[:len(REPOSITORY_BASE)], "!=", REPOSITORY_BASE)
sys.exit(1)
try:
parent_dir = os.path.dirname(store_path)
os.makedirs(parent_dir, 0775)
except OSError: pass
with open(store_path, "wb") as fh:
fh.write(file_content)
print("ok.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment