Search code examples
dockerdocker-composenexussonatype

How can I create a docker container of sonatype/nexus with a default user and password?


My docker-compose is the simple:

version: "3"

services:

  nexus:
    container_name: nexus
    image: sonatype/nexus:2.14.5-02
    ports:
      - "8081:8081"

  ...
  (some other services)

Right now, I have to start this up and then log in as admin to create a company user. Could I add a custom user by passing a custom config as a volume? If so, what is that config? Or is there another way to do this.

Note, I also tried creating the container, adding the user, creating an image. This didn't work, the user disappeared on restart.


Solution

  • Only works with Nexus 2.x (Nexus 3 uses an embedded database OrientDB) :

    Found a solution through some more experimentation. To create a custom user on start up for the sonatype/nexus docker image:

    1. Start up a sonatype/nexus manually, in the browser login as admin, create your custom user and assign it at least one role.
    2. Save ${SONATYPE_WORK}/conf/security.xml to your local disk. This is necessary because the password needs to be encoded. The decryption key doesn't change across containers of the same image.
    3. Create a wrapper shell script for the command in docker-compose.yaml. This will contain at least three steps:

      A. run the nexus app as a background process (this I copied from the parent Dockerfile's CMD and added & to it) ${JAVA_HOME}/bin/java \ -Dnexus-work=${SONATYPE_WORK} -Dnexus-webapp-context-path=${CONTEXT_PATH} \ -Xms${MIN_HEAP} -Xmx${MAX_HEAP} \ -cp 'conf/:lib/*' \ ${JAVA_OPTS} \ org.sonatype.nexus.bootstrap.Launcher ${LAUNCHER_CONF} &

      B. after the nexus app has started(I added a 5 seconds sleep here for simplicity) copy the saved security.xml to ${SONATYPE_WORK}/conf/security.xml. This should have been loaded in the docker-compose.yaml to the container ANYWHERE BUT ${SONATYPE_WORK}/conf, this would have crashed the nexus app on startup (I can only speculate why...)

      C. execute any perpetuous command so the container doesn't exit. An idea is to reattach the nexus app back to the shell. Also a tail -f /path/to/something.txt would work.

    Now you should be able to run docker-compose up and log in with your custom user on the browser.

    For reference here are my files:

    init.sh (this is the command wrapper)

    #!/usr/bin/env bash
    
    set -x
    
    ${JAVA_HOME}/bin/java \
      -Dnexus-work=${SONATYPE_WORK} -Dnexus-webapp-context-path=${CONTEXT_PATH} \
      -Xms${MIN_HEAP} -Xmx${MAX_HEAP} \
      -cp 'conf/:lib/*' \
      ${JAVA_OPTS} \
      org.sonatype.nexus.bootstrap.Launcher ${LAUNCHER_CONF} &
    
    # here some delay may be necessary, or a function to wait the nexus app to populate ${SONATYPE_WORK}/conf.
    sleep 5
    
    cp /nexus-dependencies/security-test.xml ${SONATYPE_WORK}/conf/security.xml
    
    # I'm also copying nexus.xml to customize the Snapshot repository.
    cp /nexus-dependencies/nexus.xml ${SONATYPE_WORK}/conf/nexus.xml
    
    tail -f /nexus-dependencies/init-nexus.sh
    

    Note: /nexus-dependencies is a volume I loaded in docker-compose.yaml . This directory contains my version of security.xml which contains 2 users (company and admin) along with their roles. If a user does not have any roles, it will not be available.

    security.xml (this was copied from a manually created instance)

    <?xml version="1.0" encoding="UTF-8"?>
    <security>
      <version>2.0.5</version>
    
      <!-- Users -->
      <users>
        <!-- The Company User -->
        <user>
          <id>companyX</id>
          <firstName>First</firstName>
          <lastName>Last</lastName>
          <password>$shiro1$SHA-512$SOME-ENCODED-PASSWORd-COPIED-FROM-A-PREVIOWS-INSTANCE-OF-THIS-IMAGE==</password>
          <!-- <password>RF1Dkings</password> -->
          <status>active</status>
          <email>[email protected]</email>
        </user>
    
    
        <!-- The Admin User -->
        <user>
          <id>admin</id>
          <firstName>Administrator</firstName>
          <lastName>User</lastName>
          <password>$shiro1$SHA-512$This could just be the custom admin password, or not.</password>
          <status>active</status>
          <email>[email protected]</email>
        </user>
    
      </users>
    
    
      <!-- Roles -->
      <userRoleMappings>
        <!-- CompanyX User role mapping -->
        <userRoleMapping>
          <userId>companyX</userId>
          <source>default</source>
          <roles>
            <role>nx-developer</role>
          </roles>
        </userRoleMapping>
      <!-- End CompanyX User role mapping -->
    
    
      <!-- Admin User Roles -->
        <userRoleMapping>
          <userId>admin</userId>
          <source>default</source>
          <roles>
            <role>nx-admin</role>
          </roles>
        </userRoleMapping>
        <!-- End Admin User Roles -->
    
      </userRoleMappings>
    </security>
    

    docker-compose.yaml

    version: "3"
    
    services:
      ...
      nexus:
        container_name: nexus
        image: sonatype/nexus:2.14.5-02
        ports:
          - "8081:8081"
        volumes:
          - ./nexus-dependencies:/nexus-dependencies
        command: bash /nexus-dependencies/init.sh
      ...