Dockerized cronジョブの設定例


こんにちは、あなたのDockerized環境でcron仕事を走らせる方法を不思議に思う?それは実際には非常に簡単です!PHPを使用してMySQLテーブルに行を挿入するダミープログラムで簡単な手順に従いましょう.
プログラムやデータベース構造はその例では関連していません.ただ、ただ一つのことに焦点を絞った最小の例を設定するだけの乗り物です.
それで、始めましょう、そして、あなたのIDEで新しいプロジェクトをつくってください!

事前の要件

  • あなたのシステム上で作業標準のDockerのインストール
  • PHPコード


    1つのスクリプトに含まれ、定義済みのテーブルに行を挿入するコードは次のようになりますtest_cron.php そしてそれをプロジェクトの根源に置きます
    <?php
    
    echo "connecting to DB".PHP_EOL;
    
    if( in_array ('pdo_mysql', get_loaded_extensions())) {
        // ! this code is bad, credentials are not read from a file or from env variables !
        $dsn = "mysql:host=db;dbname=test_db";
        $opt = [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC];
        echo "connected to DB".PHP_EOL;
        try {
            $connection = new PDO($dsn, "root", '', $opt);
    
            $val = 'testStr';
            // nothing is dynamic here, this code really sucks !
            $sql = 'INSERT INTO test_table(test_field) VALUES(:val)';   
            $statement = $connection->prepare($sql);
            $statement->execute([
                ':val' => $val
            ]);   
    
        } catch (\PDOException $pdoe) {
            echo $pdoe->getMessage();
        }
    }
    
    ... さて、あなたはアイデアを得る、コメントは自分で話す:)
    それで、我々が我々のcronで定期的に走るスクリプトです.
    しかし、それを実行するには、我々はデータベースと既存の必要がありますtest_table 書く.

    テストSQL表


    テストスクリプトを作成するためにSQLスクリプトを書きましょうdocker-compose この記事の一部.このファイルを呼びましょうtable.sql そして、我々のプロジェクトの根源にそれを置いてください.
    CREATE TABLE IF NOT EXISTS `test_table` (
      `id` MEDIUMINT NOT NULL AUTO_INCREMENT,
      `test_field` varchar(255)
    ) ENGINE=InnoDB;
    
    さて、cron設定部に行きましょう.

    cronタブの実行


    を持っているLinuxシステムでcron パッケージがインストールされ、それぞれのユーザがcrontab . The crontab タスクスケジューラを表すファイルですが、ユーザはタスクを定期的に実行する必要があります.これらのタスクの頻度を定義する構文があります.それをより良い感じを得るために、私は素晴らしいチェックをお勧めしますhttps://crontab.guru/ ウェブサイト!
    これを書きましょうcrontab 次のステップでは、Dockerのイメージ定義で使用します.ファイルを作成するcrontab , 拡張子なしで、プロジェクトのルートで.
    # run the test script every minute and output whatever it echoes in a log file
    * * * * * /usr/local/bin/php /cron_scripts/test_cron.php > /cron_scripts/test_cron.log 2>&1
    

    PHP cronを実行するdockerfile


    それでは、スケジュールにスクリプトを実行するためにDockerイメージを定義しましょう.これはDockerfile そして、推測?それは同様にプロジェクトの根源に住んでいます.
    FROM php:8.1-cli
    
    # installing cron package
    RUN apt-get update && apt-get -y install cron
    
    # installing PHP PDO extension to talk to MySQL
    RUN docker-php-ext-install pdo_mysql
    
    # putting our test PHP script somewhere in the filesystem
    RUN mkdir /cron_scripts
    WORKDIR /cron_scripts
    COPY test_cron.php /cron_scripts
    
    # creating the log file that will be written to at each cron iteration
    RUN touch test_cron.log
    
    # copy the crontab in a location where it will be parsed by the system
    COPY ./crontab /etc/cron.d/crontab
    # owner can read and write into the crontab, group and others can read it
    RUN chmod 0644 /etc/cron.d/crontab
    # running our crontab using the binary from the package we installed
    RUN /usr/bin/crontab /etc/cron.d/crontab
    
    今、一緒にこのすべてに合うように欠落しているパズルの1つの部分がありますdocker-compose.yml ファイルは、このすべてを調整する!

    ドッカー構成


    version: "3.9"
    
    # persisting db data in volume
    volumes:
      db-vol:
    
    services:
    
      # We have 4 services: the database, the db seeder, a cron that writes in db, and phpmyadmin to see the results of our running cron in a friendly UI
    
      db:
        image: mysql:latest
        container_name: db
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: "true"
          # this is the name of our database, that will be created automatically
          MYSQL_DATABASE: test_db
        restart: unless-stopped
        volumes:
          - db-vol:/var/lib/mysql
        ports:
          - "3306:3306"
    
      # we'll use a seeder container to create our test table, that our scheduled PHP script will write to
      db_seeder:
        image: mysql:latest
        # we copy our table creation script into the container
        volumes:
          - ./table.sql:/table.sql
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: "true"
        # we give the db time to initialize then we import our SQL script
        entrypoint: [ "bash", "-c", "sleep 10 && mysql --user=root --host=db --port=3306 test_db < /table.sql && exit"] 
        depends_on:
          - db
    
      # this is the container that will execute our cron
      cron:
        build:
          context: ./
          dockerfile: ./Dockerfile
        # run crond as main process of container
        entrypoint: [ "bash", "-c", "cron -f"] 
        depends_on:
          - db_seeder
    
      # our nice UI to browse our test table
      phpmyadmin:
          image: phpmyadmin:latest
          restart: unless-stopped
          ports:
              - 8080:80
          environment:
              # we specify that we connect to an arbitrary server with the flag below
              # "arbitrary" means you're able to specify which database server to use on login page of phpmyadmin      
              - PMA_ARBITRARY=1
          depends_on:
            - db_seeder
    
    ましょうdocker compose up これ!

    万事うまくいく


    すべてのコンテナが解雇された後、DB SEEDERはコード0で終了しました(DBの播種を意味します);我々のテーブルが定義されたスケジュールで書かれるかどうかチェックしましょう.
    そのためには、チェックアウトしましょうphpmyadmin インスタンスは、テーブルを参照します.我々は、我々の中で指定しましたdocker-compose.yml ファイルがphpmyadmin 私たちのホストマシンでポート8080でアクセスできますhttp://localhost:8080 ; サーバはdb , ユーザはroot そして、我々はパスワードを設定している.
    一度、あなたは私たちが作成したテストテーブルの左側に見て、それをクリックし、それを参照してください😎 .
    さて、コンテナにコピーしたcronログファイルをチェックしましょうtest_cron.log ファイル:それは毎分更新する必要があります!
    今、あなたは偉大な超大国を学んだ:Linux Dockerized環境でのスケジュールの自動化タスク;これは、DBテーブルに行を挿入する以外に、無限大のユースケースを持つことができます.
    この例のコードを見つけることができますhttps://github.com/yactouat/docker-cron-example
    この動画はお気に入りから削除されています👋