Skip to content

Instantly share code, notes, and snippets.

@fhuitelec
Last active February 24, 2021 22:19
Show Gist options
  • Save fhuitelec/b5565c5e97ccc7fffaaa6798591f875b to your computer and use it in GitHub Desktop.
Save fhuitelec/b5565c5e97ccc7fffaaa6798591f875b to your computer and use it in GitHub Desktop.
Workaround for tilt's docker_compose() and complex compose stacks - https://github.com/tilt-dev/tilt/issues/3393
def _probe_for(container):
"""Simulate a healthcheck using:
- container's running status
- container's health if it exists
Needs jq installed locally
:type container: str
:rtype: Probe
"""
return probe(
period_secs=5,
success_threshold=1,
failure_threshold=1,
timeout_secs=2,
exec=exec_action(command=[
"sh", "-c",
"docker inspect --format='{{json .}}' %s " % container +
"| jq -r '((.State.Running | tostring) + \" \" + (.State.Health.Status // \"healthy\"))' " +
"| grep 'true healthy'"
])
)
def _container_for(stack_computed_name, service):
"""Compute container name from compose service & stack name
:type computed_name: str
:type service: str
:rtype: str
"""
return '%s__%s' % (stack_computed_name, service)
def _map_dependency_names(name, dependencies):
"""Transforms docker-compose depends_on to Tilt container dependencies
:type name: str
:param dependencies: List[str]
:rtype: List[str]
"""
return [_container_for(name, dependency) for dependency in dependencies]
def compose_resource(name, computed_name, dc_path, build_cmd='true', dependencies=[]):
"""Create a pseudo docker_compose() resource supporting multiple compose stack and CWDs
Beware, this resource does not support docker_build() or custom_build()
:param name: Name of the compose stack (group of services)
:param computed_name: Same as name but computable (DNS like)
:param dc_path: Path of the docker-compose.yaml file
:param build_cmd: Command to build the resource, independently from the compose services themselves
:param dependencies: Tilt resource dependencies which this resource relies on
:type name: str
:type computed_name: str
:type dc_path: str
:type build_cmd: str
:type dependencies: List[str]
"""
# Make dependencies mutable (I know, this is ugly)
dependencies = [] + dependencies
for service, specs in decode_yaml(read_file(dc_path))['services'].items():
container = _container_for(computed_name, service)
resource_deps = [] if 'depends_on' not in specs else _map_dependency_names(
computed_name,
specs['depends_on']
)
local_resource(
container,
serve_cmd='docker-compose -p %s -f %s run --rm --service-ports --use-aliases --no-deps --name %s %s' % (
computed_name,
dc_path,
container,
service
),
resource_deps=resource_deps,
deps=[os.path.dirname(dc_path)],
readiness_probe=_probe_for(container),
allow_parallel=True
)
dependencies.append(container)
local_resource(
name,
cmd=build_cmd,
serve_cmd="echo Glue service for %s && tail -f /dev/null" % computed_name,
resource_deps=dependencies,
allow_parallel=True,
)
print('Loaded docker-compose resource for %s' % computed_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment