# مساحات Docker

تستضيف Spaces حاويات [Docker](https://docs.docker.com/get-started/) مخصصة للتطبيقات التي تقع خارج نطاق Streamlit وGradio. تتيح Spaces المعتمدة على Docker للمستخدمين تجاوز حدود ما كان ممكنًا سابقًا باستخدام SDKs القياسية. فمن نقاط نهاية FastAPI وGo إلى تطبيقات Phoenix وأدوات ML Ops، يمكن لـDocker Spaces أن تساعد في العديد من الإعدادات المختلفة.

## إعداد مساحات Docker

اختيار **Docker** كـ SDK عند [إنشاء مساحة جديدة](https://huggingface.co/new-space) سيهيّئ مساحتك من خلال تعيين خاصية `sdk` إلى `docker` في كتلة YAML الخاصة بملف `README.md`. أو، بالنسبة لمستودع مساحة موجود مسبقًا، عيّن `sdk: docker` داخل كتلة `YAML` في أعلى ملف **README.md** الخاص بمساحتك. يمكنك أيضًا تغيير المنفذ الافتراضي المكشوف `7860` عن طريق تعيين `app_port: 7860`. بعد ذلك، يمكنك إنشاء `Dockerfile` عادي.

```Yaml
---
title: Basic Docker SDK Space
emoji: 🐳
colorFrom: purple
colorTo: gray
sdk: docker
app_port: 7860
---
```

يمكنك داخليًا فتح عدد غير محدود من المنافذ. على سبيل المثال، يمكنك تثبيت Elasticsearch داخل مساحتك (Space) واستدعائه داخليًا على المنفذ الافتراضي الخاص به 9200.

إذا كنت ترغب في إتاحة التطبيقات المُقدَّمة على عدة منافذ للعالم الخارجي، فإن حلاً بديلاً هو استخدام وكيل عكسي مثل Nginx لتوجيه الطلبات القادمة من الإنترنت الأوسع (على منفذ واحد) إلى منافذ داخلية مختلفة.

## إدارة الأسرار والمتغيرات
 

يمكنك إدارة متغيرات البيئة الخاصة بمساحة في إعدادات المساحة. اقرأ المزيد [هنا](./spaces-overview#managing-secrets).

### المتغيرات

#### وقت البناء

تُمرَّر المتغيرات كـ`build-arg`s عند بناء مساحة Docker الخاصة بك. اقرأ [التوثيق المخصص من Docker](https://docs.docker.com/engine/reference/builder/#arg) للحصول على دليل كامل حول كيفية استخدام ذلك في Dockerfile.

```Dockerfile
	# Declare your environment variables with the ARG directive
	ARG MODEL_REPO_NAME

	FROM python:latest
	# [...]
	# You can use them like environment variables
	RUN predict.py $MODEL_REPO_NAME
```

#### وقت التشغيل

تُحقن المتغيرات في بيئة الحاوية وقت التشغيل.

### الأسرار

#### وقت البناء

في مساحات Docker، تختلف إدارة الأسرار لأسباب أمنية. بمجرد إنشاء سر في [تبويب الإعدادات](./spaces-overview#managing-secrets)، يمكنك كشف السر عن طريق إضافة السطر التالي إلى ملف Dockerfile الخاص بك:

على سبيل المثال، إذا كان `SECRET_EXAMPLE` هو اسم السر الذي أنشأته في تبويب الإعدادات، يمكنك قراءته وقت البناء عن طريق تثبيته على ملف، ثم قراءته باستخدام `$(cat /run/secrets/SECRET_EXAMPLE)`.

انظر إلى مثال أدناه:
```Dockerfile
# Expose the secret SECRET_EXAMPLE at buildtime and use its value as git remote URL
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
 git init && \
 git remote add origin $(cat /run/secrets/SECRET_EXAMPLE)
```

```Dockerfile
# Expose the secret SECRET_EXAMPLE at buildtime and use its value as a Bearer token for a curl request
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
	curl test -H 'Authorization: Bearer $(cat /run/secrets/SECRET_EXAMPLE)'
```

#### وقت التشغيل

كما هو الحال مع المتغيرات العامة، يمكنك الوصول إلى الأسرار كمتغيرات بيئة وقت التشغيل. على سبيل المثال، في بايثون ستستخدم `os.environ.get("SECRET_EXAMPLE")`. اطّلع على هذا [مثال](https://huggingface.co/spaces/DockerTemplates/secret-example) لمساحة Docker تستخدم الأسرار.

## الصلاحيات

يعمل الحاوية مع معرّف مستخدم 1000. لتجنب مشاكل الأذونات، يجب عليك إنشاء مستخدم وإعداد `WORKDIR` الخاص به قبل أي `COPY` أو تنزيل.

```Dockerfile
# Set up a new user named "user" with user ID 1000
RUN useradd -m -u 1000 user

# Switch to the "user" user
USER user

# Set home to the user's home directory
ENV HOME=/home/user \
	PATH=/home/user/.local/bin:$PATH

# Set the working directory to the user's home directory
WORKDIR $HOME/app

# Try and run pip command after setting the user with `USER user` to avoid permission issues with Python
RUN pip install --no-cache-dir --upgrade pip

# Copy the current directory contents into the container at $HOME/app setting the owner to the user
COPY --chown=user . $HOME/app

# Download a checkpoint
RUN mkdir content
ADD --chown=user https://<SOME_ASSET_URL> content/<SOME_ASSET_NAME>
```

حدد دائمًا `--chown=user` مع `ADD` و`COPY` للتأكد من أن الملفات الجديدة مملوكة لمستخدمك.

إذا كنت لا تزال تواجه مشاكل في الأذونات، فقد تحتاج إلى استخدام `chmod` أو `chown` في `Dockerfile` الخاص بك لمنح الأذونات الصحيحة. على سبيل المثال، إذا كنت تريد استخدام المجلد `/data`، يمكنك القيام بما يلي:

```Dockerfile
RUN mkdir -p /data
RUN chmod 777 /data
```

يجب عليك دائمًا تجنب تغييرات الملكية غير الضرورية.
> [!WARNING]
> إن تحديث بيانات الوصف (metadata) لملف يُنشئ نسخة جديدة تُخزَّن في الطبقة الجديدة. لذلك، قد يؤدي تنفيذ أمر chown بشكل تكراري (recursive) إلى إنشاء صورة ضخمة الحجم بسبب تكرار جميع الملفات المتأثرة.

بدلاً من إصلاح الصلاحية عبر تشغيل `chown`:
```
COPY checkpoint .
RUN chown -R user checkpoint
```
يجب عليك دائماً القيام بما يلي:
```
COPY --chown=user checkpoint .
```
(يُطبق الأمر نفسه على أمر `ADD`)

## استمرارية البيانات

تُفقد البيانات المكتوبة على القرص عند إعادة تشغيل مساحة Docker الخاصة بك. ولحفظ البيانات عبر عمليات إعادة التشغيل، يمكنك إرفاق [Storage Bucket](./storage-buckets) بمساحتك.

حاليًا، حجم `/data` متاح فقط وقت التشغيل، أي أنك لا تستطيع استخدام `/data` أثناء خطوة البناء في ملف Dockerfile الخاص بك.

يمكنك أيضًا استخدام مركز مجموعات البيانات لدينا للحالات المحددة، حيث يمكنك تخزين الحالة والبيانات في مستودع git LFS. يمكنك العثور على مثال للاستمرارية [هنا](https://huggingface.co/spaces/Wauplin/space_to_dataset_saver)، والذي يستخدم مكتبة [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/index) لرفع الملفات برمجياً إلى مستودع مجموعة بيانات. سيساعدك هذا المثال الخاص بـ Space معًا مع [هذا الدليل](https://huggingface.co/docs/huggingface_hub/main/en/guides/upload#scheduled-uploads) في تحديد أي حل يناسب نوع بياناتك بشكل أفضل.

أخيرًا، في بعض الحالات، قد ترغب في استخدام حل تخزين خارجي من كود مساحة العمل الخاصة بك، مثل قاعدة بيانات مستضافة خارجيًا، أو S3، وما إلى ذلك.

### حاوية Docker مع GPU

يمكنك تشغيل حاويات Docker مع دعم GPU باستخدام أحد [أجهزة Spaces](./spaces-gpus) الخاصة بـ GPU.

نوصي باستخدام [`nvidia/cuda`](https://hub.docker.com/r/nvidia/cuda) من Docker Hub كصورة أساسية، حيث تأتي مع CUDA وcuDNN مثبتة مسبقًا.

خلال وقت بناء Docker، لا يكون لديك وصول إلى عتاد GPU. لذلك، يجب ألا تحاول تنفيذ أي أمر متعلق بـ GPU أثناء خطوة البناء في ملف Dockerfile الخاص بك. على سبيل المثال، لا يمكنك تشغيل `nvidia-smi` أو `torch.cuda.is_available()` أثناء بناء صورة. اقرأ المزيد [هنا](https://github.com/NVIDIA/nvidia-docker/wiki/nvidia-docker#description).

## اقرأ المزيد

- [مثال توضيحي كامل باستخدام Docker](spaces-sdks-docker-first-demo)
- [قائمة أمثلة مساحات Docker](spaces-sdks-docker-examples)
- [أمثلة على Spaces](https://huggingface.co/SpacesExamples)

