Skip to content

VIP Local Development Environment


The VIP Local Development Environment is composed of several Docker containers. Some of these containers bind host ports to be accessible from outside of their internal network.

The traefik proxy container is shared between all local environment’s running on the host machine. This makes it possible to run multiple dev-env instances simultaneously under different domains.

Unique domain names are created for each local environment with the following pattern:

The traefik proxy container uses the full domain name to direct traffic to the correct NGINX container in the internal Docker network.

For example, when a local environment’s domain is loaded in a browser, DNS resolution will find an A record for * that maps to a localhost. That request will then hit the traefik proxy container which is bound to the localhost port 80.

The traefik proxy container serves as a gateway to the local environment, and will try to bind port 80 and 443 to support http and https traffic. If those ports are taken, backup ports will be used instead.

Port binding for services

Use the info subcommand to see other exposed services on a running VIP Local Development Environment that have a port mapped to the host machine.

vip dev-env info

In the following example output, the exposed services for the local environment with the slug test are PHPMYADMIN, DATABASE, and ENTERPRISE SEARCH.

$ vip dev-env info --slug=test
 SLUG               test                                                                                     
 LOCATION           /home/user/.local/share/vip/dev-environment/test  
 SERVICES           devtools, nginx, php, database, memcached, phpmyadmin, vip-search, wordpress, mu-plugins, client-code 
 PHPMYADMIN URLS    http://localhost:49170  
 ENTERPRISE SEARCH                                
 STATUS             UP               

The ports for these services are explicitly selected to avoid conflicting with any other running environment. For this reason, service ports might change between restarts of an environment.


Wildcard DNS resolution is leveraged in order to point to localhost: It is possible for networking configurations on the local machine to prevent the local environment’s requested domain from resolving correctly.


  • The local environment is in a DOWN state.
  • Attempts to load the local environment’s domain in a browser returns the error message “This site can’t be reached“.

Verify that the domain resolution on the local machine is correct by querying the DNS for the local environment’s domain. The command output should return an A Record with the value For example:



Use the dig command. For example: dig


Use the nslookup command. For example: nslookup

Resolving DNS issues

If the returned A Record for the domain is blank, unexpected network settings are preventing the local environment’s DNS from pointing to the IP address

To resolve this issue, DNS settings on the local machine can be updated to point to a specific IPv4 address, such as Google’s DNS.

It is possible for the DNS for a local environment’s domain to correctly point at the localhost, but for proxies, tunneling, or security-related tools to prevent traffic to that domain from resolving as expected.

To investigate, use the curl command to verify that an environment is reachable and review the returned headers for more information about possible causes for the issue. Include the -v switch in the curl command to return all headers in the command output.

In this command example, the returned headers include the X-Powered-By: WordPress VIP header. The presence of this header indicates that traffic is correctly directed to the local environment, and a network setting on the local machine or the machine’s ISP is causing the DNS issue.

$ curl -v -o /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying
* Connected to ( port 80 (#0)
> GET / HTTP/1.1
> Host:
> User-Agent: curl/7.68.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Date: Tue, 17 May 2022 13:05:32 GMT
< Host-Header: a9130478a60e5f9135f765b23f26593b
< Link: <>; rel=""
< Server: nginx/1.21.6
< X-Hacker: If you're reading this, you should visit and apply to join the fun, mention this header.
< X-Powered-By: WordPress VIP <>
< X-Robots-Tag: noindex, nofollow
< Transfer-Encoding: chunked
{ [32589 bytes data]
100 80776    0 80776    0     0   355k      0 --:--:-- --:--:-- --:--:--  355k
* Connection #0 to host left intact

A Docker version of the curl command can be used as an alternative. For example:

docker run -it --rm --network=host curl -v -o /dev/null

Last updated: August 29, 2022