Search code examples
phpdockergodocker-composecron

Docker-compose for nginx, php, mysql, golang


The server is now working with this configuration.

version: '3'
services:
    nginx:
        image: nginx:latest
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./www:/var/www
        depends_on:
            - php
    php:
        build: ./docker/images/php
        volumes:
            - ./www:/var/www
    mysql:
        image: mysql       
        ports:
            - "3306:3306"
        volumes:
            - ./docker/mysql:/var/lib/mysql
            - ./docker/import:/docker-entrypoint-initdb.d
        environment:
            MYSQL_USER: ${MYSQL_USER}
            MYSQL_PASSWORD: ${MYSQL_PASSWORD}
            MYSQL_DATABASE: ${MYSQL_DATABASE}
            MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

Dockerfile for php image

# Main image
FROM php:7.3-fpm

# Update and install modules for php and other
RUN apt-get update && apt-get install -y \      
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && apt-get install -y wget zip unzip git \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd pdo mysqli pdo_mysql \
    && docker-php-ext-enable mysqli

# Workdir for php
WORKDIR /var/www

# Run container
CMD ["php-fpm"]

I want to add golang container to this config so that I can run the execution golang files from cron.

Questions are:

  • What is the best way to do this?
  • How to add it specifically to docker-compose / Dockerfile and run from cron?

Solution

  • == Option 1: add docker-compose to crontab ==

    * * * * * cd <project dir>/docker-compose && command docker-compose -f docker-compose.yml run --rm -T -w /go/bin <go_app_container> <go_app_name>
    

    == Option 2: use cron-docker ==

    Here is a Docker images to run cron inside the Docker container

    Adding cron jobs with cron-docker

    Suppose you have folder cron.d with your cron scripts. The only thing you have to do is copying this folder into the Docker image:

    # Dockerfile
    
    FROM renskiy/cron:debian
    
    COPY cron.d /etc/cron.d
    

    Then build and create container:

    docker build --tag my_cron .
    docker run --detach --name cron my_cron
    

    View logs

    To view logs use Docker logs command:

    docker logs --follow cron
    

    All you cron scripts should write logs to /var/log/cron.log. Otherwise you won't be able to view any log using this way.

    Passing cron jobs by arguments

    Additionally you can pass any cron job by argument(s) using custom start-cron command at the moment of container creation (providing optional user with -u/--user option):

    docker run --detach --name cron renskiy/cron:debian start-cron --user www-data \
        "0 1 \\* \\* \\* echo '01:00 AM' &gt;&gt; /var/log/cron.log 2&gt;&1" \
        "0 0 1 1 \\* echo 'Happy New Year!!' &gt;&gt; /var/log/cron.log 2&gt;&1"
    

    Environment variables

    Almost any environ variable you passed to the Docker will be visible to your cron scripts. With the exception of $SHELL, $PATH, $PWD, $USER, etc.

    docker run --tty --rm --interactive --env MY_VAR=foo renskiy/cron:debian start-cron \
        "\\* \\* \\* \\* \\* env &gt;&gt; /var/log/cron.log 2&gt;&1"
    

    == Option 3: use cron-docker with docker-compose ==

    For your case:

    version: '3'
    services:
        nginx:
            image: nginx:latest
            ports:
                - "80:80"
                - "443:443"
            volumes:
                - ./www:/var/www
            depends_on:
                - php
        php:
            build: ./docker/images/php
            volumes:
                - ./www:/var/www
        mysql:
            image: mysql       
            ports:
                - "3306:3306"
            volumes:
                - ./docker/mysql:/var/lib/mysql
                - ./docker/import:/docker-entrypoint-initdb.d
            environment:
                MYSQL_USER: ${MYSQL_USER}
                MYSQL_PASSWORD: ${MYSQL_PASSWORD}
                MYSQL_DATABASE: ${MYSQL_DATABASE}
                MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
        cron_go_app:
          image: renskiy/cron:alpine
          volumes:
            - crontabs:/etc/crontabs
            - my_go_app:/app/my_go_app
          run: start-cron