SYNOPSIS
        # Standalone: run a command with restart on failure
        shell$ aep --command /usr/bin/myapp --command-args "--foreground" --command-restart -1

        # Lock server: orchestrate startup order for docker-compose
        shell$ aep --lock-server --lock-server-order "db,redis,app" \
                   --lock-server-exhaust-action exit

        # Lock client: wait for permission to start
        shell$ aep --lock-client --lock-id db --command /usr/bin/postgres \
                   --lock-trigger "both:text:ready to accept connections"

        # Docker health check
        shell$ aep --docker-health-check

DESCRIPTION
    AEP (Advanced Entry Point) is a container entrypoint tool that runs
    commands within Docker containers and provides a lock server/client
    mechanism for orchestrating multi-container startup order.

    In multi-container environments (docker-compose, Kubernetes pods),
    services often start simultaneously but depend on each other. AEP solves
    this by providing a lock server that controls the order in which
    services start, waiting for each service to report readiness before
    allowing the next to begin.

    AEP communicates between containers over a Unix domain socket using a
    JSON protocol. It supports five trigger types for detecting when a
    service is ready: time delay, text match, regex match, TCP connect
    probe, and external script.

ARGUMENTS
  Config related
   config-env
    Default value: disabled

    Only read configuration from environment variables.

   config-file
    Default value: disabled

    Read configuration from a YAML file.

   config-args
    Default value: disabled

    Only read configuration from command line arguments.

   config-merge (default)
    Default value: enabled

    Merge together env, config file and args to generate the final
    configuration.

   config-order (default)
    Default value: 'env,file,args' (left to right)

    The order to merge configuration sources. Later sources override earlier
    ones.

  Environment related
   env-prefix (default)
    Default value: AEP_

    When scanning the environment, aep will look for this prefix to identify
    which environment variables it should use as configuration. For example,
    setting "AEP_SOCKETPATH=/var/run/aep.sock" overrides the default socket
    path.

  Command related (what to run)
   command (string)
    What to actually run within the container. Default is "aep --help".

   command-args (string)
    The arguments to add to the command, comma separated. Default is
    nothing.

    Example: "--list,--as-service,--with-long "arg",--foreground"

   command-norestart
    If the command exits, do not attempt to restart it. Exit immediately.

   command-restart (integer)
    If the command exits, how many times to retry it. Default 0. Set to -1
    for infinite restarts.

   command-restart-delay (integer)
    The time in milliseconds to wait before retrying the command. Default
    1000.

  Lock commands (server)
    These options control the lock server, which orchestrates the startup
    order of multiple containers to prevent race conditions.

   lock-server
    Default value: disabled

    Act as a lock server. Other aep instances (lock clients) will connect
    and wait for permission to start their commands.

   lock-server-host (string)
    What host to bind to. Defaults to 0.0.0.0.

   lock-server-port (integer)
    What port to bind to. Defaults to 60000.

   lock-server-default (string)
    Default value: ignore

    If a client connects with a lock-id not in the order list, what action
    to take.

    *   ignore - Do not send a run signal. The client will wait
        indefinitely.

    *   run - Immediately tell the unknown client to start.

    *   runlast - Queue the client and run it after the order list is
        exhausted.

   lock-server-order (string)
    The list of lock-ids and the order to allow them to run, comma
    separated.

    Example: "db,redis,nginx"

    Each entry must match a lock-id sent by a connecting client. The server
    sends a "run" signal to each client in order, waiting for each to report
    success (via its lock-trigger) before advancing to the next.

   lock-server-exhaust-action (string)
    Default value: idle

    What to do when all clients in the order list have reported success.

    *   exit - Exit with code 0.

    *   idle - Do nothing, keep the server running.

    *   restart - Reset the order list and start the cycle again.

    *   execute - Start the server's own command (from --command).

  Lock commands (client)
   lock-client
    Default value: disabled

    Become a lock client. This aep will connect to a lock server and wait
    for permission to start its command.

   lock-client-host (string)
    What host to connect to. Defaults to "aep-master" (assumes Docker DNS).

   lock-client-port (integer)
    What port to connect to. Defaults to 60000.

   lock-client-noretry
    If the connection to the lock server fails, exit immediately instead of
    retrying. Overrides lock-client-retry.

   lock-client-retry (integer)
    Maximum number of connection retry attempts. Set to 0 for infinite
    retries. Defaults to 3.

   lock-client-retry-delay (integer)
    How long to wait in seconds before retrying the connection. Defaults to
    5.

   lock-trigger (string)
    Default: none:time:10000

    How to determine that the command started successfully. After the
    trigger fires, the client reports success to the lock server, which then
    allows the next client in the order to start.

    The syntax is:

        handle:filter:specification

    "handle" can be "stderr", "stdout", "both", or "none".

    Available filters:

    *   time - Wait this many milliseconds and then report success.

        Example: "none:time:2000"

    *   regex - Wait until this regex matches output.

        Example: "both:regex:ok|success"

    *   text - Wait until this exact text appears in output.

        Example: "both:text:success"

    *   script - Run an external script and use its exit code (0 = success).
        Runs with a 30-second timeout. Retries every second on failure.

        Example: "none:script:/opt/check_state"

    *   connect - Try to connect to a TCP host:port. No data is sent or
        received. Retries every second on failure.

        Example: "none:connect:127.0.0.1:6767"

   lock-id (string)
    The identity this client reports to the lock server. Must match an entry
    in the server's "--lock-server-order" list (unless
    "--lock-server-default" is set to "run" or "runlast").

  Other
   docker-health-check
    Connect to the lock server socket and return an exit code for use with
    Docker HEALTHCHECK. Returns 0 (healthy) or 1 (unhealthy).

ENVIRONMENT
    AEP_SOCKETPATH
        Path to the Unix domain socket for lock server/client communication.
        Default: "/tmp/aep.sock"

BUGS
    For any feature requests or bug reports please visit:

    <https://github.com/PaulGWebster/p5-App-aep>

    You may also find the author 'daemon' on IRC:

    *   irc.libera.org #perl

AUTHOR
    Paul G Webster <daemon@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2023-2026 by Paul G Webster.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

