8. النشر باستخدام الحاويات¶
توجد طرق عديدة لاستخدام التطبيقات المعبأة في حاويات، من أبسطها (صور Docker البسيطة) إلى أكثرها تطورًا (Kubernetes وغيرها).
ملاحظة
يتطلب هذا النوع من النشر أن يكون تطبيق Docker مثبتًا وقيد التشغيل. راجع هذا الدرس التعليمي.
تلميح
يشغّل Docker تطبيقات معبأة مسبقًا (تُسمى الصور Images)، ويمكن الحصول عليها إما مصادرَ (ملف Dockerfile والموارد) لبنائها، أو جاهزة البناء من السجلات (Registries) الخاصة أو العامة.
ملاحظة
تتطلب تنزيلات حزم QGIS لـ Debian-Ubuntu مفتاح مصادقة gpg صالحًا. يرجى الرجوع إلى صفحات التثبيت لتحديث ملف Dockerfile التالي.
8.1. صور Docker بسيطة¶
بما أن صورة Docker غير موجودة في سجل عام، فستحتاج إلى بنائها. للقيام بذلك أنشئ مجلدًا باسم qgis-server، وداخل هذا المجلد:
أنشئ ملفًا باسم
Dockerfileبهذا المحتوى:
FROM debian:bookworm-slim
ENV LANG=en_EN.UTF-8
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests --allow-unauthenticated -y \
gnupg \
ca-certificates \
wget \
locales \
&& localedef -i en_US -f UTF-8 en_US.UTF-8 \
# Add the current key for package downloading
# Please refer to QGIS install documentation (https://www.qgis.org/fr/site/forusers/alldownloads.html#debian-ubuntu)
&& mkdir -m755 -p /etc/apt/keyrings \
&& wget -O /etc/apt/keyrings/qgis-archive-keyring.gpg https://qgis.org/downloads/qgis-archive-keyring.gpg \
# Add repository for latest version of qgis-server
# Please refer to QGIS repositories documentation if you want other version (https://qgis.org/resources/installation-guide/#repositories)
&& echo "deb [signed-by=/etc/apt/keyrings/qgis-archive-keyring.gpg] https://qgis.org/debian bookworm main" | tee /etc/apt/sources.list.d/qgis.list \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests --allow-unauthenticated -y \
qgis-server \
spawn-fcgi \
xauth \
xvfb \
&& apt-get remove --purge -y \
gnupg \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN useradd -m qgis
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENV QGIS_PREFIX_PATH /usr
ENV QGIS_SERVER_LOG_STDERR 1
ENV QGIS_SERVER_LOG_LEVEL 2
COPY cmd.sh /home/qgis/cmd.sh
RUN chmod -R 777 /home/qgis/cmd.sh
RUN chown qgis:qgis /home/qgis/cmd.sh
USER qgis
WORKDIR /home/qgis
ENTRYPOINT ["/tini", "--"]
CMD ["/home/qgis/cmd.sh"]
أنشئ ملفًا باسم
cmd.shبهذا المحتوى:
#!/bin/bash
[[ $DEBUG == "1" ]] && env
exec /usr/bin/xvfb-run --auto-servernum --server-num=1 /usr/bin/spawn-fcgi -p 5555 -n -d /home/qgis -- /usr/lib/cgi-bin/qgis_mapserv.fcgi
ابنِ الصورة باستخدام:
docker build -f Dockerfile -t qgis-server ./
8.1.1. التشغيل الأول¶
لتشغيل الخادم ستحتاج إلى ملف مشروع QGIS. يمكنك استخدام أحد مشاريعك أو اختيار هذا المثال.
للقيام بذلك، أنشئ مجلدًا باسم data داخل المجلد qgis-server وانسخ ملفك إليه. ولتتوافق مع الشروح التالية، أعد تسميته إلى osm.qgs.
ملاحظة
قد تحتاج إلى إضافة عناوين URL المُعلَنة ضمن تبويب QGIS Server في إذا كانت استجابة GetCapabilites معطوبة. فمثلًا إذا كان خادمك مكشوفًا على المنفذ 8080، فاكتب عنوان URL المُعلَن التالي http://localhost:8080/qgis-server/. تتوفر معلومات إضافية في القسم ضبط مشروعك والأقسام التي تليه.
يمكنك الآن تشغيل الخادم باستخدام:
docker network create qgis
docker run -d --rm --name qgis-server --net=qgis --hostname=qgis-server \
-v $(pwd)/data:/data:ro -p 5555:5555 \
-e "QGIS_PROJECT_FILE=/data/osm.qgs" \
qgis-server
الخيارات المستخدمة:
-d: التشغيل في الخلفية
--rm: إزالة الحاوية عند إيقافها
--name: اسم الحاوية المراد إنشاؤها
--net: الشبكة الفرعية (المنشأة مسبقًا)
--hostname: اسم المضيف للحاوية، للإشارة إليها لاحقًا
-v: مجلد البيانات المحلي المراد ربطه (Mount) داخل الحاوية
-p: ربط منفذ المضيف بمنفذ الحاوية
-e: متغير البيئة المراد استخدامه في الحاوية
للتحقق، اكتب docker ps | grep qgis-server ويُفترض أن ترى سطرًا يحتوي على qgis-server:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4de8192da76e qgis-server "/tini -- /home/qgis…" 3 seconds ago Up 2 seconds 0.0.0.0:5555->5555/tcp qgis-server
8.1.2. مثال قابل للاستخدام¶
بما أن الخادم لا يقبل إلا اتصالات fastcgi، فأنت بحاجة إلى خادم HTTP يتعامل مع هذا البروتوكول. لذلك علينا إنشاء ملف إعدادات Nginx بسيط وتشغيل صورة Nginx.
أنشئ ملفًا باسم nginx.conf في المجلد الحالي بهذا المحتوى:
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /qgis-server {
proxy_buffers 16 16k;
proxy_buffer_size 16k;
gzip off;
include fastcgi_params;
fastcgi_pass qgis-server:5555;
}
}
ثم اكتب هذا الأمر:
docker run -d --rm --name nginx --net=qgis --hostname=nginx \
-v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro -p 8080:80 \
nginx:1.13
للتحقق من توفر الإمكانات (Capabilities)، اكتب في المتصفح http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities
8.1.3. التنظيف¶
لتنظيف الصور قيد التشغيل، اكتب:
docker stop qgis-server nginx
8.2. مكدسات Docker¶
الطريقة السابقة قابلة للأتمتة بالسكربتات، لكنها ليست سهلة التحزيم ولا قياسية ولا سهلة الإدارة.
للعمل مع مجموعة من صور Docker يمكنك استخدام مكدس Docker (Stack) يديره منسّق (Orchestrator). في المكدس تعمل الصور ضمن الشبكة الخاصة نفسها، ويمكنك تشغيل المكدس بأكمله أو إيقافه أو نشره على عُقد عاملة أخرى. توجد منسّقات عديدة، مثل Swarm و Kubernetes و Mesos.
سنعرض فيما يلي إعدادات بسيطة لأغراض الاختبار، وهي غير مناسبة لبيئات الإنتاج.
8.2.1. Swarm و docker-compose¶
أصبح لدى Docker الآن منسّقه الخاص: Swarm (المتوافق مع ملفات docker-compose). عليك تفعيله (نسخة Mac ستعمل أيضًا مع Linux).
وصف المكدس¶
الآن بعد أن أصبح Swarm يعمل، أنشئ ملف الخدمة qgis-stack.yaml (انظر النشر على Swarm):
version: '3.7'
services:
qgis-server:
# Should use version with utf-8 locale support:
image: qgis-server:latest
volumes:
- REPLACE_WITH_FULL_PATH/data:/data:ro
environment:
- LANG=en_EN.UTF-8
- QGIS_PROJECT_FILE=/data/osm.qgs
- QGIS_SERVER_LOG_LEVEL=0 # INFO (log all requests)
- DEBUG=1 # display env before spawning QGIS Server
nginx:
image: nginx:1.13
ports:
- 8080:80
volumes:
- REPLACE_WITH_FULL_PATH/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- qgis-server
لنشر المكدس (أو تحديثه)، اكتب:
docker stack deploy -c qgis-stack.yaml qgis-stack
تحقق من حالة نشر المكدس حتى تحصل على 1/1 في العمود replicas:
docker stack services qgis-stack
شيء من قبيل:
ID NAME MODE REPLICAS IMAGE PORTS
gmx7ewlvwsqt qgis_nginx replicated 1/1 nginx:1.13 *:8080->80/tcp
l0v2e7cl43u3 qgis_qgis-server replicated 1/1 qgis-server:latest
للتحقق من إمكانات WMS، اكتب في متصفح الويب http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities
التنظيف¶
للتنظيف، اكتب:
docker stack rm qgis-stack
8.2.2. Kubernetes¶
التركيب¶
إذا كان لديك تثبيت لـ Docker Desktop، فإن استخدام Kubernetes (المعروف اختصارًا بـ k8s) سهل جدًا: فعّل k8s.
وإن لم يكن كذلك، فاتبع درس minikube التعليمي أو microk8s لـ Ubuntu.
بما أن تثبيت Kubernetes قد يكون معقدًا جدًا، فسنركز فقط على الجوانب المستخدمة في هذا العرض التوضيحي. لمعلومات إضافية أو أعمق، راجع الوثائق الرسمية.
microk8s¶
يحتاج microk8s إلى خطوات إضافية: عليك تفعيل السجل (Registry) ووسم صورة qgis-server لكي يعثر Kubernetes على الصور المنشأة.
أولًا، فعّل السجل:
microk8s enable dashboard dns registry
ثم ضع وسمًا على الصورة وادفعها إلى السجل الذي أنشأته للتو:
docker tag qgis-server 127.0.0.1:32000/qgis-server && docker push 127.0.0.1:32000/qgis-server
أخيرًا، أضف الملف /etc/docker/daemon.json أو أكمله ليتضمن سجلك 127.0.0.1:32000 في الحقل insecure-registries:
{
"insecure-registries": ["127.0.0.1:32000"]
}
إنشاء ملفات البيان (Manifests)¶
يصف Kubernetes الكائنات المراد نشرها في ملفات بيان بصيغة yaml. وتوجد أنواع كثيرة منها، لكننا سنستخدم فقط عمليات النشر (Deployments) (التي تدير الـ Pods، أي صور Docker) والخدمات (Services) لكشف عمليات النشر لأغراض داخلية أو خارجية.
ملفات بيان النشر¶
أنشئ ملفًا باسم deployments.yaml بهذا المحتوى:
apiVersion: apps/v1
kind: Deployment
metadata:
name: qgis-server
namespace: default
spec:
replicas: 1
selector:
matchLabels:
myLabel: qgis-server
template:
metadata:
labels:
myLabel: qgis-server
spec:
containers:
- name: qgis-server
image: localhost:32000/qgis-server:latest
imagePullPolicy: Always
env:
- name: LANG
value: en_EN.UTF-8
- name: QGIS_PROJECT_FILE
value: /data/osm.qgs
- name: QGIS_SERVER_LOG_LEVEL
value: "0"
- name: DEBUG
value: "1"
ports:
- containerPort: 5555
volumeMounts:
- name: qgis-data
mountPath: /data/
volumes:
- name: qgis-data
hostPath:
path: REPLACE_WITH_FULL_PATH/data
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: qgis-nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
myLabel: qgis-nginx
template:
metadata:
labels:
myLabel: qgis-nginx
spec:
containers:
- name: qgis-nginx
image: nginx:1.13
ports:
- containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d/
volumes:
- name: nginx-conf
configMap:
name: nginx-configuration
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
data:
nginx.conf: |
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /qgis-server {
proxy_buffers 16 16k;
proxy_buffer_size 16k;
gzip off;
include fastcgi_params;
fastcgi_pass qgis-server:5555;
}
}
ملفات بيان الخدمات¶
أنشئ ملفًا باسم services.yaml بهذا المحتوى:
apiVersion: v1
kind: Service
metadata:
name: qgis-server
namespace: default
spec:
type: ClusterIP
selector:
myLabel: qgis-server
ports:
- port: 5555
targetPort: 5555
---
apiVersion: v1
kind: Service
metadata:
name: qgis-nginx
namespace: default
spec:
type: NodePort
selector:
myLabel: qgis-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
نشر ملفات البيان¶
لنشر الصور والخدمات في Kubernetes، يمكنك استخدام لوحة التحكم (انقر على + في الأعلى يمينًا) أو سطر الأوامر.
ملاحظة
عند استخدام سطر الأوامر مع microk8s، عليك أن تسبق كل أمر بالكلمة microk8s.
لنشر ملفات البيان أو تحديثها:
kubectl apply -f ./
للتحقق مما هو منشور حاليًا:
kubectl get pods,services,deployment
يُفترض أن تحصل على شيء من قبيل:
NAME READY STATUS RESTARTS AGE
pod/qgis-nginx-54845ff6f6-8skp9 1/1 Running 0 27m
pod/qgis-server-75df8ddd89-c7t7s 1/1 Running 0 27m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/Kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 5h51m
service/qgis-exec-server ClusterIP 10.152.183.218 <none> 5555/TCP 35m
service/qgis-nginx NodePort 10.152.183.234 <none> 80:30080/TCP 27m
service/qgis-server ClusterIP 10.152.183.132 <none> 5555/TCP 27m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/qgis-nginx 1/1 1 1 27m
deployment.apps/qgis-server 1/1 1 1 27m
لقراءة سجلات nginx/qgis، اكتب:
kubectl logs -f POD_NAME
للتحقق من إمكانات WMS، اكتب في متصفح الويب http://localhost:30080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities
التنظيف¶
للتنظيف، اكتب:
kubectl delete service/qgis-server service/qgis-nginx deployment/qgis-nginx deployment/qgis-server configmap/nginx-configuration
8.3. النشر السحابي¶
إن إدارة عنقود خوادم خاص بك للتعامل مع نشر التطبيقات المعبأة في حاويات مهمة معقدة، إذ عليك التعامل مع قضايا متعددة مثل العتاد وعرض النطاق الترددي والأمان على مستويات مختلفة.
يمكن أن تكون حلول النشر السحابي بديلًا جيدًا عندما لا ترغب في التركيز على إدارة البنية التحتية.
قد يستخدم النشر السحابي آليات مملوكة لمزوّد الخدمة، لكنها متوافقة أيضًا مع المراحل الموضحة سابقًا (صور Docker و إدارة المكدسات).
8.3.1. حالة استخدام AWS¶
مع Amazon AWS، ومن خلال وظائف ECS (Elastic Container Service)، يمكنك استخدام أغلفة متوافقة مع docker-compose أو Kubernetes لإدارة مكدسك. وسيتعين عليك إنشاء سجل صور لتكون صورك المخصصة قابلة للوصول.
لاستخدام وظائف مشابهة لـ docker-compose، عليك تثبيت العميل ecs-cli وامتلاك الصلاحيات / الأدوار المناسبة. ثم يمكنك، بمساعدة أوامر ecs-cli compose، إعادة استخدام وصف المكدس.
لاستخدام Kubernetes، يمكنك استخدام وحدة تحكم الويب في AWS أو أداة سطر الأوامر eksctl مع امتلاك الصلاحيات / الأدوار المناسبة. ثم يمكنك، مع بيئة kubectl مضبوطة جيدًا، إعادة استخدام ملفات بيان Kubernetes.