diff --git a/lec/07-compose/forward/Dockerfile b/lec/07-compose/forward/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..7d04463b42922e7b4c5af9359c5b96310db22044
--- /dev/null
+++ b/lec/07-compose/forward/Dockerfile
@@ -0,0 +1,5 @@
+FROM ubuntu:24.04
+RUN apt-get update && apt-get install -y python3 python3-pip curl iproute2
+COPY requirements.txt /tmp/requirements.txt
+RUN pip3 install -r /tmp/requirements.txt --break-system-packages
+CMD ["python3", "-m", "jupyterlab", "--no-browser", "--ip=0.0.0.0", "--port=????", "--allow-root", "--NotebookApp.token=''"]
diff --git a/lec/07-compose/forward/requirements.txt b/lec/07-compose/forward/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8cd0a1ab8859805a1a7d9e2d7a3798049a91be37
--- /dev/null
+++ b/lec/07-compose/forward/requirements.txt
@@ -0,0 +1,90 @@
+anyio==4.4.0
+argon2-cffi==23.1.0
+argon2-cffi-bindings==21.2.0
+arrow==1.3.0
+asttokens==2.4.1
+async-lru==2.0.4
+attrs==24.2.0
+babel==2.16.0
+beautifulsoup4==4.12.3
+bleach==6.1.0
+certifi==2024.8.30
+cffi==1.17.1
+charset-normalizer==3.3.2
+comm==0.2.2
+debugpy==1.8.5
+decorator==5.1.1
+defusedxml==0.7.1
+executing==2.1.0
+fastjsonschema==2.20.0
+fqdn==1.5.1
+h11==0.14.0
+httpcore==1.0.5
+httpx==0.27.2
+idna==3.10
+ipykernel==6.29.5
+ipython==8.27.0
+isoduration==20.11.0
+jedi==0.19.1
+Jinja2==3.1.4
+json5==0.9.25
+jsonpointer==3.0.0
+jsonschema==4.23.0
+jsonschema-specifications==2023.12.1
+jupyter-events==0.10.0
+jupyter-lsp==2.2.5
+jupyter_client==8.6.3
+jupyter_core==5.7.2
+jupyter_server==2.14.2
+jupyter_server_terminals==0.5.3
+jupyterlab==4.2.5
+jupyterlab_pygments==0.3.0
+jupyterlab_server==2.27.3
+MarkupSafe==2.1.5
+matplotlib-inline==0.1.7
+mistune==3.0.2
+nbclient==0.10.0
+nbconvert==7.16.4
+nbformat==5.10.4
+nest-asyncio==1.6.0
+notebook_shim==0.2.4
+overrides==7.7.0
+packaging==24.1
+pandocfilters==1.5.1
+parso==0.8.4
+pexpect==4.9.0
+platformdirs==4.3.3
+prometheus_client==0.20.0
+prompt_toolkit==3.0.47
+psutil==6.0.0
+ptyprocess==0.7.0
+pure_eval==0.2.3
+pycparser==2.22
+Pygments==2.18.0
+python-dateutil==2.9.0.post0
+python-json-logger==2.0.7
+PyYAML==6.0.2
+pyzmq==26.2.0
+referencing==0.35.1
+requests==2.32.3
+rfc3339-validator==0.1.4
+rfc3986-validator==0.1.1
+rpds-py==0.20.0
+Send2Trash==1.8.3
+setuptools==68.1.2
+six==1.16.0
+sniffio==1.3.1
+soupsieve==2.6
+stack-data==0.6.3
+terminado==0.18.1
+tinycss2==1.3.0
+tornado==6.4.1
+traitlets==5.14.3
+types-python-dateutil==2.9.0.20240906
+uri-template==1.3.0
+urllib3==2.2.3
+wcwidth==0.2.13
+webcolors==24.8.0
+webencodings==0.5.1
+websocket-client==1.8.0
+wheel==0.42.0
diff --git a/lec/07-compose/starter/Dockerfile b/lec/07-compose/starter/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ac45dda742f107fd80464a1d5ccbe72e04403570
--- /dev/null
+++ b/lec/07-compose/starter/Dockerfile
@@ -0,0 +1,5 @@
+FROM ubuntu:24.04
+RUN apt-get update && apt-get install -y python3 python3-pip iproute2
+RUN pip3 install grpcio-tools==1.70.0 grpcio==1.70.0 protobuf==5.29.3 --break-system-packages
+COPY *.py /
+CMD ["python3", "/server.py"]
diff --git a/lec/07-compose/starter/client.py b/lec/07-compose/starter/client.py
new file mode 100644
index 0000000000000000000000000000000000000000..713767577b4554776d91ad615df4030cfcab0fea
--- /dev/null
+++ b/lec/07-compose/starter/client.py
@@ -0,0 +1,8 @@
+import sys
+import grpc
+import count_pb2, count_pb2_grpc
+
+channel = grpc.insecure_channel("127.0.0.1:" + sys.argv[1])
+stub = count_pb2_grpc.CounterStub(channel)
+
+print(stub.Count(count_pb2.Req()))
diff --git a/lec/07-compose/starter/count.proto b/lec/07-compose/starter/count.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e14b093d17cd0e3b6e86e846596e4aced1a03c0b
--- /dev/null
+++ b/lec/07-compose/starter/count.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+message Req{}
+message Resp{
+        int32 total = 1;
+}
+
+service Counter {
+        rpc Count(Req) returns (Resp);
+}
\ No newline at end of file
diff --git a/lec/07-compose/starter/count_pb2.py b/lec/07-compose/starter/count_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c90fe315cface368ab00fc4c28c4928eaba87ee
--- /dev/null
+++ b/lec/07-compose/starter/count_pb2.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: count.proto
+# Protobuf Python Version: 5.27.2
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+_runtime_version.ValidateProtobufRuntimeVersion(
+    _runtime_version.Domain.PUBLIC,
+    5,
+    27,
+    2,
+    '',
+    'count.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x63ount.proto\"\x05\n\x03Req\"\x15\n\x04Resp\x12\r\n\x05total\x18\x01 \x01(\x05\x32\x1f\n\x07\x43ounter\x12\x14\n\x05\x43ount\x12\x04.Req\x1a\x05.Respb\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'count_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+  DESCRIPTOR._loaded_options = None
+  _globals['_REQ']._serialized_start=15
+  _globals['_REQ']._serialized_end=20
+  _globals['_RESP']._serialized_start=22
+  _globals['_RESP']._serialized_end=43
+  _globals['_COUNTER']._serialized_start=45
+  _globals['_COUNTER']._serialized_end=76
+# @@protoc_insertion_point(module_scope)
diff --git a/lec/07-compose/starter/count_pb2_grpc.py b/lec/07-compose/starter/count_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..309f71f258fbc07c98299982820142ac146d05d8
--- /dev/null
+++ b/lec/07-compose/starter/count_pb2_grpc.py
@@ -0,0 +1,97 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+import warnings
+
+import count_pb2 as count__pb2
+
+GRPC_GENERATED_VERSION = '1.66.1'
+GRPC_VERSION = grpc.__version__
+_version_not_supported = False
+
+try:
+    from grpc._utilities import first_version_is_lower
+    _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
+except ImportError:
+    _version_not_supported = True
+
+if _version_not_supported:
+    raise RuntimeError(
+        f'The grpc package installed is at version {GRPC_VERSION},'
+        + f' but the generated code in count_pb2_grpc.py depends on'
+        + f' grpcio>={GRPC_GENERATED_VERSION}.'
+        + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+        + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
+    )
+
+
+class CounterStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Count = channel.unary_unary(
+                '/Counter/Count',
+                request_serializer=count__pb2.Req.SerializeToString,
+                response_deserializer=count__pb2.Resp.FromString,
+                _registered_method=True)
+
+
+class CounterServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def Count(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_CounterServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Count': grpc.unary_unary_rpc_method_handler(
+                    servicer.Count,
+                    request_deserializer=count__pb2.Req.FromString,
+                    response_serializer=count__pb2.Resp.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'Counter', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+    server.add_registered_method_handlers('Counter', rpc_method_handlers)
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Counter(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def Count(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(
+            request,
+            target,
+            '/Counter/Count',
+            count__pb2.Req.SerializeToString,
+            count__pb2.Resp.FromString,
+            options,
+            channel_credentials,
+            insecure,
+            call_credentials,
+            compression,
+            wait_for_ready,
+            timeout,
+            metadata,
+            _registered_method=True)
diff --git a/lec/07-compose/starter/server.py b/lec/07-compose/starter/server.py
new file mode 100644
index 0000000000000000000000000000000000000000..83d193397376c9e87058d5916231d024df6c863f
--- /dev/null
+++ b/lec/07-compose/starter/server.py
@@ -0,0 +1,18 @@
+import grpc
+import count_pb2, count_pb2_grpc
+from concurrent import futures
+
+total = 0
+
+class MyCounter(count_pb2_grpc.CounterServicer):
+    def Count(self, request, context):
+        global total
+        total += 1
+        return count_pb2.Resp(total=total)
+
+server = grpc.server(futures.ThreadPoolExecutor(max_workers=1), options=[("grpc.so_reuseport", 0)])
+count_pb2_grpc.add_CounterServicer_to_server(MyCounter(), server)
+server.add_insecure_port("0.0.0.0:5440")
+server.start()
+print("started")
+server.wait_for_termination()