์ฝ”๋“œํ˜• ์ธํ”„๋ผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ Nexus Sonatype ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ

Sonatype Nexus๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ Java(Maven) ์ข…์†์„ฑ, Docker, Python, Ruby, NPM, Bower ์ด๋ฏธ์ง€, RPM ํŒจํ‚ค์ง€, gitlfs, Apt, Go, Nuget์„ ํ”„๋ก์‹œ, ์ €์žฅ ๋ฐ ๊ด€๋ฆฌํ•˜๊ณ  ์†Œํ”„ํŠธ์›จ์–ด ๋ณด์•ˆ์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ํ†ตํ•ฉ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

Sonatype Nexus๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

  • ๊ฐœ์ธ ์œ ๋ฌผ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด
  • ์ธํ„ฐ๋„ท์—์„œ ๋‹ค์šด๋กœ๋“œํ•œ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์บ์‹ฑํ•˜๋Š” ๊ฒฝ์šฐ

๊ธฐ๋ณธ Sonatype Nexus ํŒจํ‚ค์ง€์—์„œ ์ง€์›๋˜๋Š” ์•„ํ‹ฐํŒฉํŠธ:

  • ์ž๋ฐ”, ๋ฉ”์ด๋ธ(jar)
  • ๋„์ปค
  • ํŒŒ์ด์ฌ(ํ•)
  • ๋ฃจ๋น„(๋ณด์„)
  • NPM
  • ๋‚˜๋ฌด ๊ทธ๋Š˜
  • ๋ƒ (rpm)
  • gitlfs
  • ์‚ด๊ฐ—์ด ๋ฒ—์–ด ์ง„
  • ์•„ํŒŒํŠธ(deb)
  • Go
  • ๋„ˆ๊ฒŸ

์ปค๋ฎค๋‹ˆํ‹ฐ ์ง€์› ์œ ๋ฌผ:

  • ์ž‘๊ณก๊ฐ€
  • ์ฝ”๋‚œ
  • CPAN
  • ์—˜ํŒŒ
  • ํ‚ค
  • P2
  • R

๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ Sonatype Nexus ์„ค์น˜ https://github.com/ansible-ThoTeam/nexus3-oss

์š”๊ตฌ ์‚ฌํ•ญ

  • ์ธํ„ฐ๋„ท์—์„œ ansible ์‚ฌ์šฉ์— ๋Œ€ํ•ด ์ฝ์–ด๋ณด์„ธ์š”.
  • ์•ค์„œ๋ธ” ์„ค์น˜ pip install ansible ํ”Œ๋ ˆ์ด๋ถ์ด ์‹คํ–‰๋˜๋Š” ์›Œํฌ์Šคํ…Œ์ด์…˜์—์„œ.
  • ์„ธํŠธ geerlingguy.java ํ”Œ๋ ˆ์ด๋ถ์ด ์‹คํ–‰๋˜๋Š” ์›Œํฌ์Šคํ…Œ์ด์…˜์—์„œ.
  • ์„ธํŠธ geerlingguy.apache ํ”Œ๋ ˆ์ด๋ถ์ด ์‹คํ–‰๋˜๋Š” ์›Œํฌ์Šคํ…Œ์ด์…˜์—์„œ.
  • ์ด ์—ญํ• ์€ CentOS 7, Ubuntu Xenial(16.04) ๋ฐ Bionic(18.04), Debian Jessie ๋ฐ Stretch์—์„œ ํ…Œ์ŠคํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • jmespath ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ”Œ๋ ˆ์ด๋ถ์ด ์‹คํ–‰๋˜๋Š” ์›Œํฌ์Šคํ…Œ์ด์…˜์— ์„ค์น˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ: sudo pip install -r requirements.txt
  • ํ”Œ๋ ˆ์ด๋ถ ํŒŒ์ผ(์•„๋ž˜ ์˜ˆ)์„ nexus.yml ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋„ฅ์„œ์Šค ์„ค์น˜ ์‹คํ–‰ ansible-playbook -i host nexus.yml

Maven(java), Docker, Python, Ruby, NPM, Bower, RPM ๋ฐ gitlfs ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LDAP ์—†์ด nexus๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์ œ ansible-playbook์ž…๋‹ˆ๋‹ค.

---
- name: Nexus
  hosts: nexus
  become: yes

  vars:
    nexus_timezone: 'Asia/Omsk'
    nexus_admin_password: "admin123"
    nexus_public_hostname: 'apatsev-nexus-playbook'
    httpd_setup_enable: false
    nexus_privileges:
      - name: all-repos-read
        description: 'Read & Browse access to all repos'
        repository: '*'
        actions:
          - read
          - browse
      - name: company-project-deploy
        description: 'Deployments to company-project'
        repository: company-project
        actions:
          - add
          - edit
    nexus_roles:
      - id: Developpers # maps to the LDAP group
        name: developers
        description: All developers
        privileges:
          - nx-search-read
          - all-repos-read
          - company-project-deploy
        roles: []
    nexus_local_users:
      - username: jenkins # used as key to update
        first_name: Jenkins
        last_name: CI
        email: [email protected]
        password: "s3cr3t"
        roles:
          - Developpers # role ID here
    nexus_blobstores:
      - name: company-artifacts
        path: /var/nexus/blobs/company-artifacts
    nexus_scheduled_tasks:
      - name: compact-blobstore
        cron: '0 0 22 * * ?'
        typeId: blobstore.compact
        taskProperties:
          blobstoreName: 'company-artifacts'

    nexus_repos_maven_proxy:
      - name: central
        remote_url: 'https://repo1.maven.org/maven2/'
        layout_policy: permissive
      - name: jboss
        remote_url: 'https://repository.jboss.org/nexus/content/groups/public-jboss/'
      - name: vaadin-addons
        remote_url: 'https://maven.vaadin.com/vaadin-addons/'
      - name: jaspersoft
        remote_url: 'https://jaspersoft.artifactoryonline.com/jaspersoft/jaspersoft-repo/'
        version_policy: mixed
    nexus_repos_maven_hosted:
      - name: company-project
        version_policy: mixed
        write_policy: allow
        blob_store: company-artifacts
    nexus_repos_maven_group:
      - name: public
        member_repos:
          - central
          - jboss
          - vaadin-addons
          - jaspersoft

    # Yum. Change nexus_config_yum to true for create yum repository
    nexus_config_yum: true
    nexus_repos_yum_hosted:
      - name: private_yum_centos_7
        repodata_depth: 1
    nexus_repos_yum_proxy:
      - name: epel_centos_7_x86_64
        remote_url: http://download.fedoraproject.org/pub/epel/7/x86_64
        maximum_component_age: -1
        maximum_metadata_age: -1
        negative_cache_ttl: 60
      - name: centos-7-os-x86_64
        remote_url: http://mirror.centos.org/centos/7/os/x86_64/
        maximum_component_age: -1
        maximum_metadata_age: -1
        negative_cache_ttl: 60
    nexus_repos_yum_group:
      - name: yum_all
        member_repos:
          - private_yum_centos_7
          - epel_centos_7_x86_64

    # NPM. Change nexus_config_npm to true for create npm repository
    nexus_config_npm: true
    nexus_repos_npm_hosted: []
    nexus_repos_npm_group:
      - name: npm-public
        member_repos:
          - npm-registry
    nexus_repos_npm_proxy:
      - name: npm-registry
        remote_url: https://registry.npmjs.org/
        negative_cache_enabled: false

    # Docker. Change nexus_config_docker to true for create docker repository
    nexus_config_docker: true
    nexus_repos_docker_hosted:
      - name: docker-hosted
        http_port: "{{ nexus_docker_hosted_port }}"
        v1_enabled: True
    nexus_repos_docker_proxy:
      - name: docker-proxy
        http_port: "{{ nexus_docker_proxy_port }}"
        v1_enabled: True
        index_type: "HUB"
        remote_url: "https://registry-1.docker.io"
        use_nexus_certificates_to_access_index: false
        maximum_component_age: 1440
        maximum_metadata_age: 1440
        negative_cache_enabled: true
        negative_cache_ttl: 1440
    nexus_repos_docker_group:
      - name: docker-group
        http_port: "{{ nexus_docker_group_port }}"
        v1_enabled: True
        member_repos:
          - docker-hosted
          - docker-proxy

    # Bower. Change nexus_config_bower to true for create bower repository
    nexus_config_bower: true
    nexus_repos_bower_hosted:
      - name: bower-hosted
    nexus_repos_bower_proxy:
      - name: bower-proxy
        index_type: "proxy"
        remote_url: "https://registry.bower.io"
        use_nexus_certificates_to_access_index: false
        maximum_component_age: 1440
        maximum_metadata_age: 1440
        negative_cache_enabled: true
        negative_cache_ttl: 1440
    nexus_repos_bower_group:
      - name: bower-group
        member_repos:
          - bower-hosted
          - bower-proxy

    # Pypi. Change nexus_config_pypi to true for create pypi repository
    nexus_config_pypi: true
    nexus_repos_pypi_hosted:
      - name: pypi-hosted
    nexus_repos_pypi_proxy:
      - name: pypi-proxy
        index_type: "proxy"
        remote_url: "https://pypi.org/"
        use_nexus_certificates_to_access_index: false
        maximum_component_age: 1440
        maximum_metadata_age: 1440
        negative_cache_enabled: true
        negative_cache_ttl: 1440
    nexus_repos_pypi_group:
      - name: pypi-group
        member_repos:
          - pypi-hosted
          - pypi-proxy

    # rubygems. Change nexus_config_rubygems to true for create rubygems repository
    nexus_config_rubygems: true
    nexus_repos_rubygems_hosted:
      - name: rubygems-hosted
    nexus_repos_rubygems_proxy:
      - name: rubygems-proxy
        index_type: "proxy"
        remote_url: "https://rubygems.org"
        use_nexus_certificates_to_access_index: false
        maximum_component_age: 1440
        maximum_metadata_age: 1440
        negative_cache_enabled: true
        negative_cache_ttl: 1440
    nexus_repos_rubygems_group:
      - name: rubygems-group
        member_repos:
          - rubygems-hosted
          - rubygems-proxy

    # gitlfs. Change nexus_config_gitlfs to true for create gitlfs repository
    nexus_config_gitlfs: true
    nexus_repos_gitlfs_hosted:
      - name: gitlfs-hosted

  roles:
    - { role: geerlingguy.java }
    # Debian/Ubuntu only
    # - { role: geerlingguy.apache, apache_create_vhosts: no, apache_mods_enabled: ["proxy_http.load", "headers.load"], apache_remove_default_vhost: true, tags: ["geerlingguy.apache"] }
    # RedHat/CentOS only
    - { role: geerlingguy.apache, apache_create_vhosts: no, apache_remove_default_vhost: true, tags: ["geerlingguy.apache"] }
    - { role: ansible-thoteam.nexus3-oss, tags: ['ansible-thoteam.nexus3-oss'] }

์Šคํฌ๋ฆฐ์ƒท:

์ฝ”๋“œํ˜• ์ธํ”„๋ผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ Nexus Sonatype ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ

์ฝ”๋“œํ˜• ์ธํ”„๋ผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ Nexus Sonatype ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ

๋‹ค์–‘ํ•œ ์—ญํ• 

์—ญํ•  ๋ณ€์ˆ˜

๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋Š” ๋ณ€์ˆ˜(์ฐธ์กฐ default/main.yml):

์ผ๋ฐ˜ ๋ณ€์ˆ˜

    nexus_version: ''
    nexus_timezone: 'UTC'

๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ด๋‹น ์—ญํ• ์€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ตœ์‹  ๋ฒ„์ „์˜ Nexus๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฒ„์ „์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค nexus_version. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „์„ ํ™•์ธํ•˜์„ธ์š”. https://www.sonatype.com/download-oss-sonatype.

์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์—ญํ• ์ด Nexus ์„ค์น˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฒ„์ „๋ณด๋‹ค ์ด์ „ ๋ฒ„์ „์˜ Nexus๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์„ค์น˜๋œ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด yum ์ €์žฅ์†Œ ํ˜ธ์ŠคํŒ…์€ 3.8.0๋ณด๋‹ค ํฐ nexus, git lfs repo์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 3.3.0๋ณด๋‹ค ํฐ ๋„ฅ์„œ์Šค์˜ ๊ฒฝ์šฐ ๋“ฑ)

nexus timezone nexus_scheduled ์ž‘์—…์— ๋Œ€ํ•ด ๋‹ค์Œ cron ํ‘œํ˜„์‹๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Java ์‹œ๊ฐ„๋Œ€์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

Nexus ํฌํŠธ ๋ฐ ์ปจํ…์ŠคํŠธ ๊ฒฝ๋กœ

    nexus_default_port: 8081
    nexus_default_context_path: '/'

Java ์—ฐ๊ฒฐ ํ”„๋กœ์„ธ์Šค์˜ ํฌํŠธ ๋ฐ ์ปจํ…์ŠคํŠธ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. nexus_default_context_path ์„ค์ • ์‹œ ์Šฌ๋ž˜์‹œ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: nexus_default_context_path: '/nexus/'.

Nexus OS ์‚ฌ์šฉ์ž ๋ฐ ๊ทธ๋ฃน

    nexus_os_group: 'nexus'
    nexus_os_user: 'nexus'

Nexus ํŒŒ์ผ์„ ์†Œ์œ ํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์‚ฌ์šฉ์ž ๋ฐ ๊ทธ๋ฃน์ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ์—ญํ• ์— ์˜ํ•ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

    nexus_os_user_home_dir: '/home/nexus'

Nexus ์‚ฌ์šฉ์ž์˜ ๊ธฐ๋ณธ ํ™ˆ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ณ€๊ฒฝ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

Nexus ์ธ์Šคํ„ด์Šค ๋””๋ ‰ํ„ฐ๋ฆฌ

    nexus_installation_dir: '/opt'
    nexus_data_dir: '/var/nexus'
    nexus_tmp_dir: "{{ (ansible_os_family == 'RedHat') | ternary('/var/nexus-tmp', '/tmp/nexus') }}"

๋„ฅ์„œ์Šค ์นดํƒˆ๋กœ๊ทธ.

  • nexus_installation_dir ์„ค์น˜๋œ ์‹คํ–‰ ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • nexus_data_dir ๋ชจ๋“  ๊ตฌ์„ฑ, ์ €์žฅ์†Œ ๋ฐ ๋‹ค์šด๋กœ๋“œ๋œ ์•„ํ‹ฐํŒฉํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ Blobstore ๊ฒฝ๋กœ nexus_data_dir ์‚ฌ์šฉ์ž ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. nexus_blobstores.
  • nexus_tmp_dir ๋ชจ๋“  ์ž„์‹œ ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. Redhat์˜ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๊ฐ€ ๋‹ค์Œ์—์„œ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค. /tmp ์ž๋™ ์ฒญ์†Œ ์ ˆ์ฐจ์˜ ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๋ฅผ ๊ทน๋ณตํ•ฉ๋‹ˆ๋‹ค. #168์„ ์ฐธ์กฐํ•˜์„ธ์š”.

Nexus JVM ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๊ตฌ์„ฑ

    nexus_min_heap_size: "1200M"
    nexus_max_heap_size: "{{ nexus_min_heap_size }}"
    nexus_max_direct_memory: "2G"

Nexus์˜ ๊ธฐ๋ณธ ์„ค์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์•„์ง ์ฝ์ง€ ์•Š์•˜๋‹ค๋ฉด Nexus ์‹œ์Šคํ…œ ์š”๊ตฌ ์‚ฌํ•ญ ๋ฉ”๋ชจ๋ฆฌ ์„น์…˜ ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋“ค์ด ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ๊ฒฝ๊ณ ๋กœ, ์œ„ ๋ฌธ์„œ์—์„œ ๋ฐœ์ทŒํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด JVM ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ถŒ์žฅ ๊ฐ’ ์ด์ƒ์œผ๋กœ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์€ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹ค์ œ๋กœ ๋ฐ˜๋Œ€ ํšจ๊ณผ๋ฅผ ๊ฐ€์ ธ์„œ ์šด์˜ ์ฒด์ œ์— ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ

    nexus_admin_password: 'changeme'

์„ค์ •์„ ์œ„ํ•œ โ€œadminโ€ ๊ณ„์ • ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ฒซ ๋ฒˆ์งธ ๊ธฐ๋ณธ ์„ค์น˜์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.. ๋‚˜์ค‘์— ์—ญํ• ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด [์ฒซ ์„ค์น˜ ํ›„ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ](#change-admin-password-after-first-install)์„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ”Œ๋ ˆ์ด๋ถ์— ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋กœ ์ €์žฅํ•˜์ง€ ๋ง๊ณ  [ansible-vault ์•”ํ˜ธํ™”]๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค(https://docs.ansible.com/ansible/latest/user_guide/vault.html) (์ธ๋ผ์ธ ๋˜๋Š” include_vars์™€ ํ•จ๊ป˜ ๋กœ๋“œ๋œ ๋ณ„๋„์˜ ํŒŒ์ผ)

๊ธฐ๋ณธ์ ์œผ๋กœ ์ต๋ช… ์•ก์„ธ์Šค

    nexus_anonymous_access: false

์ต๋ช… ์•ก์„ธ์Šค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์ต๋ช… ์•ก์„ธ์Šค.

๊ณต๊ฐœ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„

    nexus_public_hostname: 'nexus.vm'
    nexus_public_scheme: https

ํด๋ผ์ด์–ธํŠธ๊ฐ€ Nexus ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ •๊ทœํ™”๋œ ๋„๋ฉ”์ธ ์ด๋ฆ„ ๋ฐ ์ฒด๊ณ„(https ๋˜๋Š” http)์ž…๋‹ˆ๋‹ค.

์ด ์—ญํ• ์— ๋Œ€ํ•œ API ์•ก์„ธ์Šค

    nexus_api_hostname: localhost
    nexus_api_scheme: http
    nexus_api_validate_certs: "{{ nexus_api_scheme == 'https' }}"
    nexus_api_context_path: "{{ nexus_default_context_path }}"
    nexus_api_port: "{{ nexus_default_port }}"

์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋Š” ํ”„๋กœ๋น„์ €๋‹์„ ์œ„ํ•ด ์—ญํ• ์ด Nexus API์— ์—ฐ๊ฒฐ๋˜๋Š” ๋ฐฉ์‹์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
๊ณ ๊ธ‰ ์‚ฌ์šฉ์ž์—๊ฒŒ๋งŒ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ ์„ค์ •

    httpd_setup_enable: false
    httpd_server_name: "{{ nexus_public_hostname }}"
    httpd_default_admin_email: "[email protected]"
    httpd_ssl_certificate_file: 'files/nexus.vm.crt'
    httpd_ssl_certificate_key_file: 'files/nexus.vm.key'
    # httpd_ssl_certificate_chain_file: "{{ httpd_ssl_certificate_file }}"
    httpd_copy_ssl_files: true

์„ธํŠธ SSL ์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ.
์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” httpd๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ : ์–ธ์ œ httpd_setup_enable ์„ค์ • ๊ฐ’true, ๋„ฅ์„œ์Šค๋Š” 127.0.0.1:8081์— ์ ‘์†ํ•˜๋ฏ€๋กœ ์•„๋‹ˆ ์™ธ๋ถ€ IP ์ฃผ์†Œ์—์„œ HTTP ํฌํŠธ 8081์„ ํ†ตํ•ด ์ง์ ‘ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. nexus_public_hostname. ์–ด๋–ค ์ด์œ ๋กœ ๋‹ค๋ฅธ ์ด๋ฆ„์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. httpd_server_name ๋‹ค๋ฅธ ์˜๋ฏธ๋กœ.

ะก httpd_copy_ssl_files: true (๊ธฐ๋ณธ์ ์œผ๋กœ) ์œ„ ์ธ์ฆ์„œ๋Š” ํ”Œ๋ ˆ์ด๋ถ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ์„œ๋ฒ„์— ๋ณต์‚ฌ๋˜๊ณ  Apache์—์„œ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์— ์žˆ๋Š” ๊ธฐ์กด ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด httpd_copy_ssl_files: false ๋‹ค์Œ ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    # These specifies to the vhost where to find on the remote server file
    # system the certificate files.
    httpd_ssl_cert_file_location: "/etc/pki/tls/certs/wildcard.vm.crt"
    httpd_ssl_cert_key_location: "/etc/pki/tls/private/wildcard.vm.key"
    # httpd_ssl_cert_chain_file_location: "{{ httpd_ssl_cert_file_location }}"

httpd_ssl_cert_chain_file_location ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์ฒด์ธ ํŒŒ์ผ์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์„ค์ •ํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    httpd_default_admin_email: "[email protected]"

๊ธฐ๋ณธ ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ ์ฃผ์†Œ ์„ค์ •

LDAP ๊ตฌ์„ฑ

LDAP ์—ฐ๊ฒฐ ๋ฐ ๋ณด์•ˆ ์˜์—ญ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    nexus_ldap_realm: false
    ldap_connections: []

LDAP ์—ฐ๊ฒฐ, ๊ฐ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    nexus_ldap_realm: true
    ldap_connections:
      - ldap_name: 'My Company LDAP' # used as a key to update the ldap config
        ldap_protocol: 'ldaps' # ldap or ldaps
        ldap_hostname: 'ldap.mycompany.com'
        ldap_port: 636
        ldap_use_trust_store: false # Wether or not to use certs in the nexus trust store
        ldap_search_base: 'dc=mycompany,dc=net'
        ldap_auth: 'none' # or simple
        ldap_auth_username: 'username' # if auth = simple
        ldap_auth_password: 'password' # if auth = simple
        ldap_user_base_dn: 'ou=users'
        ldap_user_filter: '(cn=*)' # (optional)
        ldap_user_object_class: 'inetOrgPerson'
        ldap_user_id_attribute: 'uid'
        ldap_user_real_name_attribute: 'cn'
        ldap_user_email_attribute: 'mail'
        ldap_user_subtree: false
        ldap_map_groups_as_roles: false
        ldap_group_base_dn: 'ou=groups'
        ldap_group_object_class: 'posixGroup'
        ldap_group_id_attribute: 'cn'
        ldap_group_member_attribute: 'memberUid'
        ldap_group_member_format: '${username}'
        ldap_group_subtree: false

์ต๋ช… ์ธ์ฆ(์ต๋ช… ๋ฐ”์ธ๋”ฉ)์„ ์œ„ํ•œ LDAP ๊ตฌ์„ฑ ์˜ˆ๋Š” "์ตœ์†Œ" ๊ตฌ์„ฑ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

    nexus_ldap_realm: true
    ldap_connection:
      - ldap_name: 'Simplest LDAP config'
        ldap_protocol: 'ldaps'
        ldap_hostname: 'annuaire.mycompany.com'
        ldap_search_base: 'dc=mycompany,dc=net'
        ldap_port: 636
        ldap_use_trust_store: false
        ldap_user_id_attribute: 'uid'
        ldap_user_real_name_attribute: 'cn'
        ldap_user_email_attribute: 'mail'
        ldap_user_object_class: 'inetOrgPerson'

๋‹จ์ˆœ ์ธ์ฆ์„ ์œ„ํ•œ LDAP ๊ตฌ์„ฑ ์˜ˆ(DSA ๊ณ„์ • ์‚ฌ์šฉ):

    nexus_ldap_realm: true
    ldap_connections:
      - ldap_name: 'LDAP config with DSA'
        ldap_protocol: 'ldaps'
        ldap_hostname: 'annuaire.mycompany.com'
        ldap_port: 636
        ldap_use_trust_store: false
        ldap_auth: 'simple'
        ldap_auth_username: 'cn=mynexus,ou=dsa,dc=mycompany,dc=net'
        ldap_auth_password: "{{ vault_ldap_dsa_password }}" # better keep passwords in an ansible vault
        ldap_search_base: 'dc=mycompany,dc=net'
        ldap_user_base_dn: 'ou=users'
        ldap_user_object_class: 'inetOrgPerson'
        ldap_user_id_attribute: 'uid'
        ldap_user_real_name_attribute: 'cn'
        ldap_user_email_attribute: 'mail'
        ldap_user_subtree: false

๋‹จ์ˆœ ์ธ์ฆ(DSA ๊ณ„์ • ์‚ฌ์šฉ)์„ ์œ„ํ•œ LDAP ๊ตฌ์„ฑ ์˜ˆ์‹œ + ์—ญํ• ๋กœ ๋งคํ•‘๋œ ๊ทธ๋ฃน:

    nexus_ldap_realm: true
    ldap_connections
      - ldap_name: 'LDAP config with DSA'
        ldap_protocol: 'ldaps'
        ldap_hostname: 'annuaire.mycompany.com'
        ldap_port: 636
        ldap_use_trust_store: false
        ldap_auth: 'simple'
        ldap_auth_username: 'cn=mynexus,ou=dsa,dc=mycompany,dc=net'
        ldap_auth_password: "{{ vault_ldap_dsa_password }}" # better keep passwords in an ansible vault
        ldap_search_base: 'dc=mycompany,dc=net'
        ldap_user_base_dn: 'ou=users'
        ldap_user_object_class: 'inetOrgPerson'
        ldap_user_id_attribute: 'uid'
        ldap_user_real_name_attribute: 'cn'
        ldap_user_email_attribute: 'mail'
        ldap_map_groups_as_roles: true
        ldap_group_base_dn: 'ou=groups'
        ldap_group_object_class: 'groupOfNames'
        ldap_group_id_attribute: 'cn'
        ldap_group_member_attribute: 'member'
        ldap_group_member_format: 'uid=${username},ou=users,dc=mycompany,dc=net'
        ldap_group_subtree: false

๋‹จ์ˆœ ์ธ์ฆ(DSA ๊ณ„์ • ์‚ฌ์šฉ)์„ ์œ„ํ•œ LDAP ๊ตฌ์„ฑ ์˜ˆ + ์—ญํ• ๋กœ ๋™์ ์œผ๋กœ ๋งคํ•‘๋œ ๊ทธ๋ฃน:

    nexus_ldap_realm: true
    ldap_connections:
      - ldap_name: 'LDAP config with DSA'
        ldap_protocol: 'ldaps'
        ldap_hostname: 'annuaire.mycompany.com'
        ldap_port: 636
        ldap_use_trust_store: false
        ldap_auth: 'simple'
        ldap_auth_username: 'cn=mynexus,ou=dsa,dc=mycompany,dc=net'
        ldap_auth_password: "{{ vault_ldap_dsa_password }}" # better keep passwords in an ansible vault
        ldap_search_base: 'dc=mycompany,dc=net'
        ldap_user_base_dn: 'ou=users'
        ldap_user_object_class: 'inetOrgPerson'
        ldap_user_id_attribute: 'uid'
        ldap_user_real_name_attribute: 'cn'
        ldap_user_email_attribute: 'mail'
        ldap_map_groups_as_roles: true
        ldap_map_groups_as_roles_type: 'dynamic'
        ldap_user_memberof_attribute: 'memberOf'

ํŠน๊ถŒ

    nexus_privileges:
      - name: all-repos-read # used as key to update a privilege
        # type: <one of application, repository-admin, repository-content-selector, repository-view, script or wildcard>
        description: 'Read & Browse access to all repos'
        repository: '*'
        actions: # can be add, browse, create, delete, edit, read or  * (all)
          - read
          - browse
        # pattern: pattern
        # domain: domain
        # script_name: name

๋ช…๋ถ€ ํŠน๊ถŒ ์„ค์ •์„ ์œ„ํ•ด. ๋ฌธ์„œ์™€ GUI๋ฅผ ๋ณด๊ณ  ๊ถŒํ•œ ์œ ํ˜•์— ๋”ฐ๋ผ ์–ด๋–ค ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

์ด๋Ÿฌํ•œ ์š”์†Œ๋Š” ๋‹ค์Œ ๊ธฐ๋ณธ๊ฐ’๊ณผ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค.

    _nexus_privilege_defaults:
      type: repository-view
      format: maven2
      actions:
        - read

์—ญํ• (๋‚ด๋ถ€ Nexus ์˜๋ฏธ)

    nexus_roles:
      - id: Developpers # can map to a LDAP group id, also used as a key to update a role
        name: developers
        description: All developers
        privileges:
          - nx-search-read
          - all-repos-read
        roles: [] # references to other role names

๋ช…๋ถ€ ์—ญํ•  ์„ค์ •์„ ์œ„ํ•ด.

ํšŒ์›

    nexus_local_users: []
      # - username: jenkins # used as key to update
      #   state: present # default value if ommited, use 'absent' to remove user
      #   first_name: Jenkins
      #   last_name: CI
      #   email: [email protected]
      #   password: "s3cr3t"
      #   roles:
      #     - developers # role ID

๋„ฅ์„œ์Šค์—์„œ ์ƒ์„ฑํ•  ๋กœ์ปฌ(๋น„LDAP) ์‚ฌ์šฉ์ž/๊ณ„์ • ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

Nexus์—์„œ ์ƒ์„ฑํ•  ๋กœ์ปฌ(๋น„LDAP) ์‚ฌ์šฉ์ž/๊ณ„์ • ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

      nexus_ldap_users: []
      # - username: j.doe
      #   state: present
      #   roles:
      #     - "nx-admin"

์‚ฌ์šฉ์ž/์—ญํ• ์˜ LDAP ๋งคํ•‘. ์ƒํƒœ absent ๊ธฐ์กด ์‚ฌ์šฉ์ž์˜ ์—ญํ• ์ด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์—ญํ• ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
LDAP ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์—ญํ• ์„ ์„ค์ •ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ฝ˜ํ…์ธ  ์„ ํƒ๊ธฐ

  nexus_content_selectors:
  - name: docker-login
    description: Selector for docker login privilege
    search_expression: format=="docker" and path=~"/v2/"

์ฝ˜ํ…์ธ  ์„ ํƒ๊ธฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”. ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜.

์ฝ˜ํ…์ธ  ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. type: repository-content-selector ๊ด€๋ จ์„ฑ์ด ์žˆ๊ณ contentSelector

- name: docker-login-privilege
  type: repository-content-selector
  contentSelector: docker-login
  description: 'Login to Docker registry'
  repository: '*'
  actions:
  - read
  - browse

Blobstore ๋ฐ ์ €์žฅ์†Œ

    nexus_delete_default_repos: false

Nexus ์„ค์น˜ ์ดˆ๊ธฐ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์—์„œ ์ €์žฅ์†Œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ์ตœ์ดˆ ์„ค์น˜ ์‹œ์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. nexus_data_dir ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค).

Nexus์˜ ๊ธฐ๋ณธ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์—์„œ ์ €์žฅ์†Œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ์ฒ˜์Œ ์„ค์น˜ํ•˜๋Š” ๋™์•ˆ์—๋งŒ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค( nexus_data_dir ๋น„์–ด ์žˆ๋Š”).

    nexus_delete_default_blobstore: false

nexus ์„ค์น˜ ์ดˆ๊ธฐ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์—์„œ ๊ธฐ๋ณธ blobstore๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์€ ๋‹ค์Œ ๊ฒฝ์šฐ์—๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. nexus_delete_default_repos: true ๊ตฌ์„ฑ๋œ ๋ชจ๋“  ์ €์žฅ์†Œ(์•„๋ž˜ ์ฐธ์กฐ)์—๋Š” ๋ช…์‹œ์ ์ธ blob_store: custom. ์ด ๋‹จ๊ณ„๋Š” ์ตœ์ดˆ ์„ค์น˜ ์‹œ์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. nexus_data_dir ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค).

Blob Storage(์ด์ง„ ์•„ํ‹ฐํŒฉํŠธ) ์ œ๊ฑฐ๋Š” ์ดˆ๊ธฐ ๊ตฌ์„ฑ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. Blob Storage(๋ฐ”์ด๋„ˆ๋ฆฌ ์•„ํ‹ฐํŒฉํŠธ)๋ฅผ ์ œ๊ฑฐํ•˜๋ ค๋ฉด ๋„์„ธ์š”. nexus_delete_default_repos: true. ์ด ๋‹จ๊ณ„๋Š” ์ฒ˜์Œ ์„ค์น˜ํ•˜๋Š” ๋™์•ˆ์—๋งŒ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค( nexus_data_dir ๋น„์–ด ์žˆ๋Š”).

    nexus_blobstores: []
    # example blobstore item :
    # - name: separate-storage
    #   type: file
    #   path: /mnt/custom/path
    # - name: s3-blobstore
    #   type: S3
    #   config:
    #     bucket: s3-blobstore
    #     accessKeyId: "{{ VAULT_ENCRYPTED_KEY_ID }}"
    #     secretAccessKey: "{{ VAULT_ENCRYPTED_ACCESS_KEY }}"

๋ธ”๋กญ์Šคํ† ์–ด ๋งŒ๋“ค๋‹ค. blobstore ๊ฒฝ๋กœ ๋ฐ ์ €์žฅ์†Œ blobstore๋Š” ์ดˆ๊ธฐ ์ƒ์„ฑ ํ›„์—๋Š” ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(์—ฌ๊ธฐ์„œ์˜ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋Š” ๋‹ค์‹œ ํ”„๋กœ๋น„์ €๋‹ ์‹œ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค).

S3์—์„œ blobstore๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ ํŽธ์˜๋ฅผ ์œ„ํ•ด ์ œ๊ณต๋˜๋ฉฐ travis์—์„œ ์‹คํ–‰ํ•˜๋Š” ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. S3์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ AWS์— ๋ฐฐํฌ๋œ ์ธ์Šคํ„ด์Šค์—๋งŒ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

์ฐฝ์กฐ ๋ธ”๋กญ์Šคํ† ์–ด. ์Šคํ† ๋ฆฌ์ง€ ๊ฒฝ๋กœ ๋ฐ ์Šคํ† ๋ฆฌ์ง€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” ์ดˆ๊ธฐ ์ƒ์„ฑ ํ›„์—๋Š” ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(๋‹ค์‹œ ์„ค์น˜ํ•˜๋ฉด ์—ฌ๊ธฐ์˜ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค).

S3์—์„œ Blob Storage ์„ค์ •์€ ํŽธ์˜๋ฅผ ์œ„ํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. S3 ์Šคํ† ๋ฆฌ์ง€๋Š” AWS์— ๋ฐฐํฌ๋œ ์ธ์Šคํ„ด์Šค์—๋งŒ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

    nexus_repos_maven_proxy:
      - name: central
        remote_url: 'https://repo1.maven.org/maven2/'
        layout_policy: permissive
        # maximum_component_age: -1
        # maximum_metadata_age: 1440
        # negative_cache_enabled: true
        # negative_cache_ttl: 1440
      - name: jboss
        remote_url: 'https://repository.jboss.org/nexus/content/groups/public-jboss/'
        # maximum_component_age: -1
        # maximum_metadata_age: 1440
        # negative_cache_enabled: true
        # negative_cache_ttl: 1440
    # example with a login/password :
    # - name: secret-remote-repo
    #   remote_url: 'https://company.com/repo/secure/private/go/away'
    #   remote_username: 'username'
    #   remote_password: 'secret'
    #   # maximum_component_age: -1
    #   # maximum_metadata_age: 1440
    #   # negative_cache_enabled: true
    #   # negative_cache_ttl: 1440

์œ„๋Š” ๊ตฌ์„ฑ ์˜ˆ์ž…๋‹ˆ๋‹ค. ํ”„๋ก์‹œ ์„œ๋ฒ„ ๋ฉ”์ด๋ธ.

    nexus_repos_maven_hosted:
      - name: private-release
        version_policy: release
        write_policy: allow_once  # one of "allow", "allow_once" or "deny"

๋ฉ”์ด๋ธ ํ˜ธ์ŠคํŒ…๋œ ์ €์žฅ์†Œ ๊ตฌ์„ฑ. ๋„ค๊ฑฐํ‹ฐ๋ธŒ ์บ์‹œ ๊ตฌ์„ฑ์€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์ƒ๋žตํ•  ๊ฒฝ์šฐ ์œ„ ๊ฐ’์ด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ํ˜ธ์ŠคํŒ…๋œ ์ €์žฅ์†Œ ๋ฉ”์ด๋ธ. ๋„ค๊ฑฐํ‹ฐ๋ธŒ ์บ์‹œ ๊ตฌ์„ฑ(-1)์€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์œ„ ๊ฐ’์ด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

    nexus_repos_maven_group:
      - name: public
        member_repos:
          - central
          - jboss

๊ตฌ์„ฑ ๊ทธ๋ฃน ๋ฉ”์ด๋ธ.

์„ธ ๊ฐ€์ง€ ์ €์žฅ์†Œ ์œ ํ˜•์€ ๋ชจ๋‘ ๋‹ค์Œ ๊ธฐ๋ณธ๊ฐ’๊ณผ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค.

    _nexus_repos_maven_defaults:
      blob_store: default # Note : cannot be updated once the repo has been created
      strict_content_validation: true
      version_policy: release # release, snapshot or mixed
      layout_policy: strict # strict or permissive
      write_policy: allow_once # one of "allow", "allow_once" or "deny"
      maximum_component_age: -1  # Nexus gui default. For proxies only
      maximum_metadata_age: 1440  # Nexus gui default. For proxies only
      negative_cache_enabled: true # Nexus gui default. For proxies only
      negative_cache_ttl: 1440 # Nexus gui default. For proxies only

Docker, Pypi, Raw, Rubygems, Bower, NPM, Git-LFS ๋ฐ yum ์ €์žฅ์†Œ ์œ ํ˜•:
์ฐธ์กฐ defaults/main.yml ๋‹ค์Œ ์˜ต์…˜์˜ ๊ฒฝ์šฐ:

Docker, Pypi, Raw, Rubygems, Bower, NPM, Git-LFS ๋ฐ yum ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
์ฐธ์กฐ defaults/main.yml ๋‹ค์Œ ์˜ต์…˜์˜ ๊ฒฝ์šฐ:

      nexus_config_pypi: false
      nexus_config_docker: false
      nexus_config_raw: false
      nexus_config_rubygems: false
      nexus_config_bower: false
      nexus_config_npm: false
      nexus_config_gitlfs: false
      nexus_config_yum: false

Maven ์ด์™ธ์˜ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํŠน์ • ๋ณด์•ˆ ๋ฒ”์œ„๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค.

nexus_nuget_api_key_realm: false
nexus_npm_bearer_token_realm: false
nexus_docker_bearer_token_realm: false  # required for docker anonymous access

์›๊ฒฉ ์‚ฌ์šฉ์ž ์˜์—ญ์€ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ™œ์„ฑํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

nexus_rut_auth_realm: true

์ œ๋ชฉ์€ ๋‹ค์Œ์„ ์ •์˜ํ•˜์—ฌ ๋งž์ถค์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

nexus_rut_auth_header: "CUSTOM_HEADER"

์˜ˆ์•ฝ ๋œ ์ผ๋“ค

    nexus_scheduled_tasks: []
    #  #  Example task to compact blobstore :
    #  - name: compact-docker-blobstore
    #    cron: '0 0 22 * * ?'
    #    typeId: blobstore.compact
    #    task_alert_email: [email protected]  # optional
    #    taskProperties:
    #      blobstoreName: {{ nexus_blob_names.docker.blob }} # all task attributes are stored as strings by nexus internally
    #  #  Example task to purge maven snapshots
    #  - name: Purge-maven-snapshots
    #    cron: '0 50 23 * * ?'
    #    typeId: repository.maven.remove-snapshots
    #    task_alert_email: [email protected]  # optional
    #    taskProperties:
    #      repositoryName: "*"  # * for all repos. Change to a repository name if you only want a specific one
    #      minimumRetained: "2"
    #      snapshotRetentionDays: "2"
    #      gracePeriodInDays: "2"
    #    booleanTaskProperties:
    #      removeIfReleased: true
    #  #  Example task to purge unused docker manifest and images
    #  - name: Purge unused docker manifests and images
    #    cron: '0 55 23 * * ?'
    #    typeId: "repository.docker.gc"
    #    task_alert_email: [email protected]  # optional
    #    taskProperties:
    #      repositoryName: "*"  # * for all repos. Change to a repository name if you only want a specific one
    #  #  Example task to purge incomplete docker uploads
    #  - name: Purge incomplete docker uploads
    #    cron: '0 0 0 * * ?'
    #    typeId: "repository.docker.upload-purge"
    #    task_alert_email: [email protected]  # optional
    #    taskProperties:
    #      age: "24"

์˜ˆ์•ฝ ๋œ ์ผ๋“ค ์„ค์ •์„ ์œ„ํ•ด. typeId ํŠน์ • ์ž‘์—…taskProperties/booleanTaskProperties ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Java ์œ ํ˜• ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ org.sonatype.nexus.scheduling.TaskDescriptorSupport
  • ๋ธŒ๋ผ์šฐ์ €์—์„œ HTML ์ž‘์—… ์ƒ์„ฑ ์–‘์‹ ํ™•์ธ
  • ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•  ๋•Œ ๋ธŒ๋ผ์šฐ์ €์—์„œ AJAX ์š”์ฒญ์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ž‘์—… ์†์„ฑ์€ ํ•ด๋‹น ์œ ํ˜•์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅธ yaml ๋ธ”๋ก์—์„œ ์„ ์–ธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.:

  • taskProperties ๋ชจ๋“  ๋ฌธ์ž์—ด ์†์„ฑ(์˜ˆ: ์ €์žฅ์†Œ ์ด๋ฆ„, ์ €์žฅ์†Œ ์ด๋ฆ„, ๊ธฐ๊ฐ„...)์— ๋Œ€ํ•ด.
  • booleanTaskProperties ๋ชจ๋“  ๋…ผ๋ฆฌ์  ์†์„ฑ(์˜ˆ: ์ฃผ๋กœ ๋„ฅ์„œ์Šค ์ƒ์„ฑ ์ž‘์—… GUI์˜ ํ™•์ธ๋ž€)์— ๋Œ€ํ•ด

๋ฐฑ์—…

      nexus_backup_configure: false
      nexus_backup_cron: '0 0 21 * * ?'  # See cron expressions definition in nexus create task gui
      nexus_backup_dir: '/var/nexus-backup'
      nexus_restore_log: '{{ nexus_backup_dir }}/nexus-restore.log'
      nexus_backup_rotate: false
      nexus_backup_rotate_first: false
      nexus_backup_keep_rotations: 4  # Keep 4 backup rotation by default (current + last 3)

์ „ํ™˜ํ•  ๋•Œ๊นŒ์ง€ ๋ฐฑ์—…์ด ๊ตฌ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. nexus_backup_configure ะฒ true.
์ด ๊ฒฝ์šฐ ์˜ˆ์•ฝ๋œ ์Šคํฌ๋ฆฝํŠธ ์ž‘์—…์€ Nexus์—์„œ ์‹คํ–‰๋˜๋„๋ก ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
์— ์ง€์ •๋œ ๊ฐ„๊ฒฉ์œผ๋กœ nexus_backup_cron (๊ธฐ๋ณธ์ ์œผ๋กœ ๋งค์ผ 21:00).
์ž์„ธํ•œ ๋‚ด์šฉ์€ [์ด ์ž‘์—…์„ ์œ„ํ•œ Groovy ํ…œํ”Œ๋ฆฟ](templates/backup.groovy.j2)์„ ์ฐธ์กฐํ•˜์„ธ์š”.
์ด ์˜ˆ์•ฝ๋œ ์ž‘์—…์€ ๋‹ค๋ฅธ ์ž‘์—…๊ณผ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค. nexus_scheduled_tasks๋‹น์‹ ์ด
ํ”Œ๋ ˆ์ด๋ถ์— ๋ฐœํ‘œํ•˜์„ธ์š”.

๋ฐฑ์—…์„ ์ˆœํ™˜/์‚ญ์ œํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค. nexus_backup_rotate: true ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅํ•˜๋ ค๋Š” ๋ฐฑ์—… ์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. nexus_backup_keep_rotations (๊ธฐ๋ณธ๊ฐ’ 4).

์ˆœํ™˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋ฐฑ์—… ๊ณผ์ •์—์„œ ์ถ”๊ฐ€ ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด,
๋‹น์‹ ์€ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค nexus_backup_rotate_first: true. ๋ฐฑ์—… ์ „ ์‚ฌ์ „ ํšŒ์ „/์‚ญ์ œ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ต์ฒด๋Š” ๋ฐฑ์—…์ด ์ƒ์„ฑ๋œ ํ›„์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ด์ „ ๋ฐฑ์—…์€
ํ˜„์žฌ ๋ฐฑ์—…์ด ์ด๋ฃจ์–ด์ง€๊ธฐ ์ „์— ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

๋ณต๊ตฌ ์ ˆ์ฐจ

๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”Œ๋ ˆ์ด๋ถ ์‹คํ–‰ -e nexus_restore_point=<YYYY-MM-dd-HH-mm-ss>
(์˜ˆ: 2017๋…„ 12์›” 17์ผ 21:00์˜ ๊ฒฝ์šฐ 00-17-2017-21-00-XNUMX)

๋„ฅ์„œ์Šค ์‚ญ์ œ ์ค‘

๊ฒฝ๊ณ : ํ˜„์žฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์™„์ „ํžˆ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋‹ค๋ฉด ๋ฏธ๋ฆฌ ๋ฐฑ์—…ํ•ด๋‘์„ธ์š”

๋ณ€์ˆ˜ ์‚ฌ์šฉ nexus_purge์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ณ  ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์ œ๊ฑฐ๋œ ๋„ฅ์„œ์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค์‹œ ์„ค์น˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ.

ansible-playbook -i your/inventory.ini your_nexus_playbook.yml -e nexus_purge=true

์ตœ์ดˆ ์„ค์น˜ ํ›„ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ

    nexus_default_admin_password: 'admin123'

ํ”Œ๋ ˆ์ด๋ถ์—์„œ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.. ์ด ๋ณ€์ˆ˜๋Š” ์ฒ˜์Œ ์„ค์น˜ํ•  ๋•Œ ๊ธฐ๋ณธ Nexus ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์ฑ„์›Œ์ง€๋ฉฐ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋‹ค์Œ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. nexus_admin_password.

์ฒ˜์Œ ์„ค์น˜ํ•œ ํ›„ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋ช…๋ น์ค„์—์„œ ์ผ์‹œ์ ์œผ๋กœ ์ด์ „ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ํ›„ nexus_admin_password ํ”Œ๋ ˆ์ด๋ถ์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ansible-playbook -i your/inventory.ini your_playbook.yml -e nexus_default_admin_password=oldPassword

Nexus Sonatype์˜ ํ…”๋ ˆ๊ทธ๋žจ ์ฑ„๋„: https://t.me/ru_nexus_sonatype

๋“ฑ๋ก๋œ ์‚ฌ์šฉ์ž๋งŒ ์„ค๋ฌธ ์กฐ์‚ฌ์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์ œ๋ฐœ

์–ด๋–ค ์•„ํ‹ฐํŒฉํŠธ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์‹œ๋‚˜์š”?

  • ์†Œ๋‚˜ํƒ€์ž… ๋„ฅ์„œ์Šค๋Š” ๋ฌด๋ฃŒ์ž…๋‹ˆ๋‹ค

  • ์†Œ๋‚˜ํƒ€์ž… ๋„ฅ์„œ์Šค ์œ ๋ฃŒ

  • ์•„ํ‹ฐํŒฉํ† ๋ฆฌ๋Š” ๋ฌด๋ฃŒ์ž…๋‹ˆ๋‹ค

  • ์•„ํ‹ฐํŒฉํ† ๋ฆฌ ์ง€๊ธ‰

  • ํ•ญ๊ตฌ

  • ํŽ„ํ”„

9๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํˆฌํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. 3๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๊ถŒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€