diff --git a/lec/05-docker/Dockerfile b/lec/05-docker/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..7848cc3eb73a4f384547fc8294a91ef3b7d2ace1
--- /dev/null
+++ b/lec/05-docker/Dockerfile
@@ -0,0 +1,6 @@
+FROM ubuntu:24.10
+RUN apt-get update && \
+    apt-get install -y unzip python3 python3-pip
+RUN pip3 install pandas==2.2.2 --break-system-packages
+COPY test.py /test.py
+CMD ["python3", "test.py"]
\ No newline at end of file
diff --git a/lec/05-docker/test.py b/lec/05-docker/test.py
new file mode 100644
index 0000000000000000000000000000000000000000..d48796b0bcee2b8eb14261337eb70be7ab8b778f
--- /dev/null
+++ b/lec/05-docker/test.py
@@ -0,0 +1,2 @@
+import pandas as pd
+print(pd.Series([1,2,3]).sum())
diff --git a/lec/06-grpc/client.py b/lec/06-grpc/client.py
new file mode 100644
index 0000000000000000000000000000000000000000..bef45ba267c893c9ed3b41a82f025ffa9a8427a4
--- /dev/null
+++ b/lec/06-grpc/client.py
@@ -0,0 +1,8 @@
+import grpc
+import math_pb2_grpc, math_pb2
+
+channel = grpc.insecure_channel("localhost:5440")
+stub = math_pb2_grpc.CalcStub(channel)
+
+resp = stub.Mult(math_pb2.MultReq(x=3, y=4))
+print(resp.result)
diff --git a/lec/06-grpc/many.py b/lec/06-grpc/many.py
new file mode 100644
index 0000000000000000000000000000000000000000..2db3d6f04217c89d9329fc1be9b5efb57ae0e173
--- /dev/null
+++ b/lec/06-grpc/many.py
@@ -0,0 +1,10 @@
+import grpc
+import math_pb2_grpc, math_pb2
+import sys
+
+nums = [int(arg) for arg in sys.argv[1:]]
+print(nums)
+channel = grpc.insecure_channel("localhost:5440")
+stub = math_pb2_grpc.CalcStub(channel)
+resp = stub.MultMany(math_pb2.MultManyReq(nums=nums))
+print(resp.result)
diff --git a/lec/06-grpc/math.proto b/lec/06-grpc/math.proto
new file mode 100644
index 0000000000000000000000000000000000000000..d654183d6073d2c43a48685dd0e79457388ea6ad
--- /dev/null
+++ b/lec/06-grpc/math.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+
+// PART 1: specify messages (with protobufs)
+
+message MultManyReq {
+        repeated int32 nums = 1;
+}
+
+message MultReq {
+        int32 x = 1;
+        int32 y = 2;
+}
+
+message MultResp {
+        int32 result = 1;
+}
+
+// PART 2: specify RPC calls (gprc services)
+
+service Calc {
+        // rpc FUNC_NAME(ARGS) returns (RESULT);
+        rpc Mult(MultReq) returns (MultResp);
+        rpc MultMany(MultManyReq) returns (MultResp);
+}
\ No newline at end of file
diff --git a/lec/06-grpc/math_pb2.py b/lec/06-grpc/math_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..8ff0478540eca92240f24d55ba5b2843246fc9ee
--- /dev/null
+++ b/lec/06-grpc/math_pb2.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: math.proto
+# Protobuf Python Version: 5.29.0
+"""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,
+    29,
+    0,
+    '',
+    'math.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmath.proto\"\x1b\n\x0bMultManyReq\x12\x0c\n\x04nums\x18\x01 \x03(\x05\"\x1f\n\x07MultReq\x12\t\n\x01x\x18\x01 \x01(\x05\x12\t\n\x01y\x18\x02 \x01(\x05\"\x1a\n\x08MultResp\x12\x0e\n\x06result\x18\x01 \x01(\x05\x32H\n\x04\x43\x61lc\x12\x1b\n\x04Mult\x12\x08.MultReq\x1a\t.MultResp\x12#\n\x08MultMany\x12\x0c.MultManyReq\x1a\t.MultRespb\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'math_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+  DESCRIPTOR._loaded_options = None
+  _globals['_MULTMANYREQ']._serialized_start=14
+  _globals['_MULTMANYREQ']._serialized_end=41
+  _globals['_MULTREQ']._serialized_start=43
+  _globals['_MULTREQ']._serialized_end=74
+  _globals['_MULTRESP']._serialized_start=76
+  _globals['_MULTRESP']._serialized_end=102
+  _globals['_CALC']._serialized_start=104
+  _globals['_CALC']._serialized_end=176
+# @@protoc_insertion_point(module_scope)
diff --git a/lec/06-grpc/math_pb2_grpc.py b/lec/06-grpc/math_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..9aa88acfeb86a68b0d96e29fd1b0e1a58cea7cec
--- /dev/null
+++ b/lec/06-grpc/math_pb2_grpc.py
@@ -0,0 +1,147 @@
+# 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 math_pb2 as math__pb2
+
+GRPC_GENERATED_VERSION = '1.70.0'
+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 math_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 CalcStub(object):
+    """PART 2: specify RPC calls (gprc services)
+
+    """
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Mult = channel.unary_unary(
+                '/Calc/Mult',
+                request_serializer=math__pb2.MultReq.SerializeToString,
+                response_deserializer=math__pb2.MultResp.FromString,
+                _registered_method=True)
+        self.MultMany = channel.unary_unary(
+                '/Calc/MultMany',
+                request_serializer=math__pb2.MultManyReq.SerializeToString,
+                response_deserializer=math__pb2.MultResp.FromString,
+                _registered_method=True)
+
+
+class CalcServicer(object):
+    """PART 2: specify RPC calls (gprc services)
+
+    """
+
+    def Mult(self, request, context):
+        """rpc FUNC_NAME(ARGS) returns (RESULT);
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def MultMany(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_CalcServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Mult': grpc.unary_unary_rpc_method_handler(
+                    servicer.Mult,
+                    request_deserializer=math__pb2.MultReq.FromString,
+                    response_serializer=math__pb2.MultResp.SerializeToString,
+            ),
+            'MultMany': grpc.unary_unary_rpc_method_handler(
+                    servicer.MultMany,
+                    request_deserializer=math__pb2.MultManyReq.FromString,
+                    response_serializer=math__pb2.MultResp.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'Calc', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+    server.add_registered_method_handlers('Calc', rpc_method_handlers)
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Calc(object):
+    """PART 2: specify RPC calls (gprc services)
+
+    """
+
+    @staticmethod
+    def Mult(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,
+            '/Calc/Mult',
+            math__pb2.MultReq.SerializeToString,
+            math__pb2.MultResp.FromString,
+            options,
+            channel_credentials,
+            insecure,
+            call_credentials,
+            compression,
+            wait_for_ready,
+            timeout,
+            metadata,
+            _registered_method=True)
+
+    @staticmethod
+    def MultMany(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,
+            '/Calc/MultMany',
+            math__pb2.MultManyReq.SerializeToString,
+            math__pb2.MultResp.FromString,
+            options,
+            channel_credentials,
+            insecure,
+            call_credentials,
+            compression,
+            wait_for_ready,
+            timeout,
+            metadata,
+            _registered_method=True)
diff --git a/lec/06-grpc/server.py b/lec/06-grpc/server.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e0341d525a1b1b419941d1c6905f6d1ec4afb86
--- /dev/null
+++ b/lec/06-grpc/server.py
@@ -0,0 +1,25 @@
+import grpc
+import math_pb2_grpc, math_pb2
+from concurrent import futures
+
+class Calculator(math_pb2_grpc.CalcServicer):
+    def Mult(self, request, context):
+        print("in mult")
+        result = request.x * request.y
+        return math_pb2.MultResp(result=result)
+
+    def MultMany(self, request, context):
+        print("in MultMany")
+        result = 1
+        for num in request.nums:
+            result *= num
+        return math_pb2.MultResp(result=result)
+
+print("start server")
+server = grpc.server(futures.ThreadPoolExecutor(max_workers=1), options=[("grpc.so_reuseport", 0)])
+
+math_pb2_grpc.add_CalcServicer_to_server(Calculator(), server)
+
+server.add_insecure_port("0.0.0.0:5440")
+server.start()
+server.wait_for_termination()