چجوری پروژه‌‌های Vue رو Dockerize کنیم‌؟

Vue + Dockerممکنه که به این فکر افتاده باشید که چجوری میشه یه پروژه Vue js رو داکرایز کرد.با من پیش بیایید تا این کار رو انجام بدیم:با ساختن یک فایل به اسم Dockerfile (بدون هیچ پسوندی) در مسیر ریشه‌ی پروژه شروع میکنیم. ( توجه کنید که اگه بخواهید میتونید اسم و محل فایل رو عوض کنید اما بزارید فعلا خیلی پیچیدش نکنیم :) )این دستورات رو توی این فایل می‌نویسیم:FROM node:lts-alpine # install simple http server for serving static content RUN npm install -g http-server # make the 'app' folder the current working directory WORKDIR /app # copy both 'package.json' and 'package-lock.json' (if available) COPY package*.json ./ # install project dependencies RUN npm install # copy project files and folders to the current working directory (i.e. 'app' folder) COPY . . # build app for production with minification RUN npm run build EXPOSE 8080 CMD [ &quothttp-server&quot, &quotdist&quot ]خب، یه نگاهی بندازیم به این داکرفایل با دستور FROM، نوع و ورژن image پایه‌ی این Dockerfile را مشخص می‌کنیم. سپس پکیجی که برای اجرای فایل‌های پروژه به آن نیاز داریم رو به صورت گلوبال نصب کردیم (پکیج http-server) این پکیج نقش سرور را برایمان بازی می‌کند. سپس یک دایرکتوری به اسم app ساختیم و اونرو محل اجرای دستورات بعدی تعیین کردیم.فایل ‌های package.json و package.lock.json رو توی پوشه app کپی کردیم بعد npm install و نصب پکیج‌های پروژه‌ی خودمونبا دستور COPY تمام فایل‌های پروژه مون رو توی پوشه‌ی app کپی کردیماز پروژه build گرفتیم و در نهایت پوشه dist رو با http-server اجرا کردیم.قبل از اجرای این داکر فایل، یک فایل به اسم dockerignore. رو توی مسیر ریشه از پروژه می‌سازیم و دستورات زیر رو داخلش قرار میدیم: **/node_modules **/distاین فایل مشابه با فایل gitignore. عمل میکنه و باعث میشه که محتویات این فایل از چشم دستورات داکرفایل نادیده گرفته بشن،‌ مثلا با اجرای دستور COPY از فایل‌های پروژه، این دستور دایرکتوری‌ها و فایل‌های داخل dockerignore. رو نادیده میگیره.حالا یک image از این داکرفایل می سازیم:docker build -t vuejs/dockerize .توی دستور بالا،‌ با آپشن t- مشخص کردیم که اسم image ی که قرار هست ساخته بشه vuejs/dockerize باشه و علامت نقطه مشخص میکنه که این image باید از روی همین داکرفایلی که در محل اجرای این دستور هست ساخته شود.در نهایت یک کانتینر از روی این Image اجرا میکنیم:docker run -d -p 8080:8080 --rm --name dockerize-vuejs-app vuejs/dockerizeبا دستور بالا یک کانتینر می‌سازیم که پورت ۸۰۸۰ از هاست شما را به پورت ۸۰۸۰ از کانتینر متصل میکنداگر این کانتینر از قبل موجود باشد، آپشن rm-- به صورت اتوماتیک آنرا حذف می‌کند.با آپشن name-- اسم کانتینر رو مشخص کردیم و در انتها هم گفتیم که این کانتینر از روی image به اسم vuejs/dockerize ساخته بشه.آپشن -d باعث میشه که این کانتینر در بک گراند اجرا بشه (detached mode)اگر که تمام مراحل بالا بدون مشکل انجام داده باشید، شما می‌تونید این پروژه vue رو از طریق مرورگرتون با رفتن به آدرس localhost:8080 اجرا کنید.خب...طبق چیزی که توی داکیومنت vue گفته شده، درسته که شما تونستید به این شکل پروژه‌ی vue رو داکرایز کنید اما این شیوه برای حالت production خیلی امن و مطمئن نیست و بهتر هست که از یک وب سرور مثل apache و یا nginx استفاده کنید.It is powerful enough for production usage, but it’s simple and hackable enough to be used for testing, local development, and learning.https://v2.vuejs.org/v2/cookbook/dockerize-vuejs-app.htmlواسه‌ی این که پروژه رو با nginx اجرا کنیم باید یک تغییراتی توی داکرفایلمون بدیم:# build stage FROM node:lts-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install --production COPY . . RUN npm run build # production stage FROM nginx:stable-alpine as production-stage COPY --from=build-stage /app/dist /usr/share/nginx/html EXPOSE 80 CMD [&quotnginx&quot, &quot-g&quot, &quotdaemon off;&quot]به این شکل از داکرفایل ها که چند دستور FROM دارند، multi stage گفته می‌شه.برای اطلاعات بیشتر می‌تونید این لینک رو ببینید.خب ببینیم توی این داکر فایل چی داریم:توی stage اول که اونو build-stage نام گذاری کردیم تقریبا همه چیز مشابه به با داکرفایل قبلی است با این تفاوت که دیگه http-server رو نصب نکردیم و ازش استفاده ای هم نکردیم.و اما در stage دوم از nginx استفاده کردیم و اسم این stage رو production-stage گذاشتیم.محتویات پوشه‌ی /app/dist از build-stage رو به داخل دایرکتوری /user/share/nginx/html از production-stage ریختیمپورت ۸۰ کانتینر رو expose کردیمو در پایان هم با استفاده از nginx سرور رو راه‌اندازی کردیم.حالا اگر از روی این داکر فایل یک image بسازید و بعد یک کانتینر از روش اجرا کنید، باز خروجی مشابهی در آدرس localhost:8080 خواهید گرفت.توجه کنید که این بار توی ساخت Container پورت ۸۰۸۰ از هاست رو به پورت ۸۰ کانتینر متصل می‌کنیم.docker run -d -p 8080:80 --rm --name dockerize-vuejs-app vuejs/dockerizeتوجه:‌ حالت خاص‌ِ History Mode در Vue Routerاگه که توی Router پروژه‌تون mode رو به history تغییر داده‌اید ممکنه که زمانی که پروژه رو اجرا می‌کنید، اگه یک آدرسی از پروژه‌‌تون رو به جز آدرس ریشه، توی مرورگر بزنید با خطای ۴۰۴ رو به رو شید.برای حل این مشکل کافیه که یک تغییر توی تنظیمات nginx بدیم:برای این کار، فایل nginx.conf رو توی مسیر ریشه پروژه ایجاد کنید و تنظیمات زیر رو داخلش قرار بدید:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] &quot$request&quot ' '$status $body_bytes_sent &quot$http_referer&quot ' '&quot$http_user_agent&quot &quot$http_x_forwarded_for&quot'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root /app; index index.html; try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }سپس نیاز داریم که مجدد داکرفایلمون رو تغییراتی بدیم و این فایل nginx.conf رو به عنوان تنظیمات جدید Nginx قرار بدیم:FROM node:latest as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY ./ . RUN npm run build FROM nginx as production-stage RUN mkdir /app COPY --from=build-stage /app/dist /app COPY nginx.conf /etc/nginx/nginx.confحالا کافیه که باز روال ایجاد image و container رو یک بار دیگه انجام بدیم و یک کانتینر جدید اجرا کنیم.اگه مراحل رو با موفقیت پشت سر گذاشته باشید،‌می‌تونید خروجی رو توی آدرس localhost:8080 مرورگرتون ببینید.تمام :) در ضمن، اگه سوالی داشته باشید، خوشحال میشم تا جایی که بلد باشم کمکتون کنم.موفق باشید.