Nexus 3 OSS একটি ওপেন সোর্স আর্টিফ্যাক্ট রিপোজিটরি ম্যানেজার যা কন্টেইনার ইমেজ, Python PIP, Java jar এবং অন্যান্য অনেক ফরম্যাট হ্যান্ডেল করতে পারে।
অন-প্রিমাইস আর্টিফ্যাক্ট ম্যানেজার কেন রাখবেন? এর অনেক কারণ আছে:
নিজস্ব ইনফ্রাস্ট্রাকচার ব্যবহার: আপনার প্রپرাইটারি কোড থাকতে পারে যা সুরক্ষিত রাখতে হয়।
দ্রুত আর্টিফ্যাক্ট ডাউনলোড স্পিড: আপনি যদি বারবার একই আর্টিফ্যাক্ট ইন্টারনেট থেকে ডাউনলোড করেন, তবে সেগুলো একটি সেন্ট্রাল লোকেশনেই ক্যাশ করে রাখলে একাধিক সার্ভারের একাধিক ব্যবহারকারী উপকৃত হবেন।
বিল্ড চেইনে কোন আর্টিফ্যাক্ট যাবে তা নিয়ন্ত্রণ: আর্টিফ্যাক্টের লোকেশন সেন্ট্রালাইজ করুন, নিশ্চিত করুন সেগুলো ব্যবহার অনুমোদিত এবং ম্যালিশিয়াস কোড ছাড়া।
কौন কোন আর্টিফ্যাক্ট এক্সেস করবে তা পৃথক করুন: আপনার সংস্থায় কئكемо আর্টিফ্যাক্ট এক্সেসের জন্য কঠোর.requirement থাকতে পারে।
এই আর্টিকেলে আমি দেখাব কীভাবে Ansible playbook ব্যবহার করে Nexus 3-এর OSS ভার্সন ডাউনলোড, ইনস্টল এবং কনফিগার করবেন।
Nexus 3 ৮ GB RAM যুক্ত একটি Orange PI 5 কম্পিউটারে চলবে, কিন্তু এই প্রোভিশনিং ন্যূনতম রিকোয়ারমেন্ট वाले যেকোনো মেশিনে করা যাবে। সেটআপের অংশ হিসেবে, আমার ইনভেন্টরি ফাইলে লিস্ট করা মেশিনগুলোের জন্য PyPI.org-এর একটি প্রক্সি সেট করা থাকবে।
এই টিউটোরিয়ালের কোড রান করার জন্য কী কী লাগবে
Ansible playbook, Nexus, এবং PIP মডিউলের সোর্স কোড ডাউনলোড করার জন্য ইন্টারনেট সংযোগ
দুই বা অধিক লিনাক্স মেশিন (আমি Debian, Armbian এবং Fedora IOT ব্যবহার করেছি), কমপক্ষে ৮ GB RAM। আমার ক্লাস্টারে Raspberry PI 4 এবং একটি OrangePI 5 মিশ্রিত।
Ansible কন্ট্রোলার Fedora মেশিনে চলবে, কিন্তু যেকোনো সার্ভার কন্ট্রোলার হতে পারে। Ansible ইনস্টলেশন ইনস্ট্রাকশন ফলো করা সহজ।
Playbook Organisation
আমি টাস্কগুলো গ্রুপে ভাগ করেছি এবং ফলস্বরূপ playbookটি এমন দেখে:
[josevnz@dmaf5 Nexus3OnOrangePI]$ tree -N ansible/ ansible/ ├── inventories │ └── home │ └── hosts.yaml ├── roles │ ├── clients │ │ ├── tasks │ │ │ └── main.yaml │ │ └── templates │ │ └── pip.conf.j2 │ └── nexus │ ├── files │ │ └── swagger.json │ ├── tasks │ │ ├── download.yaml │ │ ├── install.yaml │ │ ├── main.yaml │ │ ├── post_install.yaml │ │ ├── pre_install.yaml │ │ ├── repositories.yaml │ │ ├── third_party.yaml │ │ └── user.yaml │ └── templates │ ├── logrotate.nexus3.j2 │ ├── nexus3.service.j2 │ ├── nexus.rc.j2 │ └── nexus.vmoptions.j2 ├── site.yaml ├── vars │ ├── clients.yaml │ └── nexus.yaml └── vault ├── nexus_password.enc └── README.md 13 directories, 21 files এখন কিছু ব্যাখ্যা:
দুটি রোল আছে: ‘nexus’ এবং ‘clients’। nexus রোলটি আর্টিফ্যাক্ট ম্যানেজমেন্ট সফটওয়্যার সেটআপ করতে ব্যবহৃত হয়, যেখানে client রোলটি প্রতিটি মেশিনে pip সেটিংস সেটআপ করে।
Vars-এ প্রতিটি রোলের জন্য ব্যবহৃত ভেরিয়েবল থাকে, যেগুলো ফাইল অনুযায়ী পৃথক করা হয়েছে ব্যবহার স্পষ্ট করতে।
পাসওয়ার্ডগুলো আছে, এবং আমরা Ansible vault ফিচার ব্যবহার করে সেগুলো ম্যানেজ করেছি।
‘site.yaml’ ফাইলটি রোল এক্সিকিউশন অর্কেস্ট্রেট করে:
- hosts: all tags: clients vars_files: - vars/clients.yaml roles: - clients - hosts: nexus_server tags: nexus become_user: root become: true vars_files: - vars/nexus.yaml roles: - nexus এখন প্লেবুক এক্সিকিউট হওয়ার यूनিভার্স দেখি।
হост ইনভেন্টরি
আমার কেসে এটি বেশ সিম্পল – আমার দুটি মূল গ্রুপ আছে: ‘clients’ এবং যে মেশিনে Nexus 3 সার্ভারই চলবে:
all: children: nexus_server: hosts: orangepi5.home: home_lab: hosts: dmaf5.home: raspberrypi.home: orangepi5.home: পরবর্তী গুরুত্বপূর্ণ টাস্ক হল Nexus 3 ডাউনলোড এবং কনফিগার করা।
Nexus 3 ইনস্টল করার পদ্ধতি
main.yaml ফাইলটি Nexus রোলের প্রতিটি ইনস্টলেশন টাস্কের ক্রম এবং উদ্দেশ্য বর্ণনা করে:
# Tasks listed here are related to the remote Nexus 3 server # Included tasks are called in order --- - include_tasks: third_party.yaml - include_tasks: pre_install.yaml - include_tasks: download.yaml - include_tasks: install.yaml - include_tasks: post_install.yaml - include_tasks: user.yaml - include_tasks: repositories.yaml প্রথমে যা আমি "core tasks" বলি সেগুলো দেখি:
third_party.yaml: এখানে আমরা OpenJDK8 (Nexus 3 জাভায় লেখা) এবং logrotate ইনস্টল করি পুরনো লগ হ্যান্ডেল করার জন্য।
pre_install.yaml: এখানে অনেক কিছু হয়, যেমন nexus-এর জন্য প্রয়োজনীয় ডিরেক্টরি তৈরি, ডেডিকেটেড non-privileged ইউজার তৈরি যা প্রসেস চালাবে।
download.yaml: নাম অনুযায়ী, আমরা Nexus 3 OSS সফটওয়্যারের একটি ফ্রেশ ভার্সন পাই এবং নিশ্চিত করি সেটির সঠিক চেকসাম। আমরা ইন্টারনেট থেকে ম্যালওয়্যার ইনস্টল করতে চাই না।
তারপর আসে "customized installation group"-এ পড়া টাস্কগুলো:
install.yaml: সফটওয়্যার আনপ্যাক করুন, সিস্টেমড یونিট প্রস্তুত করুন যাতে এটি অটোমেটিক শুরুর, Nexus-এর জন্য JVM সেটিংস সেটআপ করুন, এবং logrotate কনফিগারেশন ডিপ্লয় করুন।
post_install.yaml: এখানে একসাইটিং কিছু হয় – সফটওয়্যার ইনস্টল হয়ে গেল, এবং আমরা এটি প্রথমবার চালাই। আমরা REST API ব্যবহার করে ডিফল্ট পাসওয়ার্ড পরিবর্তন করি, যাতে কাস্টমাইজেশন স্টেজে যেতে পারি।
user.yaml: এখানে আমরা আমাদের এন্ড ইউজারদের Nexus-এর সার্ভিসগুলোর সঠিক এক্সেস দিতে প্রস্তুতি নেয়। আমরা REST-API এবং Ansible ক্লায়েন্ট কোডের কম্বিনেশন ব্যবহার করে এটি করি:
# https://help.sonatype.com/repomanager3/installation-and-upgrades/post-install-checklist # https://help.sonatype.com/repomanager3/integrations/rest-and-integration-api --- - name: Enable anonymous user tags: anonymous ansible.builtin.uri: user: "" password: "" url: "/v1/security/anonymous" method: PUT body_format: raw status_code: [ 200, 202, 204 ] headers: Content-Type: application/json body: |- { "enabled" : true, "userId" : "anonymous", "realmName" : "NexusAuthorizingRealm" } force_basic_auth: true return_content: true any_errors_fatal: true - name: Enable Docker security realm tags: docker_realm ansible.builtin.uri: user: "" password: "" url: "/v1/security/realms/active" method: PUT body_format: raw status_code: [ 200, 202, 204 ] headers: Content-Type: application/json body: |- [ "NexusAuthenticatingRealm", "NexusAuthorizingRealm", "DockerToken" ] force_basic_auth: true return_content: true any_errors_fatal: true লজিক সহজে ফলো করা যায়, 'PUT' HTTP মেথড ব্যবহার করে আপনি বোঝাতে পারেন এটি একটি মডিফিকেশন অপারেশন (অর্থাৎ বিদ্যমান রোল এবং ইউজার ইতিমধ্যে আছে)। এরর ডিটেকশন করা হয় Nexus দ্বারা রিটার্ন করা HTTP কোডগুলো পেতে।
পরবর্তী ধাপ হল আমাদের লোকাল PyPi প্রক্সি প্রস্তুত করা। এটি একটি মাল্টিস্টেপ টাস্ক এবং পরবর্তীতে বিস্তারিত বর্ণনা করা হবে।
Nexus 3-এ PyPI Proxy সেটআপ করার পদ্ধতি
Nexus 3 রোলের শেষ ফাইল হল ‘repositories.yaml’। এখানে আমরা নিচের ধাপগুলো অনুসরণ করি:
চেক করুন প্রক্সি ইতিমধ্যে সেটআপ আছে কিনা (GET বা রিড-অনলি অপারেশন)
যদি না থাকে, তবে একটি নতুন তৈরি করুন (POST মেথড JSON পেলোড দিয়ে পুরো নতুন রিপোজিটরি তৈরি করতে)
দ্রষ্টব্য যে এই প্লেবুক রিপোজিটরি সেটিংস আপডেট করার অপশন দেয় না। REST API-তে এটি করা সম্ভব, তবে আমি এটি পাঠকের জন্য এক্সারসাইজ হিসেবে রেখেছি।
PyPi প্রক্সি প্রস্তুত করার টাস্কগুলো নিচে দেখানো হলো:
# Create proxy for repositories # https://help.sonatype.com/repomanager3/integrations/rest-and-integration-api # PyPi: https://pip.pypa.io/en/stable/user_guide/ --- - name: Check if the PyPi proxy exists tags: pypi_proxy_exists ansible.builtin.uri: user: "" password: "" url: "/v1/repositories/pypi/proxy/python_proxy" method: GET body_format: raw status_code: [ 200, 202, 204, 404 ] headers: Content-Type: application/json force_basic_auth: true return_content: true any_errors_fatal: true register: python_local - name: Create PyPI proxy tags: pypi_proxy_create ansible.builtin.uri: user: "" password: "" url: "/v1/repositories/pypi/proxy" method: POST body_format: raw status_code: [ 201 ] headers: Content-Type: application/json body: |- { "name": "python_proxy", "online": true, "storage": { "blobStoreName": "default", "strictContentTypeValidation": true }, "proxy": { "remoteUrl": "https://pypi.org/", "contentMaxAge": -1, "metadataMaxAge": 1440 }, "negativeCache": { "enabled": true, "timeToLive": 1440 }, "httpClient": { "blocked": false, "autoBlock": true, "connection": { "retries": 0, "timeout": 60, "enableCircularRedirects": false, "enableCookies": true, "useTrustStore": false } } } force_basic_auth: true return_content: true any_errors_fatal: true when: python_local.status == 404 আমরা почти শেষে পেয়েছি। এখন আমাদের PyPi ক্লায়েন্টদের বলতে হবে যে তারা ডায়রেক্ট PyPi সাইটের বদলে আমাদের লোকাল Nexus ব্যবহার করে Python লাইব্রেরি পাবে।
ক্লায়েন্ট সেটআপ করার পদ্ধতি
clients রোলটি অনেক সহজ এবং শুধু pip.conf-এর একটি টেমপ্লেট ডিপ্লয় করতে হয় যথেষ্ট ইনফো দিয়ে যাতে সার্চ আমাদের নতুন রিপোজিটরিতে বাধ্যতামূলক হয়:
# Tasks here are meant to be used on our clients user --- - name: Create installation directory for pip.conf tags: pip_basedir ansible.builtin.file: state: directory path: "" owner: "" group: "" mode: "u+rwx,go-rwx" - name: Copy pip.conf file tags: pip_copy ansible.builtin.template: src: pip.conf.j2 dest: "/pip.conf" owner: "" group: "" mode: u=rxw,g=r,o=r ফলস্বরূপ ফাইলটি প্রতিটি মেশিনে ‘~/.config/pip/pip.conf’-এ ডিপ্লয় হয়:
# https://pip.pypa.io/en/stable/topics/configuration/ [global] timeout = 60 [install] index = https://orangepi5.home:8081/repository/python_proxy/pypi index-url = https://orangepi5.home:8081/repository/python_proxy/simple/ trusted-host = orangepi5.home উপরের ফাইলটি দেখায় কীভাবে ফাইনাল ভার্সনটি আমার ক্লাস্টারে ডিপ্লয় হওয়ার পর দেখাবে (আপনারটি রেজলভড URL-এর সাথে ভিন্ন হবে)।
এখন পুরো প্লেবুক রান করি এবং দেখি কী হয়।
প্লেবুক রান করার পদ্ধতি
প্লেবুক রান করতে আমরা কিছু আর্গুমেন্ট পাস করি:
আমাদের হост ইনভেন্টরির লোকেশন
এনক্রিপ্টেড পাসওয়ার্ড ফাইলের লোকেশন এবং একটি মাস্টার ফাইল যাতে ভল্ট পাসওয়ার্ড থাকে প্রোটেক্টেড ফাইলের কন্টেন্ট আনলক করার জন্য
এবং অবশেষে আমাদের মেইন প্লেবুক ফাইলের লোকেশন
cd ansible ansible-playbook --inventory inventories --extra-vars @vault/nexus_password.enc --vault-password-file $HOME/vault/ansible_vault_pass site.yaml 
নতুন PyPI প্রক্সি টেস্ট করার পদ্ধতি
নতুন প্রক্সি টেস্ট করতে, আমরা pip এবং ভার্চুয়াল এনভায়রনমেন্ট ব্যবহার করে Python Rich ইনস্টল করব।
josevnz@orangepi5:~$ python3 -m venv ~/virtualenv/rich (rich) josevnz@orangepi5:~$ . ~/virtualenv/rich/bin/activate (rich) josevnz@orangepi5:~$ pip install rich Looking in indexes: https://orangepi5.home:8081/repository/python_proxy/simple/ Collecting rich Downloading https://orangepi5.home:8081/repository/python_proxy/packages/rich/13.3.4/rich-13.3.4-py3-none-any.whl (238 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 238.7/238.7 KB 14.8 MB/s eta 0:00:00 Collecting pygments<3.0.0,>=2.13.0 Downloading https://orangepi5.home:8081/repository/python_proxy/packages/pygments/2.15.0/Pygments-2.15.0-py3-none-any.whl (1.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 23.8 MB/s eta 0:00:00 Collecting markdown-it-py<3.0.0,>=2.2.0 Downloading https://orangepi5.home:8081/repository/python_proxy/packages/markdown-it-py/2.2.0/markdown_it_py-2.2.0-py3-none-any.whl (84 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 84.5/84.5 KB 6.9 MB/s eta 0:00:00 Collecting mdurl~=0.1 Downloading https://orangepi5.home:8081/repository/python_proxy/packages/mdurl/0.1.2/mdurl-0.1.2-py3-none-any.whl (10.0 kB) Installing collected packages: pygments, mdurl, markdown-it-py, rich Successfully installed markdown-it-py-2.2.0 mdurl-0.1.2 pygments-2.15.0 rich-13.3.4 এবং তারপর আমরা নতুন রিপোজিটরিতে নতুন আর্টিফ্যাক্ট দেখে ক্যাশ ব্যবহার হয়েছে কিনা নিশ্চিত করতে পারি:

PyPi আর্টিফ্যাক্ট দেখুন
একটি ক্লায়েন্ট ডেমো দেখি অন্য কিছু ইনস্টল করে:

REST-API ব্যবহার করে আরও কাস্টমাইজেশন
প্রতিটি Nexus ইনস্টলেশন আপনাকে একটি JSON ফাইল ডাউনলোড করতে দেয় যা সার্ভার দ্বারা সাপোর্টেড API বর্ণনা করে। উদাহরণস্বরূপ, আমার সার্ভারে orangepi5.home-এ থেকে আপনি এভাবে একটি কপি পেতে পারেন:
curl --fail --remote-name https://orangepi5.home:8081/service/rest/swagger.json অছা, UI-তেও আপনি অন্যান্য REST API এন্ডপয়েন্ট ট্রাই করে আপনার ইনস্টলেশন কাস্টমাইজ করতে পারেন।

REST API টেস্টিং
উপসংহার
আমি সুপারিশ করব কিছু সময় ব্যয় করে Nexus 3 বুকটি পড়ুন যাতে এই টুল যে ফিচারগুলো অফার করে সেগুলো আপনি জানতে পারেন।
কমিউনিটি Debian এবং RPM ইনস্টলার তৈরি করেছে, যদি আপনাকে Ansible-এর বদলে সেই সেটআপ দরকার হয়।
Nexus 3-র অনেক বেশি কনফিগারেবল সেটিংস আছে। আমরা এখানে শুধু সতহী কভার করেছি। এই আর্টিকেল প্রস্তুত করার সময় আমি 'ThoTeam Nexus3-oss repository' খুঁজে পেলাম যা খুব কমপ্লিট এবং আপ-টু-ডেট প্লেবুক, কিন্তু আমার হোম ল্যাবের জন্য প্রয়োজনীয় চেয়ে অনেক জটিল।
Archiva আরেকটি ওপেন সোর্স আর্টিফ্যাক্ট ম্যানেজার, এটি ফাংশনালিটিতে আরও সীমিত কিন্তু সেটআপ করা সহজ।
একটি পোস্ট-ইনস্টলেশন চেকলিস্ট আছে কিছু টাস্কের সাথে যা আমার হোম ল্যাবের জন্য প্রয়োজন হয়নি। সেটি চেক আউট করুন আপনার সেটআপ কমপ্লিট নিশ্চিত করতে।
বিনামূল্যে কোডিং শিখুন। freeCodeCamp-এর ওপেন সোর্স করিকুলাম ৪০,০০০ এর বেশি লোককে ডেভেলপার হিসেবে জব পেতে সাহায্য করেছে। শুরু করুন।