Search code examples
phpdockercurl

Curl PHP cannot connect to localhost inside Docker container


My Docker-compose.yml is:

version: '3.8'
services:
    app:
        build:
            context: .
            dockerfile: ./docker/app/Dockerfile
        command: bash -c "
            if [ ! -d /var/www/vendor ]         ; then  composer install --no-interaction                    ;  fi  &&
            if [ ! -f /var/www/.env ]           ; then  composer env-set                                     ;  fi  &&
            if [ ! -d /var/www/node_modules ]   ; then  npm install  &&  npm install chokidar && npm run dev ;  fi  &&
            if [ ! -d /var/www/public/storage ] ; then  php /var/www/artisan storage:link                    ;  fi &&
            php /var/www/artisan octane:start --no-interaction --host=0.0.0.0 --port=8000 --watch &&
            bash /var/www/docker/scheduler/run.sh
            "
        volumes:
            - .:/var/www
            - ./docker/app/php-settings.ini:/etc/php/8.3/cli/conf.d/php-settings.ini
            - ./docker/app/xdebug.ini:/etc/php/8.3/cli/conf.d/20-xdebug.ini
        working_dir: /var/www
        depends_on:
            - database
        ports:
           - "9010:9003"
        restart: unless-stopped
        extra_hosts:
            - "host.docker.internal:host-gateway"

    nginx:
        image: nginx:alpine
        ports:
            - '${APP_PORT:-80}:80'
        volumes:
            - .:/var/www
            # RoadRunner
            - ./docker/nginx/roadrunner.conf:/etc/nginx/conf.d/default.conf
        depends_on:
            - app
        restart: unless-stopped

    database:
        image: postgres:alpine
        ports:
            - '${FORWARD_DB_PORT:-5432}:5432'
        volumes:
            - db_data:/var/lib/postgresql/data
        environment:
            POSTGRES_DB: ${DB_DATABASE:-devices}
            POSTGRES_USER: ${DB_USERNAME:-root}
            POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
        restart: unless-stopped

    influx:
        image: influxdb:latest
        ports:
            - '${INFLUXDB_PORT:-8086}:8086'
        environment:
            DOCKER_INFLUXDB_INIT_MODE: setup
            DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_USERNAME:-influx}
            DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_PASSWORD:-password}
            DOCKER_INFLUXDB_INIT_ORG: influx
            DOCKER_INFLUXDB_INIT_BUCKET: influx
            DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: ${INFLUXDB_TOKEN:-tsb8f_gfi-dpo86qFaD58MRAIBadSWXLjL2orRMwkciE3Cit7Y_-lbSrqEvqhzU7XZ8ksxqhSWf4-KQs1CTG8A==}
        depends_on:
            - app
        restart: unless-stopped
        networks:
            - web
volumes:
    db_data:

networks:
    web:
        external: true

When I try to connect by OS curl as curl --location 'http://localhost:8086/api/v2' --header "Authorization: Token ${INFLUXDB_TOKEN} - everything ends fine.

When I try to use the same in PHP:

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://localhost:8086/api/v2');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_PORT, 8086);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    "Authorization: Token token_here"
]);
$out = curl_exec($curl);
return curl_errno($curl);

... then I always got CURL 7 error.

Found that problem exactly in Docker's nature of http://localhost:8086 ((

When change URL to http://influx:8086 - got CURL 6.

How to work with Docker conatainers by PHP CURL ?


Solution

  • Solution

    localhost is rarely ever the correct url for inter container communication with docker-compose. By default, it points to the localhost of each container, not to the localhost of your host machine.

    You can use the service name of the container as the url for influxdb, so in this case it's influx. ->

    'http://influx:8086/api/v2' is the correct url.

    You said you tried that and got curl error 6, are you sure you did not have some typo?

    Minimal Reproducible Example

    This minimal example works for me:

    test.php

    <?php
    
    print("Waiting for InfluxDB to start...");
    sleep(2);
    
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://influx:8086/api/v2');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_PORT, 8086);
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
        "Authorization: Token tsb8f_gfi-dpo86qFaD58MRAIBadSWXLjL2orRMwkciE3Cit7Y_-lbSrqEvqhzU7XZ8ksxqhSWf4-KQs1CTG8A=="
    ]);
    $out = curl_exec($curl);
    
    if(curl_error($curl)) {
        print(curl_error($curl));
    }
    
    return curl_errno($curl);
    ?>
    

    docker-compose.yml

    version: '3.8'
    services:
        php:
            image: php:latest
            command: php -f /test.php
            volumes:
              - ./test.php:/test.php
            depends_on:
                - influx
    
        influx:
            image: influxdb:latest
            environment:
                DOCKER_INFLUXDB_INIT_MODE: setup
                DOCKER_INFLUXDB_INIT_USERNAME: influx
                DOCKER_INFLUXDB_INIT_PASSWORD: password
                DOCKER_INFLUXDB_INIT_ORG: influx
                DOCKER_INFLUXDB_INIT_BUCKET: influx
                DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: tsb8f_gfi-dpo86qFaD58MRAIBadSWXLjL2orRMwkciE3Cit7Y_-lbSrqEvqhzU7XZ8ksxqhSWf4-KQs1CTG8A==
    

    By running this with docker compose up I can observe the following from the log:

    ...
    influx-1  | ts=2024-03-03T18:37:04.653010Z lvl=info msg="Welcome to InfluxDB" log_id=0niPXN30000 version=v2.7.5 commit=09a9607fd9 build_date=2024-01-05T17:17:04Z log_level=info
    ...
    php-1     | Waiting for InfluxDB to start...
    php-1     | {"authorizations":"/api/v2/authorizations","backup":"/api/v2/backup","buckets":"/api/v2/buckets","checks":"/api/v2/checks","dashboards":"/api/v2/dashboards","delete":"/api/v2/delete","external":{"statusFeed":"https://www.influxdata.com/feed/json"},"flags":"/api/v2/flags","labels":"/api/v2/labels","me":"/api/v2/me","notificationEndpoints":"/api/v2/notificationEndpoints","notificationRules":"/api/v2/notificationRules","orgs":"/api/v2/orgs","plugins":"/api/v2/telegraf/plugins","query":{"analyze":"/api/v2/query/analyze","ast":"/api/v2/query/ast","self":"/api/v2/query","suggestions":"/api/v2/query/suggestions"},"restore":"/api/v2/restore","scrapers":"/api/v2/scrapers","setup":"/api/v2/setup","signin":"/api/v2/signin","signout":"/api/v2/signout","sources":"/api/v2/sources","swagger":"/api/v2/swagger.json","system":{"debug":"/debug/pprof","health":"/health","metrics":"/metrics"},"tasks":"/api/v2/tasks","telegrafs":"/api/v2/telegrafs","users":"/api/v2/users","variables":"/api/v2/variables","write":"/api/v2/write"}
    php-1 exited with code 0