Moodle Docker Web Service working but can not be called from another docker container in the same network

Viewed 215

I am running a moodle docker container and one other container to call moodle web service function in a same network. I'm pretty sure I have set up the moodle properly because I can call moodle web service from postman. I am also aware i need to use the container alias of the running moodle container, which in this case is webserver. This is what i have tried

calling http://localhost:8000/webservice/rest/server.php?moodlewsrestformat=json&wstoken=fa4e7222df472b032ca9b4bd6d17595a&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2 from Postman and it return the following response

{
    "users": [
        {
            "id": 2,
            "username": "admin",
            "firstname": "Admin",
            "lastname": "User",
            "fullname": "Admin User",
            "email": "abc@def.com",
            "department": "",
            "firstaccess": 1655901976,
            "lastaccess": 1655907821,
            "auth": "manual",
            "suspended": false,
            "confirmed": true,
            "lang": "en",
            "theme": "",
            "timezone": "99",
            "mailformat": 1,
            "description": "",
            "descriptionformat": 1,
            "profileimageurlsmall": "http://localhost:8000/theme/image.php/boost/core/1655902245/u/f2",
            "profileimageurl": "http://localhost:8000/theme/image.php/boost/core/1655902245/u/f1",
            "preferences": [
                {
                    "name": "core_message_migrate_data",
                    "value": "1"
                },
                {
                    "name": "auth_manual_passwordupdatetime",
                    "value": "1655902098"
                },
                {
                    "name": "email_bounce_count",
                    "value": "1"
                },
                {
                    "name": "email_send_count",
                    "value": "1"
                },
                {
                    "name": "login_failed_count_since_success",
                    "value": "0"
                },
                {
                    "name": "_lastloaded",
                    "value": 1655907864
                }
            ]
        }
    ],
    "warnings": []
}

but when i try calling the same API from the other container i get a 403 response status, i also tried calling the same API with curl inside the container using curl -v -g 'http://webserver/webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2'

with result:

*   Trying 172.18.0.8:80...
* Connected to webserver (172.18.0.8) port 80 (#0)
> GET /webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2 HTTP/1.1
> Host: webserver
> User-Agent: curl/7.80.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Forbidden
< Date: Wed, 22 Jun 2022 14:42:38 GMT
< Server: Apache/2.4.53 (Debian)
< X-Powered-By: PHP/7.4.29
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=utf-8
< 
* Closing connection 0

so it is clearly connected but somehow still return 403 response, am i missing something? is there another moodle settings i have to tweak?

I am using moodle-docker with added

networks:
  default:
    name: network_name
    external: true

at the end of base.yml file so it could connect to the current project I'm working on which is a Node.js project that will call one of the web service on moodle. Here is the docker-compose.yml which relevant to this question

version: "3.7"
services:
  test:
    build: .
    env_file:
      - "./.env"
    ports:
      - 8085:8085
    networks:
      - network_name

networks:
  network_name:
    driver: bridge
    name: network_name

this is the result of calling docker logs of the moodle container

172.18.0.1 - - [22/Jun/2022:15:38:27 +0000] "GET /webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2 HTTP/1.1" 200 1464 "-" "PostmanRuntime/7.29.0"
[Wed Jun 22 15:38:30.315720 2022] [php7:notice] [pid 22] [client 172.18.0.3:34082] Debugging: The server died because the web services or the REST protocol are not enable in \n* line 39 of /webservice/rest/server.php: call to debugging()\n
172.18.0.3 - - [22/Jun/2022:15:38:30 +0000] "GET /webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2 HTTP/1.1" 403 199 "-" "curl/7.80.0"

This error doesn't make any sense to me because i already enabled the web service and the REST protocol on the site administration settings. I also tried to enable web services for mobile devices with no luck so far. I'm also new to moodle development so I might miss something simple so any input is appreciated.

UPDATE:

After restarting the whole docker setup and try to curl from the container again I got this message:

*   Trying 172.19.0.8:80...
* Connected to webserver (172.19.0.8) port 80 ()
> GET /webservice/rest/server.php?wstoken=beebce17854eff740ba85ec016542cfe&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2 HTTP/1.1
> Host: webserver
> User-Agent: curl/7.80.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 23 Jun 2022 07:34:35 GMT
< Server: Apache/2.4.53 (Debian)
< X-Powered-By: PHP/7.4.29
< Vary: Accept-Encoding
< Content-Length: 284
< Content-Type: text/html; charset=UTF-8
< 
Install Behat before enabling it, use:
 php admin/tool/behat/cli/init.php
<br />
<b>Warning</b>:  Cannot modify header information - headers already sent by (output started at /var/www/html/lib/testing/lib.php:169) in <b>/var/www/html/lib/testing/lib.php</b> on line <b>171</b><br />
* Connection #0 to host webserver left intact

After further investigation I found that in config.docker-template.php there is a setting for $CFG->behat_wwwroot which has default value to http://webserver. I am not familiar how to setup testing framework in Moodle so I'm not sure how can I change this.

Now my problem is how to setup the moodle docker to both be exposed from localhost and webserver. Is anyone familiar with this?

2 Answers

Problem

Since you have not mentioned the port cURL tries to connect to port 80 which is the default http port. You can observe it here:

* Connected to webserver (172.18.0.8) port 80 (#0)

Solution

You need to specifically set it as 8000:

Instead of

'http://webserver/webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2'

It should be

'http://webserver:8000/webservice/rest/server.php?wstoken=fa4e7222df472b032ca9b4bd6d17595a&moodlewsrestformat=json&wsfunction=core_user_get_users&criteria[0][key]=id&criteria[0][value]=2'

you must use docker-compose to create your network.

Related