Soy nuevo en Docker y tengo un problema con mi Dockerfile personalizado que necesita ayuda de ustedes. Funciona bien hasta que agrego un código para ejecutar el cronjob en el contenedor docker.
Este es mi archivo Dockerfile:
FROM php:7.2-fpm-alpine COPY cronjobs /etc/crontabs/root // old commands ENTRYPOINT ["crond", "-f", "-d", "8"] Este es el archivo cronjobs :
* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1 Este es el archivo docker-compose.yml :
version: '3' networks: laravel: services: nginx: image: nginx:stable-alpine container_name: nginx_ctrade ports: - "8081:80" volumes: - ./app:/var/www/html - ./config/nginx/default.conf:/etc/nginx/conf.d/default.conf - ./config/certs:/etc/nginx/certs - ./log/nginx:/var/log/nginx depends_on: - php - mysql networks: - laravel working_dir: /var/www/html php: build: context: ./build dockerfile: php.dockerfile container_name: php_ctrade volumes: - ./app:/var/www/html - ./config/php/php.ini:/usr/local/etc/php/php.ini networks: - laravel mysql: image: mysql:latest container_name: mysql_ctrade tty: true volumes: - ./data:/var/lib/mysql - ./config/mysql/my.cnf:/etc/mysql/my.cnf environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_USER=admin - MYSQL_DATABASE=laravel - MYSQL_PASSWORD=secret networks: - laravel Reconstruyo las imágenes de la ventana acoplable y las ejecuto. El cronjob funciona bien, pero cuando accedo a localhost en localhost:8081 . Ya no funciona. La página muestra 502 Bad Gateway , así que verifiqué el registro de errores de Nginx. Este es el error de Nginx que me mostró:
2020/04/10 13:33:36 [error] 8#8: *28 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.224.1, server: localhost, request: "GET /trades HTTP/1.1", upstream: "fastcgi://192.168.224.3:9000", host: "localhost:8081", referrer: "http://localhost:8081/home"Todos los contenedores siguen ejecutándose después de la actualización.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a2403ece8509 nginx:stable-alpine "nginx -g 'daemon of…" 18 seconds ago Up 17 seconds 0.0.0.0:8081->80/tcp nginx_ctrade 69032097b7e4 ctrade_php "docker-php-entrypoi…" 19 seconds ago Up 18 seconds 9000/tcp php_ctrade 592b483305d5 mysql:latest "docker-entrypoint.s…" 3 hours ago Up 18 seconds 3306/tcp, 33060/tcp mysql_ctrade¿Hay alguien que tenga este problema antes? ¡Cualquier ayuda sería apreciada! ¡Muchas gracias!
Según la documentación, ejecutar dos (o más) servicios dentro de un contenedor Docker rompe su filosofía de responsabilidad única.
Por lo general, se recomienda separar las áreas de interés utilizando un servicio por contenedor. Ese servicio puede bifurcarse en múltiples procesos (por ejemplo, el servidor web Apache inicia múltiples procesos de trabajo). Está bien tener múltiples procesos, pero para obtener el máximo beneficio de Docker, evite que un contenedor sea responsable de múltiples aspectos de su aplicación general. [...]
Si elige seguir esta recomendación, terminará con dos opciones:
Opción 1 . Cree un contenedor separado que manejará las tareas de programación.
Ejemplo:
# File: Dockerfile FROM php:7.4.8-fpm-alpine COPY ./cron.d/tasks /cron-tasks RUN touch /var/log/cron.log RUN chown www-data:www-data /var/log/cron.log RUN /usr/bin/crontab -u www-data /cron-tasks CMD ["crond", "-f", "-l", "8"] # File: cron.d/tasks * * * * * echo "Cron is working :D" >> /var/log/cron.log 2>&1 # File: docker-compose.yml services: [...] scheduling: build: context: ./build dockerfile: cron.dockerfile [...]Opción 2 Use el crontab de su propio host para ejecutar las tareas programadas en los contenedores (como se defiende en esta publicación ).
Ejemplo:
# File on host: /etc/cron.d/my-laravel-apps * * * * * root docker exec -t laravel-container-A php artisan schedule:run >> /dev/null 2>&1 * * * * * root docker exec -t laravel-container-B php artisan schedule:run >> /dev/null 2>&1 * * * * * root docker exec -t laravel-container-C php artisan schedule:run >> /dev/null 2>&1PD: En su caso, reemplace <laravel-container-*> por php_ctrade .
Opción 3: Usar supervisord
Por otro lado, si realmente desea un solo contenedor, aún puede usar supervisord como su proceso principal y configurarlo para inicializar (y supervisar) las aplicaciones php-fpm y crontab .
Tenga en cuenta que este es un enfoque moderadamente pesado y requiere que empaquete supervisord y su configuración en su imagen (o base su imagen en una que incluya supervisord), junto con las diferentes aplicaciones que administra.
Encontrarás un ejemplo de cómo hacerlo aquí .
Referencias:
Lectura recomendada: