Visión general de la Arquitectura¶
QFieldCloud tiene una arquitectura en contenedores con múltiples contenedores y volúmenes.
docker-compose.yml, el resto del texto es la función del contenedor. Las flechas entre contenedores indican quién inicia la comunicación. Las flechas entre un contenedor y un volumen representan si el contenedor lee (flecha que señala al contenedor) o escribe (flecha que señala al volumen) datos. Las flechas y contenedores en gris representan servicios obsoletos
See an interactive version of the drawing above.
Nota Por simplicidad y claridad, todos los gráficos muestran el llamado "camino feliz" sin detallar la gestión de errores a lo largo del proceso.
Objetos Docker¶
Contenedores¶
[nginx] Proxy inverso¶
The reverse proxy that sits in front of QFieldCloud.
Hard requirement on nginx for this purpose as the X-Accel-Redirect HTTP header is heavily used in production to serve files directly from the Object Storage.
Requiere la presencia de un certificado SSL: autofirmado, Let's Encrypt u otro.
[app] Aplicación QFieldCloud¶
El software principal que ejecuta QFieldCloud, incluyendo autenticación, gestión de permisos, modelos de datos, archivos estáticos, interfaz administrativa y más.
Consta de varias aplicaciones Django, a saber:
autenticación- responsable de la autenticación de la API.core- modelos de datos, permisos, gestión de colas de trabajo, API REST, interfaz administrativa y todo lo demás de QFieldCloud que no gestionan las otras aplicaciones Django.filestorage- responsable de la gestión de archivos del proyecto y de su respectiva API REST.notifs- módulo de notificaciones.suscripción- gestión de los planes de usuario, suscripción y cuota de almacenamiento.
[memcached] Caché en memoria¶
Utiliza memcached para la caché en memoria de la configuración de Django y otros valores calculados.
[ofelia] Runner CRON¶
Utiliza ofelia para el runner CRON.
[mkcert] Creador del certificado autofirmado¶
Crea automáticamente un certificado SSL autofirmado para el desarrollo local y las implantaciones de prueba.
[certbot] Gestor de Letsencrypt¶
Utiliza certbot para gestionar los certificados Let's Encrypt.
Recrea automáticamente los certificados SSL que caducan y son recargados automáticamente por [nginx] Reverse Proxy.
[worker_wrapper] Cola Consumer¶
Uno o más contenedores para consumir y gestionar trabajos desde la cola.
El [worker_wrapper] Consumidor de Cola consulta periódicamente la [db] Base de Datos de Aplicaciones para detectar nuevos trabajos pendientes.
Al encontrar un trabajo en estado PENDIENTE, el [worker_wrapper] Consumidor de Cola lo establece en estado EN COLA y comienza a procesarlo.
A continuación, el contenedor establece una serie de metadatos en el objeto Trabajo en la [db] Base de Datos de Aplicaciones e inicia un nuevo contenedor temporal [qgis] Worker.
Espera a que el contenedor [qgis] Worker finalice, obtiene los registros y los almacena en la [db] Base de Datos de Aplicaciones.
Por último, actualiza un conjunto de metadatos de otros Trabajos en la [db] Base de Datos basándose en el código de salida y en los registros del [qgis] Worker, y establece el estado del Trabajo en FINISHED o FAILED.
El contenedor ejecuta el mismo código Django utilizado en [app] QFieldCloud App.
Lee cómo funciona la cola del consumer [worker_wrapper] en la sección Cola de trabajos.
[qgis] Worker¶
El contenedor del Worker es el lugar real donde se ejecutan los Trabajos creados por la [app] QFieldCloud App.
Cada contenedor Worker es creado dinámicamente por el [worker_wrapper] Cola del Consumer para ejecutar un único trabajo para un único proyecto y eliminado justo después.
La ejecución típica de un Worker consiste en iniciar una aplicación QGIS cualquiera, descargar los archivos del proyecto, procesar los archivos del proyecto y volver a cargar los archivos procesados resultantes.
El contenedor [qgis] Worker obtiene variables de entorno, incluido un token temporal de autenticación QFieldCloud, del [worker_wrapper] Cola de Consumer, y le devuelve datos escribiendo registros en el STDERR y escribiendo archivos en el volumen compartido temporal, principalmente feedback.json.
Volúmenes¶
[cerbot_www]¶
Almacena los certificados SSL creados por [mkcert] Creador de certificados autofirmados o [certbot] Gestor de Letsencrypt.
[transformation_grids]¶
Contiene todos los grip de transformación disponibles, descargadas de https://cdn.proj.org/ y puestas a disposición de todos los Trabajos.
[static_volume]¶
Contiene todos los activos estáticos, como fuentes, CSS, JS o archivos de imagen.
[media_volume]¶
Aviso Obsoleto, puede ser eliminado en cualquier momento.
La ubicación por defecto para los archivos subidos por el usuario. No debe utilizarse nunca.
Servicios de desarrollo¶
Los siguientes contenedores sólo están disponibles para fines de desarrollo local y no deben utilizarse en producción, ya que estos servicios no están monitorizados, no tienen copia de seguridad y, en general, están diseñados para un uso crítico dentro del stack.
[rustfs] File Storage¶
Local Object Storage (S3-like) used for development.
The data is stored on 4 [rustfs_data] volumes, as replication is enforced by rustfs.
Should be replaced by a proper S3-like Object Storage SaaS provider in production environments.
If rustfs is running, please make sure the host's firewall allows port 8009, required by the rustfs service (or the port configured with the OBJECT_STORAGE_API_PORT environment variable).
[createbuckets] Create Object Storage Buckets¶
Single shot container to create the required buckets on [rustfs] File Storage.
[webdav] WebDAV File Storage¶
Almacenamiento WebDAV local utilizado para el desarrollo, utilizando el protocolo y las especificaciones WebDAV.
Los datos se almacenan en el volumen [webdav_data].
Can alternatively be used in place of the rustfs File Storage for storing the files.
Can optionally be used for storing only attachments on it.
Info
Configuring a WebDAV storage is optional, it is not a requirement for the system to work properly.
If used, the WebDAV storage service should be replaced by a proper WebDAV SaaS provider in production environments, e.g. NextCloud.
[db] Aplicación PostgreSQL¶
Servidor local de base de datos PostgreSQL para alojar los datos de la [app] QFieldCloud Aplicación.
El esquema de la base de datos está totalmente gestionado por Django.
El esquema no debe ser modificado por servicios externos.
Debería reemplazarse por una base de datos PostgreSQL adecuada con un proveedor SaaS PostGIS instalado.
[smtpdev] Servidor de correo¶
Servidor de correo local para gestionar el envío de correos electrónicos, como activación de registro, restablecimiento de contraseña o notificaciones.
Debería reemplazarse por un proveedor SaaS de correo electrónico adecuado que admita el protocolo SMTP.
[rustfs_data]¶
Stores data for the [rustfs] File Storage.
[webdav_data]¶
Stores data for the [webdav] WebDAV File Storage if present.
[postgres_data]¶
Almacena datos para [db] Aplicación PostgreSQL.
[smtp4dev_data]¶
Almacena datos para el servidor de correo [smtpdev].
Cola de trabajos¶
QFieldCloud ejecuta operaciones muy pesadas para que la sincronización del proyecto funcione sin problemas para los usuarios. Por lo tanto, estas operaciones se ejecutan mediante los trabajos (jobs.md) que se ejecutan en segundo plano.
Aquí tenemos un diagrama de secuencia de las etapas que sigue cada ejecución de trabajo.
Algunos de los pasos se acortan intencionalmente para mayor claridad..
sequenceDiagram
autonumber
participant DB as QFieldCloud DB
participant Queue as QFieldCloud Queue
loop poll database
Queue->>DB: select the oldest Job with `PENDING` status
Queue->>DB: set the status of Job to `STARTED` status
Queue->>DB: create a new temporary authentication token
create participant Worker
Queue->>Worker: create the worker and pass the authentication token
note over Worker: job specific processing...
destroy Worker
Queue-xWorker: get worker's structured and free text logs and exit code
Queue->>DB: set job's structured logs, free text logs and exit code
alt Worker has zero exit status
Queue->>DB: set the Job status to `FINISHED`
else Worker has non-zero exit status
Queue->>DB: set the Job status to `FAILED`
end
break when any of the steps above fails
Queue-->DB: set the status Job to `FAILED`
end
end
Si bien algunos de los pasos aún están simplificados, este diagrama contiene mucha más información sobre el ciclo de vida de los atributos del trabajo.
sequenceDiagram
autonumber
participant DB as QFieldCloud DB
participant Queue as QFieldCloud Queue
loop [every few seconds]
Queue->>DB: select the oldest job with `PENDING` status
Queue->>DB: set the status of current job to `QUEUED`
Queue->>DB: set the status of current job to `STARTED` and `started_at` to `now()`
Queue->>DB: create a new temporary authentication token
Queue->>DB: set `docker_started_at` to `now()`
create participant Worker
Queue->>Worker: - mount `transformation_grids` volume <br> - set shared data volume <br> - set the environment variable with the authentication token <br> - set the environment variables from secrets <br> - set the `pgservice` file from secrets <br><br> Create the worker
activate Worker
par run worker
Worker->>API: Download files
API->>Worker: Files downloaded
note over Worker: job specific processing...
Worker->>API: Upload files
API->>Worker: Files uploaded
deactivate Worker
and wait for Worker to finish on Queue
Queue->>DB: set `container_id` to the newly created Docker container id
Queue->>Queue: wait until the Worker is finished or timeout reached
end
Queue->>DB: set `docker_finished_at` to `now()`
destroy Worker
Queue-xWorker: - get Worker's `stdout` logs <br> - get Worker's structured logs from the `feedback.json` in the shared volume <br> - get Worker's exit status code <br><br> Remove the container and cleanup all Job data
Queue->>DB: set job's `output` and `feedback`
alt [Worker has zero exit status]
Queue->>DB: set the status of current job to `FINISHED` and `finished_at` to `now()`
else [Worker has non-zero exit status]
Queue->>DB: set the status of current job to `FAILED`
end
break when any of the steps above fails
Queue-->DB: set the status of the current job to `FAILED`
end
end
participant API as QFieldCloud App