<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های mandi.nariman</title>
        <link>https://virgool.io/feed/@mandi.nariman</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 14:53:59</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/10107/avatar/MPhO3H.png?height=120&amp;width=120</url>
            <title>mandi.nariman</title>
            <link>https://virgool.io/@mandi.nariman</link>
        </image>

                    <item>
                <title>راه اندازی Gitlab CI/CD از صفر تا صد</title>
                <link>https://virgool.io/baharan-co/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-gitlab-cicd-%D8%A7%D8%B2-%D8%B5%D9%81%D8%B1-%D8%AA%D8%A7-%D8%B5%D8%AF-y7i07ifluivr</link>
                <description>این روز ها با داغ شدن فضای startup  ها خیلی از developer ها دور هم جمع شدند و دارند روی یک ایده کار میکنند تا در نهایت به یک اپلیکیشن برسند . یکی از معضلاتی که سال ها پیش برای developer هایی که به صورت تیمی کار می کردند وجود داشت این بود که مدیریت source پروژه کار بسیار سختی بود و حتی source ها رو با flash جا به جا میکردند اما با بالا رفتن سرعت اینترنت و رشد تکنولوژی ، source control ها مطرح شدند و همون طور که امروز نگاه میکنیم سایت هایی مثل Gitlab و Github این روزها با استفاده از version control گیت (git) به راحتی این مشکل رو برای همه حل کردند ، مخصوصا این روز ها که Github هم با اضافه کردن امکان ساخت private repository برای کاربران غیر premium فضای کار رو رقابتی تر کرده  و developer  ها در هرجای دنیا میتونن بدون هیچ مشکلی source ها رو در اختیار داشته باشن و روشون کار کنند بدون اینکه هیچ نگرانی وجود داشته باشه.اما یکی دیگه از مشکلات تیم ها روند نسخه گذاری هست که یه جورایی کار روتین و وقت گیری محسوب میشه . اینجاست که کمپانی های بزرگ به این فکر افتادن که چجوری میشه روال نسخه گذاری رو راحت تر کرد ، که اینجا نقطه تولد  Continuous Integration and Continuous Delivery یا همون CI/CD هست.در واقع CI/CD میاد source و روال build  شما رو با هم integrate می کنه و در نهایت اون رو به محیط production شما deliver می کنهبه زبان ساده اگر بخوام بگم CI/CD روال نسخه گذاری رو automatic میکنه . فرض کنید اپلیکیشنی دارید که به تازگی بالا اومده و یک سری مشتری دارن باهاش کار میکنند . حالا اگه روال نسخه گذاریتون وقت گیر باشه و یه باگی هم توی سیستم به وجود بیاد ، چقدر روال  توسعه و پشتیبانی سیستم برای رفع مشکلات به وجود آمده میتونه ترسناک باشهیا این طور در نظر بگیرید که اون نفری از تیمتون که عملیات نسخه گذاری رو بلد بوده و همیشه انجام میداده نیست و شما هم بهش دسترسی ندارید حالا باید چی کار کنیم؟با استفاده از CI/CD به راحتی میتونید این کار رو انجام بدید . فرض کنید مشکل رو درست کنید و commit کنید و تنها برای نسخه گذاری ، داخل source control خودتون login کنید و  یک دکمه رو فشار بدید و چند دقیقه بعدش اپلیکیشنتون با آخرین تغییرات روی سرور آماده بهره برداری باشهتوی این نوشته من نحوه راه اندازی gitlab Ci/CD ، روی یک پروژه جاوایی رو آموزش میدم و امیدوارم که بتونید ازش استفاده کنیدتوجه : برای متوجه شدن مفاهیم این متن ، آشنایی با داکر و مفاهیم آن الزامی است و برای کمک میتونید به این پست مراجعه کنیدآشنایی با Docker از نصب تا راه اندازیبا یک مثال سعی میکنم مفاهیم رو شفاف تر توضیح بدم تا بهتر متوجه بشید.مثالمن یک اپلیکیشن جاوایی دارم که در نهایت قراره یک war فایل بشه . پس اولین قدم ما ، ساختن یک image داکری از روی war فالمون محسوب میشه.قطعا اپلیکیشن ما یک دیتابیس داره که به کمکش داریم اطلاعات مورد نیازمون رو در اون ذخیره میکنیم. من توی این مثال از دیتابیس mysql استفاده میکنم ، پس قدم بعدی ساخت یک image از دیتابیس محسوب میشه که این بخش هم کار راحتی هست و خود mysql توی dockerhub ایمیج و نحوه استفاده اش رو قرار داده که لینک اش رو اینجا قرار میدمایمیج mysqlحالا برای اجرا کردن این image های ساخته شده نیازمند یک فایل docker-compose.yml هستیم که بتونیم داخل اون image های اپلیکیشن و دیتابیسی که ساختیم رو اجرا کنیم.بهتر این است که خود mysql هم توی یک mysql-compse.yml ای باشه به صورت جداگانه و توی docker-compose اصلی مون docker-compose مربوط به mysql رو extend کنیم ، که در ادامه نحوه این کار رو توضیح میدم.پس همون طور که گفتم دو تا container خواهیم داشت یکی برای application اصلی و یکی هم برای mysqlحالا اینطور در نظر بگیرید که اگر به دنبال build کردن اپ خودتون باشید ، قطعا باید آخرین نسخه اپلیکیشن رو از سورس کنترل خودمون که کدها رو اونجا کامیت کردیم ، دریافت کنیم.پس در ادامه به این شکل میریم جلو که شما از gitlab به عنوان source control استفاده میکنید و یه سرور cloud  یا  vps هم گرفتید که میخواین اپکلیکیشن خودتون رو اونجا اجرا کنید.اگر بخوام دقیق تر بگم باید دستور docker-compose up -d که از روی یک image یک container میسازده و اون رو start میکنه باید توی سرورمون اجرا بشه . پس اولین سوالی که مطرح میشه اینه که سرورمون قراره این ایمیج رو از کجا بیاره ؟ در واقع همون طور که وقتی میخوایم یه داکر ایمیج از روی mysql بسازیم ، اون رو از dockerhub میگیریم یا اصطلاحا pull کنیم. اینجا هم باید بپذیریم که image مربوط به اپلیکیشن ما باید یه جایی push بشه تا ما روی سرورمون بتونیم اون رو pull کنیم و اجراش کنیم.توضیحات بالا سناریو کلی بود که برای انجام automatic نسخه گذاری باید انجام بدیمبرمیگردیم به gitlab که source countrol ماست . gitlab میگه که من میتونم به شما CI/CD ارائه بدم و در قالب یک سری stage بیام source شما رو بخونم و بسته به نوع پروژه ، مثلا اگر جاوایی هست با maven بیلد رو انجام بدم .خود گیت لب برای اینکه بتونه این کار رو انجام بده داره از مکانیزم داکر استفاده میکنه ، یعنی داخل خودش یک سری container های داکری رو داره اجرا میکنه پس برای اینکار از یک فایل به اسم &#x27;gitlab-ci.yml.&#x27; استفاده میکنه که در اون stage های مختلف رو میخونه و اجرا میکنه .این stage ها در واقع مراحل انجام کار هستند مثلا اولین مرحله build کردن ، دومین مرحله ساخت image و سومین مرحله اجرا ، روی سرور ما است.مکانیزم گیت لب به این شکل هست که وقتی یک  stage اجرا میشه و complete  میشه همه چیزش پاک میشه یعنی یه جورایی هر stage یک temp محسوب میشه. که در ادامه میگم که این به چه معنی هست و برای ارتباط برقرار کردن بین این stage ها و دل و بدل کردن دیتا چه کار هایی رو باید انجام بدیم.پایپ لاین ها (Pipelines)یک pipeline مجموعه ای از job هایی هست که در قالب چندین stage اجرا میشن و از طریق منو pipeline قابل دسترسی هستند. اگر تمامی job ها با موفقیت اجرا بشن ، pipeline به stage بعدی میره اما اگه یکی از job ها fail بشه ، pipeline همونجا متوقف میشه در عکس زیر عکس یک pipeline رو مشاهده میکنید که متشکل از چهار stage هست که هر کدوم حداقل یکی یا بیش از یک job دارنلایبراریاگر library ندارید لازم به خوندن این بخش نیستخب بزارین قبل شروع ساختار پروژه رو باز کنم . فرض کنید که ما یک library داریم که یک پروژه maven ای هست و کانفیگ های اصلی پروژمون و یک سری مدل های base که ممکنه توی تمامی اپ هامون مشترک باشه رو اونجا قرار دادیم . مثل تنظیمات spring boot و spring security و مدل هایی مثل user و …خب تا قبل از این چی کار میکردیم ؟لایبراریمون رو با maven goal زیر اجرا میکردیم تا بره و توی پوشه m2. قرار بگیره و اون رو به عنوان یک dependency به فایل pom.xml پروژه مون اضافه میکردیم تا ازش استفاده کنیم.clean package installاما حالا که قراره تمام این کار ها رو gitlab برامون انجام بده پس باید لایبراریمون رو توی یک maven repository که به صورت private باشه قرار بدیم تا gitlab  هم بتونه به اون دسترسی داشته باشه.پس توی پروژه لایبراریمون یه فایل gitlab-ci.yml. داریم که تنها یک stage  داره و اون هم build هست و قراره که وقتی تغییری روی library انجام میدیم و کامیت میکنیم ، gitlab اون رو build کنه و روی mymavenrepo که یک maven repository شخصی به ما ارائه میده deploy کنه.پس میریم توی mymavenrepo یک اکانت درست میکنم. برای اینکه بتونیم توی یه repository عملیات deploy انجام بدیم باید یه url و یک user,pass داشته باشیم تا ازش استفاده کنیمحالا برای بیلد کردن پروژه نیازمند maven هستم و اینجا هم base image من maven ای هست و دستورات maven رو میشناسه . حالا میخوام deploy کنم ولی سوال اینجاست که به کدوم آدرس؟یا باید برم داخل pom.xml بزارم یا توی settings.xml مربوط به m2 توی mavenاما بحث اینجاست که m2 باید توی محیط اجرا باشه ( یعنی توی سرورم ) پس میتونم کنار source خودم یه directory بسازم به اسم m2. و به maven از طریق settings.xml میگم که دایرکتوری maven من اینجاست . در واقع من آدرس default رو تغییر میدم به این دایرکتوی که تو روت پروژه ام ساختم.Settings.xml&lt;settings&gt;
    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;myMavenRepoRead&lt;/id&gt;
            &lt;activation&gt;
                &lt;property&gt;
                    &lt;name&gt;!doNotUseMyMavenRepo&lt;/name&gt;
                &lt;/property&gt;
            &lt;/activation&gt;
            &lt;properties&gt;
                &lt;myMavenRepoReadUrl&gt;https://mymavenrepo.com/repo/sampleUrl/&lt;/myMavenRepoReadUrl&gt;
            &lt;/properties&gt;
        &lt;/profile&gt;
        &lt;profile&gt;
            &lt;id&gt;myMavenRepoWrite&lt;/id&gt;
            &lt;activation&gt;
                &lt;property&gt;
                    &lt;name&gt;!doNotUseMyMavenRepo&lt;/name&gt;
                &lt;/property&gt;
            &lt;/activation&gt;
            &lt;properties&gt;
                &lt;myMavenRepoWriteUrl&gt;https://mymavenrepo.com/repo/sampleUrl/&lt;/myMavenRepoWriteUrl&gt;
            &lt;/properties&gt;
        &lt;/profile&gt;
    &lt;/profiles&gt;

    &lt;servers&gt;
        &lt;server&gt;
            &lt;id&gt;myMavenRepoRead&lt;/id&gt;
            &lt;username&gt;test&lt;/username&gt;
            &lt;password&gt;test&lt;/password&gt;
        &lt;/server&gt;
        &lt;server&gt;
            &lt;id&gt;myMavenRepoWrite&lt;/id&gt;
            &lt;username&gt;test&lt;/username&gt;
            &lt;password&gt;test&lt;/password&gt;
        &lt;/server&gt;
    &lt;/servers&gt;
&lt;/settings&gt;حالا برای اجرا کردن دستورات maven یا باید بریم اون رو توی ماشینمون نصب و config کنیم ، یا میتونیم دو تا فایل mvnw.sh و bat رو به root پروژه اضافه کنیم.کار این دو فایل این هست که دستورات maven رو میشناسند ، پس این دو تا فایل هم به root پروژه library اضافه میکنیم که این نگرانی رو نداشته باشیم که توی ماشینمون maven نصب هست یا نهخب پس حالا باید library رو بیلد کنیم که در نهایت میشه یه jar file و اون رو توی mavenrepo که بالاتر گفتم قرار میده و میتونیم ازش استفاده کنیم.این هم کد مربوط به gitlab-ci.yml. فریم ورک.gitlab-ci.ymlimage: maven:latest

variables:
  MAVEN_CLI_OPTS: &quot;-s .m2/settings.xml --batch-mode&quot;
  MAVEN_OPTS: &quot;-Dmaven.repo.local=.m2/repository&quot;

cache:
  paths:
    - .m2/repository/
#    - target/

build:
  stage: build
  when: manual
  script:
    - mvn $MAVEN_CLI_OPTS deploy
وقتی when:manual رو مینویسیم این قابلیت رو به شما میده که برید داخل gitlab و از منوی CI/CD&gt;Pipelines خودتون به صورت دستی دکمه استارت رو بزنید ، که توی عکس زیر مشخصهخب الان مرحله library تموم شد پس میرسیم به اپلیکیشن خودمون . خب قطعا توی اولین مرحله build  به dependency لایبراری که ساختیم ،  نیاز داریم ، پس باید بهش بفهمونم که باید از کجا dependency پروژه رو بگیرهپس توی پروژه مون دوباره دایرکتوری m2. و settings.xml رو قرار میدم تا متوجه بشه که از کجا باید dependency رو دانلود کنه.بخش مربوط به library تموم شد میتونید از اینجا به بعد رو ادامه بدیداستیج هاحالا برمیگردیم روی اپ خودمون ، که در اینجا ما قرار بود ۳ تا stage  داشته باشیم BuildBuild docker imageDeployیه نکته ای که باید بدونیم اینه که gitlab به ازای هر کدوم از این stage ها یک container میسازه ، یعنی توی مثال ما ، ۳ تا container داریم که به ترتیب اجرا میشن.همونطور که بالا تر گفتم هر کدوم از این container های داکری وقتی کارشون تموم میشه dispose میشن و ما دیگه بهشون دسترسی نداریم.پس سوال اصلی اینجاست که ما توی stage اول که داریم پروژه رو build میکنیم و به یک war file میرسیم و بعدش قراره توی stage دوم از روش یه docker image بسازیم ، چجوری قراره توی stage دوم از war فایلی که توی stage اول ساخته شده استفاده کنیم ؟ اون که dispose شده ؟؟؟اینجا gitlab  از یک مفهوم به اسم artifact استفاده میکنه و میگه اگر قراره بین این stage  ها فایلی رد و بدل بشه باید از طریق artifact به من بگی نحوه کارش اینجوری هست که gitlab برای خودش یک دایرکتوری داره که artifact ها رو به ازای jobId ها store میکنه و قبل از اینکه کار stage تموم بشه توی log میبینید که میزنه upload artifact و بعد از success شدن stage میبیند که وقتی میخواد stage بعدی رو شروع کنه اول میزنه download artifact و بعد ادامه مراحل رو پیش میگیره.استیج اول (build)بخش اول فایل gitlab-ci.yml..gitlab-ci.ymlimage: openjdk:8-jdk-alpine

variables:
    DOCKER_HOST: tcp://docker:2375
    MAVEN_CLI_OPTS: &quot;-s .m2/settings.xml --batch-mode&quot;
    MAVEN_OPTS: &quot;-Dmaven.repo.local=.m2/repository&quot;

services:
  - docker:dind

stages:
  - build
  - build-image
  - deploy-ssh


build:
  stage: build
  when: manual
  before_script:
  - apk update
  - apk add --nocache git
  - apk add --update nodejs nodejs-npm &amp;&amp; node -v
  - apk add maven &amp;&amp; mvn --version
  - npm install -g yarn
  - yarn --version
  - npm install -g @angular/cli@1.7.3
  script:
        - &#039;./mvnw  $MAVEN_CLI_OPTS package &#039;
  only:
    - master
  artifacts:
    expire_in: 10 mins 0 sec
    paths:
        - target/app.war
        - target/Dockerfile
خب من از openjdk alpine به عنوان base image استفاده کردم که خودش یک لینوکس light weight داره و jdk  روش کانفیگ شده که دستور java -jar رو برای اجرای پروژه بشناسهتوی بخش variables متغیر های مربوط به maven و docker host رو اضافه کردم که بسته به نوع تکنولوژی ها و زبان برنامه نویسی که استفاده میکنید این کانفیگ ها میتونه متفاوت باشهتوی بخش services گفتم که از سرویس docker in docker استفاده کنه چون در حقیقت این container هایی که داره توسط gitlab ساخته میشه باید وقتی اجرا میشن و میان بالا به صورت پیشفرض docker داخل container اش نصب باشه تا بتونن دستوراتی مثل docker-compose up رو اجرا کنندتوی بخش stages ابتدا مشخص میکنیم که چند تا stage داریم که در اینجا ۳ تا هست و بعد به ترتیب اسم stage ها رو میگیم و مشخص میکنیم که توی هر stage باید چه کاری رو انجام بده.خب در ابتدا stage : build رو توضیح میدم.توی قسمت beforeScripts  میتونم بگم که قبل از اینکه script من رو اجرا کنی یه سری کار ها رو انجام بده که در اینجا من node رو update کردم و yarn رو نصب کردم چون فریم ورک UI که استفاده میکردم angular بودهتوی بخش script گفتم که دستور maven build رو اجرا کنه تا  war فایل پروژه ام ساخته بشه توی قسمت only گفتم که دستور رو روی کدوم branch ای که روی گیت لب دارم اجرا کنهتوی قسمت artifacts توی بخش expire_in گفتم که حداکثر زمانی که این container اجازه داره زنده بمونه چقدرهو در نهایت توی قسمت paths بهش گفتم که دو فایل app.war و Dockerfile  رو از مسیر های که مشخص کردم بردار و به عنوان artifact به stage بعدی بفرستاستیج دوم (build-image)حالا وقتشه که از war file ای که ساختیم یک docker image بسازیم شاید بپرسید که چرا باید این کار رو بکنیم در جواب چرا باید بگم که راحتی کار کردن با dockerبزارید با یه مثال بهتر توضیح بدم فرض کنید که یه سرور لینوکسی گرفتین و میخواین روش یه war file رو اجرا کنید. اولین کار به روش سنتی اینه که روی لینوکس jdk نصب کنید بعد براش java home ست کنید و کلی داستانای دیگه یا مثلا قراره یه mysql نصب کنید که کار طاقت فرسایی محسوب میشه.اما با داکر شما فقط کافیه که روی سرورتون یک بار داکر رو نصب کنید و دیگه همه این ها رو با دستورات کوتاهی از docker hub بگیرید (pull کنید) و استفاده کنید خب در مرحله بعد سوال اینجاست که image ای که از روی war فایل من ساخته میشه باید کجا آپلود بشه تا توی سرورم بتونم اون رو pull کنم و از روش یه container بسازم و اجراش کنم؟برای اینکار خود gitlab دارای یک docker registery مثل docker hub هست و image شما رو اونجا آپلود میکنه و توسط یک آدرس و user/pass گیت لب با اون ارتباط برقرار میکنید و اون رو pull میکنیدخب برای ساخت image از war file پروژه اول نیاز یه یک DockerFile هستDockerfileFROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JHIPSTER_SLEEP=0 \
    JAVA_OPTS=&quot;&quot;
    
ADD *.war /app.war

EXPOSE 8080
CMD echo &quot;The application will start in ${JHIPSTER_SLEEP}s...&quot; &amp;&amp; \
    sleep ${JHIPSTER_SLEEP} &amp;&amp; \
    java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.war
توی این فایل گفتم که base image من openjdk هست و یه سری متغیر داشتم که توی ENV مشخص کردم که میخواستم توی اجرا این متغیر ها رو بشناسهتوی add گفتم که war file من رو کپی کن توی root ایمیجی که داری میسازی و port 8080 رو هم باز کن برام و در نهایت این war فایل رو با دستور java -jar اجرا کنبعد از اینکه image ما ساخته شد برای اینکه بتونیم اجراش کنیم نیاز به یه فایل docker-compose.yml داریم Mysql.ymlversion: &#039;2&#039;
services:
  mysql:
    image: mysql:5.7.22
    volumes:
      - /Users/hostDirectoryUrl/:/var/lib/mysql/
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=testDB
    ports:
      - 3306:3306
    command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8 --explicit_defaults_for_timestampاینجا گفتیم که base image ما mysql هست و توی volume گفتیم که آدرس var/lib/mysql که دیتا هامون داره اونجا ذخیره میشه رو توی سرورمون به یه آدرسی volume کنه تا هر بار که container ما stop میشه به هر دلیلی ، دیتا های DB رو از دست ندیم و وقتی دوباره container رو start میکنیم ، دیتا ها سر جای خودش باشهتوی environment  رمز عبور دیتابیس رو دادم و گفتم که وقتی یک container میسازی از این دیتابیس ، یک دیتابیس به اسم testDB هم توش بسازتوی قسمت port گفتم که پورت default دیتابیس که 3306 هست رو به پورت 3306 توی سرور من (هاست من) map کن تا از این طریق به دیتابیس ام دسترسی داشته باشمو در نهایت یک سری تنظیمات utf-8 و اینکه نام جداول با نام کوچیک باشه و …docker-compose.ymlversion: &#039;2&#039;
services:
    myApplication:
        image: registry.gitlab.com/testProject/testApp:latest
        environment:
          - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/testDB?useUnicode=yes&amp;characterEncoding=UTF-8&amp;characterSetResults=UTF-8&amp;useSSL=false
          - JHIPSTER_SLEEP=120 # gives time for the database to boot before the application
        ports:
            - 80:8087
    mysql:
      extends:
        file: mysql.yml
        service: mysqlاینجا توی docker-compose اصلی هم گفتم که base image من اون image ای هست که بالاتر ساختیم و توی gitlab-registery آپلودش کردیم.توی environments مهم ترین متغیری که استفاده شده spring_datasource_url هست که درواقع کارش اینه که کانتینر mysql رو که بالا ساختیم رو به کانتینر app ما وصل میکنه و اجازه میده که app ما توی پورت 3306 بتونه به دیتابیس ما دسترسی داشته باشه . در واقع یه راه ارتباطی بین کانتینر دیتابیس و کانتینر اپلیکیشن ایجاد میکنهبرمیگردیم به تنظیمات stage دومbuild-image:
  image: docker:latest
  stage: build-image
  when: manual
  script:
        - cd target
        - docker login registry.gitlab.com -u &quot;yourGitlabUsername&quot; -p &quot;yourPrivateKey&quot;
        - docker build --pull -t registry.gitlab.com/testProject/testApp:latest .
        - docker push registry.gitlab.com/testProject/testApp:latest
  only:
    - master
  artifacts:
    expire_in: 10 mins 0 sec
    paths:
        - target/app.war
        - target/Dockerfile
اینجا گفتیم که توی استیج build-image اول برو به مسیر targetبعد لاگین کن توی gitlab registery  با username و key که gitlab در اختیارتون میزاره برای گرفتن این token روی اکانتتون توی gitlab کلیک کنید و برید توی settings و بعد به قسمت access tokens برید و برای خودتون یه token جدید بسازید در نهایت یه کدی بهتون میده که ازش میتونید اینجا استفاده کنیدلینک راهنما برای ساخت private keyبعد image  رو میسازه و درنهایت push میکنه توی gitlab registery و دوباره دو تا فایل war , Dockerfile رو میفرسته به stage بعدیاستیج سوم (deploy)خب حالا میریم سراغ سرورمون اولین کاری که باید انجام بدیم اینه که باید روش docker نصب کنیم که این کار رو انجام میدیمدر مرحله بعد باید به یک شکلی وصل بشیم به gitlab و اون image ای که برامون ساخته رو بگیریم یا اصطلاحا pull کنیم.خب برای اینکه درگیر مسائل versioning توی image نشیم بهترین کار اینه که توی این مرحله بگیم که اول برو image فعلی که روی سرور ازش یه container ساخته بودیم رو پاک کنیم پس مراحل میشه به شکل زیرلاگین کنم به gitlabکانتینر فعلی روی سرور رو پاک کنمایمیج فعلی روی سرور رو پاک کنمدوباره ایمیج جدید رو دانلود کنمو توسط docker-compose.yml اجراش کنمحالا توی مرحله deploy اجرای دستور docker-compose up -d  باید داخل سرور من اجرا بشه پس باید با یه مکانیزمی به gitlab بفهمونیم که وصل شو به سرور من و این دستور رو اونجا برای من اجرا کنگیت لب یک امکان داره به اسم gitlab runner که درواقع میگه میتونی یه agent هایی برای من توی ماشینت نصب کنی و اون رو به من بشناسونی و بگی از جایی که من هستم (منظور داخل stage هست) به کدوم agent وصل بشم و دستوراتت رو اجرا کنم.پس برمیگردیم دوباره به سرور خودمون و اونجا gitlab runner رو نصب میکنیم که نحوه نصب اش رو اینجا قرار میدمآموزش نصب gitlab runnerبعد از نصب حالا باید وصل بشیم به gitlab runner که نحوه انجام این کار در لینک زیر هست ولی من خلاصه ای از اون رو در پایین توضیح میدم.نحوه ساخت یک runner و وصل شدن به اوندر اونجا میگیم gitlab-runner registerبعد باید token مربوط به runner ای که ساختیم رو بهش بدیم بعد میپرسه از چه نوعی هست که ما چون قراره فقط یه ssh بزنیم به ماشینمون ، پس نوع runner رو shell در نظر میگیریم.چون اینا همه دارن توی ماشین ما اجرا میشه و توی سرور ما هم همون طور که بالاتر گفتیم docker نصب هست ، پس در واقع فقط قراره یه سری shell script برای ما اجرا کنهحالا gitlab-ci باید از یه جایی بفهمه که چجوری بره این stage رو حتما تو ماشین من اجرا کنه ، اینجا جایی که من وقتی داشتم runner تعریف میکردم یه tag بهش دادم (یعنی یک اسم برای runner ام تعریف کردم) تا از طریق اون tag گیت لب این مسئله رو متوجه بشهاین هم کد مربوط به stage  سومdeploy-ssh:
  stage: deploy-ssh
  when: manual
  script:
        - sudo docker login registry.gitlab.com -u &quot;yourGitlabUsername&quot; -p &quot;yourPrivateKey&quot;
        - sudo docker rm -f yourApplicationContainerName || true
        - sudo docker rmi registry.gitlab.com/testProject/testApp || true
        - sudo docker-compose  -f /usr/testProject/docker-compose.yml up -d || true
  only:
    - master
  tags:
    - testTagNameاگر براتون سوال شده که فایل docker-compose.yml از کجا پیداش شد باید بگم که توی فایل pom.xml پروژه ام تعریف کردم که هرچی فایل yml زیر پوشه rousource ام وجود داره رو موقع build کردن به زیر پوشه target کپی کنه .اگر همه چیز به درستی config شده باشه به راحتی عملیات نسخه گذاریتون انجام میشه و دیگه لازم نیست نگران هیچ چیز باشیدامیدوارم این مطلب براتون مفید بوده باشهدر نهایت اگر به دنبال درک بهتر این مسائل هستید میتونید به لینک های زیر مراجعه کنید و همچنین اگر پروژه شما هم جاوایی هست ، برای کمک میتونید به jhipster هم سر بزنیدhttps://docs.gitlab.com/ee/ci/quick_start/https://docs.gitlab.com/ee/ci/yamlhttps://docs.gitlab.com/runner/install/linux-manually.htmlhttps://docs.gitlab.com/runner/register/https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html</description>
                <category>mandi.nariman</category>
                <author>mandi.nariman</author>
                <pubDate>Thu, 17 Jan 2019 16:20:57 +0330</pubDate>
            </item>
                    <item>
                <title>Angular 5 HttpInterceptor : show and hide loader</title>
                <link>https://virgool.io/baharan-co/angular-5-httpinterceptor-show-and-hide-loader-sww9adets54a</link>
                <description>اگر از افرادی باشید که در حال کار کردن روی یک پروژه انگیولاری هستند ، به احتمال زیاد به این مسئله برخوردین که بخواین در زمانی که سرور قرار جواب request های کاربر را بده ، یک loader نمایش بدین تا هم کاربر نتونه روی جای دیگه ای در صفحه کلیک کنه و هم حسی را به کاربر تلقین کنید که کار شما در حال انجام شدنه و تا چند ثانیه دیگه نتیجه مورد نظر خودتون رو میگیرید.مدت ها بود که به این مسئله فکر میکردم و میخواستم یک interceptor روی HTTP انگیولار بنویسم. پروژه ام روی انگیولار ۵ بود اما هنوز وقت نکرده بودم که پروژه ام رو از HTTP به HTTP Client ببرم و این خودش یک مشکل بزرگ بود و نوشتن interceptor روی HTTP تقریبا یک کار سخت و طاقت فرسا بود ، چون خود انگیولار براش این امکان را پیاده سازی نکرده بود و افرادی هم که این کار را کرده بودند با هزار trick این کار را انجام داده بودن و ظاهر جالبی نداشت و از اون طرف لایبراری های آماده ای هم که توی گیت هاب وجود داشت هیچ کدوم جواب گوی نیاز من نبودند. پس تصمیم گرفتم در مرحله اول پروژه را به HTTP Client ببرم چون نوشتن interceptor بر روی آن بسیار کار راحتی بود و خود انگیولار روش درست این کار رو recommend کرده بود .در ابتدا میخواستم خودم یک interceptor بنویسم و درون اون از یک لودر استفاده کنم که به محض اینکه request ها زده میشه اون لودر را نمایش بدم که با یک library خوب به اسم ng-http-loader آشنا شدم که اصلا نیازی به نوشتن interceptor هم نداشت و در واقع با استفاده ازش خودش این کار را براتون انجام میداد.میتونید demo این لایبراری را اینجا مشاهده کنیددر اینجا نحوه استفاده از این library  و مشکلی که خودم روی انگیولار ۵ باهاش داشتم و حل شد را براتون توضیح میدم و لینک github اش را در اینجا قرار میدممرحله اولاگر از انگیولار ۵ استفاده میکنید آخرین ورژن سازگار باهاش ۰.۹.۱ هست پس باید خط زیر را در فایل package.json پروژتون قرار بدین . باز هم تاکید میکنم که این لایبراری تنها در صورتی روی request هاتون کار میکنه که از HTTPClientModule استفاده کرده باشین.&quot;ng-http-loader&quot;:&quot;0.9.1&quot;,و بعدش یک بار npm install یا yarn install را بسته به package manager ای که استفاده میکنید را اجرا کنید تا فایل هاش به پوشه node_modules اضافه بشهمرحله دومداخل app.module تون در قسمت import کافیه که NgHttpLoaderModule را import کنید و در قطعه کد زیر به محلی که این ماژول را  import کردیم دقت کنید(منظورم آدرسش از پوشه node_modules هست).چون دقیقا اینجا نقطه ای بود که خودم مشکل داشتم و با سوالی که توی issue های پروژه زدم متوجه این نکته شدم و دوستان عزیز زحمت کشیدن و فایل readme مخصوص به این ورژن را (که سازگار با انگیولار ۵ بود) برام ارسال کردن که لینکش را اینجا قرار میدمقسمت هایی که باید شما به پروژتون اضافه کنید را با * نشانه گذاری کردمimport { BrowserModule } from &#039;@angular/platform-browser&#039;;
import { NgModule } from &#039;@angular/core&#039;;
[...]
import { AppComponent } from &#039;./app.component&#039;;
import { HttpClientModule } from &#039;@angular/common/http&#039;; &lt;============
import { NgHttpLoaderModule } from &#039;ng-http-loader/ng-http-loader.module&#039;; //******

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule, &lt;============ (Perform http requests with this module)
    NgHttpLoaderModule, //کافیه که این را اضافه کنید****
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }مرحله سومدر این مرحله کافیه که از&lt;spinner&gt; &lt;/spinner&gt; در app.component.html خود استفاده کنید و تمام ، مانند کد زیرimport {Component, OnInit, ViewContainerRef} from &#039;@angular/core&#039;;
import {LayoutService} from &quot;./shared/layout/layout.service&quot;;
import {Spinkit} from &#039;ng-http-loader/spinkits&#039;;

@Component({
    selector: &#039;app-root&#039;,
    template: `&lt;router-outlet&gt;&lt;/router-outlet&gt;
                &lt;spinner 
                    [backgroundColor]=&quot;&#039;#232f3e&#039;&quot;
                    [spinner]=&quot;spinkit.skThreeBounce&quot;
                    [debounceDelay]=&quot;10&quot;&gt;
                &lt;/spinner&gt;`
})
export class AppComponent implements OnInit {
    public title = &#039;app works!&#039;;
    public spinkit = Spinkit;
    
    public constructor(private viewContainerRef: ViewContainerRef,
                       private layoutService: LayoutService,
                       private http: HttpClient,) {
    }

    ngOnInit() {
    }
}
همینطور ثابت Spinkit را از آدرسی که در بالا مشخص شده ، import کنید تا بتونید شکل لودری که مشاهده میکنید را عوض کنید و همچنین یک سری property های دیگه هم داره که متونید آنها را تغییر بدید مثل عوض کردن رنگ و غیره امیدوارم که به کارتون بیاد.</description>
                <category>mandi.nariman</category>
                <author>mandi.nariman</author>
                <pubDate>Thu, 12 Jul 2018 17:21:04 +0430</pubDate>
            </item>
                    <item>
                <title>آشنایی با Docker از نصب تا راه اندازی</title>
                <link>https://virgool.io/baharan-co/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-docker-%D8%A7%D8%B2-%D9%86%D8%B5%D8%A8-%D8%AA%D8%A7-%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-ifn7wh4qiwjf</link>
                <description>آشنایی به زبان ساده  اولین نکته که باید مورد توجه قرار بگیره اینه که داکر هم مثل بقیه تکنولوژی ها تا وقتی که ازش دوریم خیلی سخت به نظر میاد اما وقتی شروع به کار کردن و مطالعه میکنیم ، میبینیم که چقدر ابزار کاربردی و راحتی است که در ادامه سعی دارم تمام سوالاتی که در ابتدا برای خودم مطرح بود رو در اینجا مطرح کنم و بهشون پاسخ بدم و در نهایت هم به عنوان یک مثال کاربردی نحوه بردن جئوسرور روی داکر که برای لود نقشه ها ، در فرمت های مختلف در سیستم جی آی اسی استفاده میشه رو باهم انجام بدیم.مشکلی که docker سعی میکند حل کند چیست ؟مشخصا داکر مشکلات زیادی را حل میکند اما یکی از مهم ترین آن ها improve consistency (بهبود ثبات یا استقرار ) میباشد وقتی گروهی از افراد روی یک پروژه کار میکنند ، میتونه تفاوت هایی در سیستم عامل ها و تنظیمات وجود داشته باشه که باعث بروز یک سری از مشکلات بشه و همچنین ممکنه در بالا آوردن اپلیکیشن روی کامپیوتر خودمون و محیط production (عملیاتی ) هم تناقضاتی وجود داشته باشه .تمامی اینها شما رو از حل کردن مشکلات اصلی که در حقیقت build کردن پروژه تون هست دور میکنه.چگونه docker کمک میکند تا مشکل بالا را حل کنیم؟داکر یه چیزی داره به عنوان container که مانند ماشین های مجازی لینوکس هستند با این تفاوت که اونها خیلی کارآمد تر هستند و منابع کمتری مصرف میکنند و اپلیکیشن شما رو در یک محیط (container) ایزوله و پایدار اجرا میکنه.کانتینر (container) که اپلیکیشن شما رو داخل خودش داره متونه روی ویندوز ، مک او اس و لینوکس اجرا بشه و همین قضیه مشکل دولوپر های مختلف با سیستم های عامل متفاوت را حل میکند.قابلیت docker برای ساحت و نگهداری محیطی استوار باعث portable شدن اپلیکیشن شما میشه.اما این container ها رو باید از کجا پیدا کرد ؟داکر یه جایی داره که شما میتونید خیلی از این container ها رو اونجا پیدا کنید و ازشون استفاده کنید به نام docker hub  که در زیر آدرس اون رو قرار میدم . البته توجه داشته باشید که داکر به آی پی ایران سرویس نمیده و برای نصب کردن و استفاده از docker hub باید از وی پی ان استفاده کنید.https://hub.docker.comتا زمانی که شما container مورد نظر خودتون رو بسازید میتونید از اینجا موارد مشابه ای رو پیدا کنید و سرعت ساخت اپلیکیشنتون رو بالاتر ببرید.نمونه هایی از container هایی که میتونید از داکر هاب  دانلود و استفاده کنید را در زیر نمایش میدهیمNode.js , MySQL , Ubuntoچگونه باید اپلیکیشن خودمون رو به یک container اضافه کنیم ؟زمانی که شما container مورد نظر خودتون رو پیدا کردید قطعا میخواهید اون رو customize کنید و dependency های خودتون رو بهش اضافه کنید . اینجا جاییه که Dockerfile میاد سر کار.داکر فایل (Dockerfile) به طور خلاصه توضیح میده که شما از داکر میخواین چطور برای بار اول container اتون رو بالا بیاره به عنوان مثال یک نمونه از Dockerfile رو در زیر براتون قرار میدم.# Use the official Node.js runtime as a base image
 FROM node:alpine# Set the directory of my web application to /app
 WORKDIR /app# Copy over my project’s directory into the container /app folder
 Add . /app# Install all the dependencies for my web application
 RUN yarn install# Make the port 3000 accessible outside of Docker
 EXPOSE 3000# Execute the command yarn start
 CMD [&quot;yarn&quot;, &quot;start&quot;]
این Dockerfile هر وقت که یک instance ازش ساخته بشه اجرا میشه . هنوز برای ساخت یک container شما نیازمند docker image هستید . هر وقت شما یک Image بسازید متوانید از روی اون به هر تعدادی که دلتون میخواد container  بسازید.در حقیقت شما از داکر هاب ایمیج های داکری آماده را دانلود میکنید که میتوانید به کمک آن ها هر تعداد container ای که لازم دارید را بسازید . همچنین میتوانید تنظیمات شخصی خود را بر روی کانتینری که ساخته اید اعمال کنید و دوباره از آن container یک Image جدید بسازید تا برای ساخت کانتینر هر بار نیازمند انجام تنظیمات قبلی نباشید و container های خودتون رو بر اساس Image جدیدی که ساخته اید ، تولید کنید.آیا من فقط به یک container برای کل اپلیکیشنم نیاز دارم ؟وقتی قابلیت ساخت کانتینر های مختلف وجود داره یک best practice اینه که بخش های مختلف اپلیکیشنمون رو ایزوله کنیم به container های مختلفبرا مثال فرض کنید یه وب اپلیکیشن که به یک دیتابیس و یک وب سرور پایتون نیازمنده به دو تا container نیازمنده . یکیش برای سرور پایتون و یکیشم برای دیتابیس شاید بپرسید چرا ؟ چون اداره اپلیکیشنتون رو ماژولار تر میکنه و اینکه وقتی در آینده اپلیکیشنتون رشد کنه یا گیر های ترافیکی داشته باشه شما میتوانید از چند تا instance از pyton server برای مدیریت ترافیک استفاده کنید.آیا مدیریت کردن چند تا container به صورت همزمان کار سختی نیست ؟دقیقا اینجا جاییه که داکر یه ابزار دیگه رو معرفی میکنه به عنوان docker compose . این ابزار به شما این امکان رو میده که میتونید کانفیگ container هایی که به هم مرتبط هستند رو در یک فایل yml مشخص کنید . یه فایل Docker-compose.yml به شکل زیر استversion: &#039;2&#039;
services:
  server:
    build: .
    ports:
     - &quot;3000:3000&quot;
    volumes:
     - .:/app
  database:
    image: &quot;mariadb:10.3&quot;
    environment:
     - MYSQL_ROOT_PASSWORD=MyPassword
     - MYSQL_DATABASE=MyDatabase
    ports:
     - &quot;3306:3306&quot;همین طور که در بالا مشاهده میکنید ما دو تا سرویس (container) داریم یکی به اسم server و یکی به اسم database که در اون متغیر ها و پورت ها و volume ها رو تعریف کردیم . وقتی فایل Docker-compose آماده میشه ، مدیریت گروهی از container ها که مربوط به یک اپلیکیشن هستند خیلی ساده میشه.ابزار هایی که بهتر است بشناسیدابزار Kitematic : به شما این امکان رو میده تا کانتینر های خودتون رو در یک محیط ویژوالی مدیریت کنید . شاید برای اولش که یک مقدار با محیط CLI آشنا نشدید گزینه خوبی باشهابزار Docker Swarm : وقتی اپلیکیشن شما بزرگ میشه شما ممکنه بخواین که چند تا container داشته باشین تا traffic شما رو هندل کنند. این ابزار باعث میشه مدیریت گروهی از container ها (clusters) در یک زمان ، کار ساده تری بشه  ساختار Docker داکر ساختاری server base داره و به زبان ساده این طور عمل میکنه که client دستورش رو به docker client میده و اون هم از طریق Docker Deamon(Dockerd) اجراش میکنه داکر شامل سه کامپوننت هست 1. Image2. Container3. RegisteriesDocker Imageبسته نرم افزاری هست که docker رو اجرا میکنه (اصولا container) ، image شامل تمامی فایل ها و library هایی است که برای اجرام نرم افزار به اون نیاز داریم و هر کسی میتونه image شخصی خودش رو از طریق Docker Client CLI بسازه . Docker Containerدر حقیقت یک instance از image هستند و نکته اینجاست که آنها نسبت یه host system کاملا ایزوله و مستقل از منابع نرم افزاری هستند.Docker Registeriesیک پلتفرمی هست که میزبان image های کاربران میباشد. هر کسی میتوه image های مورد نظرش رو push یا download کنه و حتی میتونید برای خودتون یا سازمانتون یک private registery تولید کنید.Docker Deamonاز هسته لینوکس استفاده میکنه و شاید به شما این باور رو بده که نمیشه روی OS های دیگه اجراش کرد اما به همین خاطر تیم docker ابزاری آماده کرده به عنوان Boot2Docker که شامل package های یک linux سبک هست که تمامی نیازمندی های Dockerd رو داره و به نحوی linuxVM داره در بالاترین سطح OS شما اجرا میشه تا Docker کارش رو انجام بده  نصب Docker CE (Community Edition)  در این بخش ما طریقه نصب داکر بر روی سیستم عامل ubunto را آموزش میدهیم  توجه داشته باشید که با توجه به لینک نصب میتوانید نحوه نصب بر روی تمامی سیستم عامل ها را مشاهده کنید.در اینجا ما نحوه نصب Docker CE از طریق repository را توضیح میدهیمنصب Repository1. در ابتدا پکیج apt رو آپدیت کنید$ sudo apt-get update2. نصب پکیج هایی که به شما اجازه میده از طریق HTTPS به repository  دسترسی داشته باشد و ازش استفاده کنید$ sudo apt-get install \    apt-transport-https \    ca-certificates \    curl \    software-properties-common3. اضافه کردن GPG Key رسمی داکر$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –4.     از دستور زیر برای استفاده از stable repositories استفاده کنید$ sudo add-apt-repository \   &quot;deb [arch=amd64] https://download.docker.com/linux/ubuntu \   $(lsb_release -cs) \   stable&quot;نصب Docker CE1. دوباره پکیج apt  را آپدیت کنید$ sudo apt-get update2. آخرین نسخه Docker CE را نصب کنید$ sudo apt-get install docker-ceدستور بالا خودش آخرین ورژن رو میگیره ولی اگر بخواهیم ورژن خاصی رو نصب کنیم هم میتونیم از روش زیر استفاده کنیم$ apt-cache madison docker-ce        Result : docker-ce | 18.03.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packagesبا دستور بالا میتونیم ورژن های موجود docker رو ببینیم و با دستور زیر آن را نصب کنیمsudo apt-get install docker-ce=&lt;VERSION&gt;برای اینکه متوجه بشیم که Docker CE درست نصب شده ایمیج زیر را اجرا میکنیم$ sudo docker run hello-worldاین دستور در ducker hub به دنبال ایمیج hello-world  میگرده و در صورتی که در آنجا وجود داشته باشه آخرین ورژن اش رو دانلود میکنهنصب Geoserver  به کمک dockerنیاز به اجرای جئوسرور در محیط لینوکس و سختی نصب پلاگین هایی مانند gdal که برای لود عکس هایی با فرمت ecw استفاده میشود باعث شد تا برای اجرای جئوسرور ، از Docker کمک بگیرم در ادامه سعی میکنیم کلیه دستورات docker و linux و همچنین توضیحات تکمیلی را در قالب نصب و ساخت ایمیج جئوسرور دلخواهمان ، توضیح و بررسی کنمهدف از ساخت docker image برای جئوسرور چیست؟قطعا همان طور که در ابتدای این مقاله گفته شد ، سادگی و قابل حمل بودن و سرعت deploy توسط docker باعث شد برای سهولت کار جئوسرور را تبدیل به یک docker image  کنییم . برای مثال ما میخواستیم جئوسرورمان دارای دو پلاگین oracle و GDAL باشد که به صورت پیش فرض بر روی جئوسرور نصب نیستند و نصب آن ها بر روی سیستم عامل های مختلف دارای پیچیدگی های مختلفی هست اما با انجام کلیه این تنظیمات و ساخت یک docker image ، دیگه نیازی نیست که هر بار تنظیمات را انجام دهیم و با ساخت هر container از ایمیج جئوسرور تنظیمات ما به صورت پیشفرض در جئوسرور اعمال میشوند.در صورت تغییر در تنظیمات ، اضافه کردن لایه ها ، استایل ها ، تنظیمات cache نقشه و ... آیا هربار که container ما پاک شود و دوباره راه اندازی شود ، اطلاعات از بین میرود ؟جواب منفی است ، در docker امکان volume کردن یا به زبان ساده تر امکان شنود کردن اتفاقاتی که در container در حال رخ دادن است وجود دارد و ما میتوانیم با استفاده از این قابلیت اتفاقات مورد نظرمون را شنود کنیم و در host خودمون نگه داریم . به عنوان مثال در ایمیج جئوسرور ، ما کلیه محتویات پوشه data_dir را که شامل کلیه تنظیمات و تغییرات جئوسرور هست را از طریق volume (( که در ادامه توضیح خواهیم داد)) در هاست خود ذخیره میکنیم تا هربار که یک instance جدید ساخته میشود آخرین تغییرات در جئوسرور وجود داشته باشد و نیازی به دوباره کاری برای بارگزاری اطلاعات جئوسرور نباشد. مرحله اول اولین مسئله ای که باید به آن دقت کرد این است که قبل از تلاش برای ساختن یک ایمیج از صفر تا صد بهتر است که سری به dockerhub بزنیم. چون در بیشتر مواقع مواردی مشابه به تنظیماتی که در نظر شما وجود دارد را میتوان از آنجا پیدا کرد با همین رویکرد ما توانستیم با جستجوی geoserver در ایمیج ها و بررسی امکانات آنها یکی را انتخاب کنیم تا به عنوان اولین قدم روی آن کار کنیم تا در نهایت base image خود را آماده کنیمwinsent/geoserverایمیج انتخابی ما که آدرسش در اسم ایمیج لینک شده است ، ایمیج winsent بود چون به صورت پیشفرض دارای پلاگین GDAL بود که البته برای این کار باید چند مرحله انجام میدادیمبا بررسی repository ایمیج و دانلود source آن متوجه شدیم برای اینکه بخواهیم ایمیجی با پلاگین از قبل آماده شده GDAL داشته باشیم باید از روی Dockerfile موجود در پوشه ورژن 2.12  و پوشه libecw یک ایمیج تهیه کنیم.در ابتدا برای اینکه اگر کاربر ادمین نباشید و نخواهید هر بار دستور sudo را قبل از دستورات docker بیاورید میتوانید از کد زیر در terminal  استفاده کنید. بعد از enter کردن رمز عبور یوزر خود را تایپ کنید و enter کنید حالا شما به عنوان یوزر ادمین شناخته شده اید$ sudo –iنحوه ساخت یک Docker Image از روی Dockerfile$ docker build –t imageName .توجه : در انتها بعد از اسم ایمیج باید یک space زده و ].[ را بگذارید تا دستور عمل کند. البته در دستور بالا چون دقیقا اسم فایل Dockefile بوده ما اسم فایل را نیاوردیم ولی اگر اسم Dockerfile  امون فرق میکنه دستور به شکل زیر میشه$ docker build -f dockerfileName -t imageName .بعد از ساخته شدن image یکسری دستورات لازمه را مرور میکنیم نحوه pull کردن یک image از docker hub$ docker pull image_nameدیدن لیستی از همه Image های داکری که روی هاست قرار دارد$ docker imagesحذف docker imageوقتی دستور docker images رو اجرا میکنیم کل اطلاعات ایمیج شامل Id ، نام و ... رو به ما نشون میده$ docker rmi &lt;imageId&gt;ساخت یک container از روی imageبرای این منظور از دستور زیر استفاده میکنیم $ docker run –d –p 8087:8080 –v path/to/host:/opt/geoserver/data_dir &lt;imageName&gt;-d یعنی container رو در background اجرا کنه -p 8087:8080 یعنی پورت 8080 در container رو به پورت 8087 در هاست خودتون مپ میکنه . یعنی برای دسترسی بهش کافیه توی هاست خودتون از آدرس زیر استفاده کنید127.0.0.1:8087/geoserver-v وظیفه volume کردن را بر عهده دارد یعنی محتویات داخل پوشه /opt/geoserver/data_dir که در container قرار دارد را میریزه داخل مسیر سمت چپی که در هاست شماست.نمایش لیست تمامی container های فعال$ docker psنمایش لیست تمامی container های فعال و غیر فعال$ docker ps –aحذف container$ docker rm &lt;containerName/Id&gt;Stop و start کردن container ها $ docker stop/start &lt;container Name/Id&gt;Stop کردن همه container ها به صورت دسته جمعی و حذف آنهاروش اول$ dcoker stop $(docker ps –a –q )$ docker rm $(docker ps –a –q)$ docker ps –a –q این دستور id (-q) همه کانتینر ها (-a) را بر میگردونهروش دوم $ docker rm –f $(docker ps –a –q)-f به معنی force یا اجبار میباشد ، پس بدون نیاز به stop کردن خودش اول stop  میکنه همه container  ها را و بعد پاکشون میکنهدستور رفتن به داخل container$ docker exec –it &lt;containerName/Id&gt; /bin/bashخروج از یک container بدون stop شدنCtrl + dحالا که container ما ساخته شده میخواهیم پلاگین های oracle را هم بهش اضافه کنیم . برای این منظور باید jar فایل های oracle و ojdbc را در مسیر زیر داخل container کپی کنیم$ docker cp ojdbc.jar myContainer:/opt/geoserver/webapps/geoserver/WEB-INF/lib/حالا که این کار را انجام دادیم پلاگین های ما اضافه میشوند و در حقیقت base image ما ساخته شده است به همین منظور از container موجود یکImage میسازیم تا همیشه از آن استفاده کنیمساخت Docker Image از روی Container$ docker commit &lt;container_id&gt; &lt;container_name&gt;:&lt;tag_version&gt;مثال :$ docker commit 2fg4805485ad sample/geoserver:1.0.0اگر :tag_version رو نگذاریم خودش latest در نظر میگیره اعداد 2fg4805485ad به معنی id کانتینر مورد نظر استبرای نگهداری Image خودمون یک tar فایل ازش میسازیم  تا هرجایی که میخواهیم ازش استفاده کنیم اون رو لود کنیمساخت tar فایل از imge$ docker save &lt;image_name&gt; yourImageName.tarمثال:$ docker save sample/geoserver:1.1.0 sample-geoserver.tarلود کردن tarFileحالا برای لود کردن این Image باید از دستور زیر استفاده کرد$ docker load tarFileAddressتوجه : در volume ای که در هاست خود داریم باید پوشه ای به نام data بسازیم و فایل های ecw را درون آن پوشه بارگذاری کنیم . این باگ پلاگین GDAL میباشد که حتما باید دیتا های رستری آن داخل پوشه data در مسیر geoserver_data_dir باشداستفاده از docker composeبرای راحتی کار میتوانیم برای ساخت container از فایل dockerCompose.yml استفاده کنیمبه عنوان مثال فایل dockerCompse جئوسرورversion: &#039;2&#039;
services:
  app:
    image: &quot;sample/geoserver:1.0.0&quot;
    ports:
     - &quot;8080:8080&quot;    volumes:-   /home/nariman/Desktop/…/geoserverData:/opt/geoserver/data_dirالبته برای استفاده از docker compose باید آن را به صورت جداگانه نصب کنید که این لینک توضیح داده شده و نیازمند چند دستور استsudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-composeبرای اجرا کردن از طریق docker compose کافیه به مسیری که فایل در اون قرا داره برید و دستور زیر را اجرا کنید$ docker-compose –f dockerComposefile.yml up -d </description>
                <category>mandi.nariman</category>
                <author>mandi.nariman</author>
                <pubDate>Thu, 14 Jun 2018 16:41:47 +0430</pubDate>
            </item>
            </channel>
</rss>