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

Vue + Docker
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 مرورگرتون ببینید.

تمام :)

در ضمن، اگه سوالی داشته باشید، خوشحال میشم تا جایی که بلد باشم کمکتون کنم.

موفق باشید.