@@ -87,6 +87,10 @@ def child_env(parent_env=None):
8787
8888 result ['PATH' ] = docker_bin
8989
90+ # `docker compose` uses $HOME to examine `~/.cache`, though I have no idea
91+ # why.
92+ result ['HOME' ] = parent_env ['HOME' ]
93+
9094 return result
9195
9296
@@ -325,6 +329,30 @@ def header_args():
325329 return fields , body
326330
327331
332+ def add_services_in_nginx_etc_hosts (services ):
333+ """When we added build/test support on ARM64 by using the ARM64 execution
334+ environment in CircleCI, we started seeing intermittent delays in DNS
335+ lookups, always about five seconds.
336+
337+ This function uses `getent` to look up the IP address of each `docker
338+ compose` service, and then associates the address with the service name by
339+ adding a line to /etc/hosts in the nginx service container. This way, the
340+ default `gethostbyname()` resolver used by nginx will not use DNS."""
341+ script = f"""
342+ for service in { " " .join (f"'{ service } '" for service in services )} ; do
343+ getent hosts "$service" >>/etc/hosts
344+ done
345+ """
346+ # "-T" means "don't allocate a TTY". This is necessary to avoid the
347+ # error "the input device is not a TTY".
348+ command = docker_compose_command ('exec' , '-T' , '--' , 'nginx' ,
349+ '/bin/sh' )
350+ subprocess .run (command ,
351+ input = script ,
352+ env = child_env (),
353+ encoding = 'utf8' )
354+
355+
328356class Orchestration :
329357 """A handle for a `docker compose` session.
330358
@@ -386,6 +414,7 @@ def up(self):
386414 runtime_info = ready_queue .get ()
387415 self .containers = runtime_info ['containers' ]
388416 print (runtime_info , file = self .verbose , flush = True )
417+ add_services_in_nginx_etc_hosts (self .services )
389418
390419 def down (self ):
391420 """Stop service orchestration.
0 commit comments