Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(docker) Add ServerApps docs #3439

Merged
merged 6 commits into from
May 16, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 70 additions & 84 deletions doc/source/how-to-run-flower-using-docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ was not found, you will need to install Docker first. You can find installation
you can follow the `Post-installation steps <https://docs.docker.com/engine/install/linux-postinstall/>`_
on the official Docker website.

.. important::

To ensure optimal performance and compatibility, the SuperLink, SuperNode and ServerApp image
must have the same version when running together. This guarantees seamless integration and
avoids potential conflicts or issues that may arise from using different versions.

Flower SuperLink
----------------

Expand Down Expand Up @@ -52,7 +58,7 @@ to the Flower SuperLink. Here, we are passing the flag ``--insecure``.

The ``--insecure`` flag enables insecure communication (using HTTP, not HTTPS) and should only be
used for testing purposes. We strongly recommend enabling
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`_
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`__
when deploying to a production environment.

You can use ``--help`` to view all available flags that the SuperLink supports:
Expand All @@ -66,14 +72,14 @@ Mounting a volume to store the state on the host system

If you want to persist the state of the SuperLink on your host system, all you need to do is specify
a path where you want to save the file on your host system and a name for the database file. In the
example below, we tell Docker via the flag ``-v`` to mount the user's home directory
example below, we tell Docker via the flag ``--volume`` to mount the user's home directory
(``~/`` on your host) into the ``/app/`` directory of the container. Furthermore, we use the
flag ``--database`` to specify the name of the database file.

.. code-block:: bash

$ docker run --rm \
-p 9091:9091 -p 9092:9092 -v ~/:/app/ flwr/superlink:1.8.0 \
-p 9091:9091 -p 9092:9092 --volume ~/:/app/ flwr/superlink:1.8.0 \
--insecure \
--database state.db

Expand All @@ -89,18 +95,18 @@ PEM-encoded certificate chain.

.. note::
For testing purposes, you can generate your own self-signed certificates. The
`Enable SSL connections <https://flower.ai/docs/framework/how-to-enable-ssl-connections.html#certificates>`_
`Enable SSL connections <https://flower.ai/docs/framework/how-to-enable-ssl-connections.html#certificates>`__
page contains a section that will guide you through the process.

Assuming all files we need are in the local ``certificates`` directory, we can use the flag
``-v`` to mount the local directory into the ``/app/`` directory of the container. This allows the
SuperLink to access the files within the container. Finally, we pass the names of the certificates
to the SuperLink with the ``--certificates`` flag.
``--volume`` to mount the local directory into the ``/app/`` directory of the container. This allows
the SuperLink to access the files within the container. Finally, we pass the names of the
certificates to the SuperLink with the ``--certificates`` flag.

.. code-block:: bash

$ docker run --rm \
-p 9091:9091 -p 9092:9092 -v ./certificates/:/app/ flwr/superlink:1.8.0 \
-p 9091:9091 -p 9092:9092 --volume ./certificates/:/app/ flwr/superlink:1.8.0 \
--certificates ca.crt server.pem server.key

Flower SuperNode
Expand All @@ -117,7 +123,7 @@ building your own SuperNode image.
day. To ensure the versions are in sync, using the concrete tag, e.g., ``1.9.0.dev20240501``
instead of ``nightly`` is recommended.

We will use the ``app-pytorch`` example, which you can find in
We will use the ``quickstart-pytorch`` example, which you can find in
the Flower repository, to illustrate how you can dockerize your client-app.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename client-app > ClientApp for consistency.


.. _SuperNode Prerequisites:
Expand All @@ -126,14 +132,14 @@ Prerequisites
~~~~~~~~~~~~~

Before we can start, we need to meet a few prerequisites in our local development environment.
You can skip the first part if you want to run your client-app instead of the ``app-pytorch``
You can skip the first part if you want to run your client-app instead of the ``quickstart-pytorch``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename client-app > ClientApp for consistency.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

example.

#. Clone the flower repository.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flower > Flower


.. code-block:: bash

$ git clone https://github.com/adap/flower.git && cd flower/examples/app-pytorch
$ git clone https://github.com/adap/flower.git && cd flower/examples/quickstart-pytorch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- git clone https://github.com/adap/flower.git && cd flower/examples/quickstart-pytorch
+ git clone --depth=1 https://github.com/adap/flower.git && cd flower/examples/quickstart-pytorch


#. Verify the Docker daemon is running.

Expand All @@ -152,13 +158,26 @@ Let's assume the following project layout:
$ tree .
.
├── client.py # ClientApp code
├── task.py # ClientApp code
├── requirements.txt # ClientApp dependencies
└── <other files>

First, we need to create a Dockerfile in the directory where the ``ClientApp`` code is located.
If you use the ``app-pytorch`` example, create a new file called ``Dockerfile.supernode`` in
``examples/app-pytorch``.
First, we need to create a ``requirements.txt`` file in the directory where the ``ClientApp`` code
is located. In the file, we list all the dependencies that the ClientApp requires.

.. code-block::

flwr-datasets[vision]>=0.0.2,<1.0.0
torch==2.1.1
torchvision==0.16.1
tqdm==4.66.3

.. important::

Note that `flwr <https://pypi.org/project/flwr/>`__ is already installed in the ``flwr/supernode``
base image, so you only need to include other package dependencies in your requirements.txt,
such as torch, tensorflow, etc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... in your requirements.txt such as torch, tensorflow, etc.


Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` example, create a new
file called ``Dockerfile.supernode`` in ``examples/quickstart-pytorch``.

The ``Dockerfile.supernode`` contains the instructions that assemble the SuperNode image.

Expand All @@ -167,34 +186,20 @@ The ``Dockerfile.supernode`` contains the instructions that assemble the SuperNo
FROM flwr/supernode:nightly

WORKDIR /app

COPY requirements.txt .
RUN python -m pip install -U --no-cache-dir -r requirements.txt && pyenv rehash

COPY client.py task.py ./
ENTRYPOINT ["flower-client-app"]
COPY client.py ./
ENTRYPOINT ["flower-client-app", "client:app"]

In the first two lines, we instruct Docker to use the SuperNode image tagged ``nightly`` as a base
image and set our working directory to ``/app``. The following instructions will now be
executed in the ``/app`` directory. Next, we install the ClientApp dependencies by copying the
``requirements.txt`` file into the image and run ``pip install``. In the last two lines,
we copy the ClientApp code (``client.py`` and ``task.py``) into the image and set the entry
point to ``flower-client-app``.

.. important::

If the requirement.txt contains the `flwr <https://pypi.org/project/flwr/>`__ or
`flwr-nightly <https://pypi.org/project/flwr-nightly/>`_ package, please ensure the version in
requirement.txt matches the docker image version.

Stable:

- Docker image: ``supernode:1.9.0``
- requirement.txt: ``flwr[simulation]==1.9.0``

Nightly:

- Docker image: ``supernode:1.9.0.dev20240501``
- requirement.txt: ``flwr-nightly[simulation]==1.9.0.dev20240501``
we copy the ClientApp code into the image and set the entry point to ``flower-client-app`` with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we copy the client.py module into the image ...

the argument ``client:app``. The argument is the object reference of the ClientApp
(``<module>:<attribute>``) that will be run inside the ClientApp.

Building the SuperNode Docker image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -226,55 +231,55 @@ Let's break down each part of this command:
* ``docker run``: This is the command to run a new Docker container.
* ``--rm``: This option specifies that the container should be automatically removed when it stops.
* ``flwr_supernode:0.0.1``: The name the tag of the Docker image to use.
* | ``client:app``: The object reference of the ``ClientApp`` (``<module>:<attribute>``).
| It points to the ``ClientApp`` that will be run inside the SuperNode container.
* ``--insecure``: This option enables insecure communication.

.. attention::

The ``--insecure`` flag enables insecure communication (using HTTP, not HTTPS) and should only be
used for testing purposes. We strongly recommend enabling
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`_
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`__
when deploying to a production environment.

* | ``--server 192.168.1.100:9092``: This option specifies the address of the SuperLinks Fleet
| API to connect to. Remember to update it with your SuperLink IP.

.. note::

Any argument that comes after the tag is passed to the Flower SuperNode binary.
To see all available flags that the SuperNode supports, run:
To test running Flower locally, you can create a
`bridge network <https://docs.docker.com/network/network-tutorial-standalone/#use-user-defined-bridge-networks>`__,
use the ``--network`` argument and pass the name of the Docker network to run your SuperNodes.

.. code-block:: bash
Any argument that comes after the tag is passed to the Flower SuperNode binary.
To see all available flags that the SuperNode supports, run:

.. code-block:: bash

$ docker run --rm flwr/supernode:nightly --help
$ docker run --rm flwr/supernode:nightly --help

Enabling SSL for secure connections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To enable SSL, we will need to mount a PEM-encoded root certificate into your SuperNode container.

Assuming the certificate already exists locally, we can use the flag ``-v`` to mount the local
Assuming the certificate already exists locally, we can use the flag ``--volume`` to mount the local
certificate into the container's ``/app/`` directory. This allows the SuperNode to access the
certificate within the container. Use the ``--certificates`` flag when starting the container.

.. code-block:: bash

$ docker run --rm -v ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 client:app \
$ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 client:app \
--server 192.168.1.100:9092 \
--certificates ca.crt

Flower ServerApp
----------------

The procedure for building and running a ServerApp image is almost identical to the SuperNode image.
A key difference is the additional argument in the ``ENTRYPOINT`` command of the ServerApp
Dockerfile.

Similar to the SuperNode image, the ServerApp Docker image comes with a pre-installed version of
Flower and serves as a base for building your own ServerApp image.

We will use the same ``app-pytorch`` example as we do in the Flower SuperNode section.
We will use the same ``quickstart-pytorch`` example as we do in the Flower SuperNode section.
If you have not already done so, please follow the `SuperNode Prerequisites`_ before proceeding.


Expand All @@ -288,13 +293,11 @@ Let's assume the following project layout:
$ tree .
.
├── server.py # ServerApp code
├── task.py # ServerApp code
├── requirements.txt # ServerApp dependencies
└── <other files>

First, we need to create a Dockerfile in the directory where the ``ServerApp`` code is located.
If you use the ``app-pytorch`` example, create a new file called ``Dockerfile.serverapp`` in
``examples/app-pytorch``.
If you use the ``quickstart-pytorch`` example, create a new file called ``Dockerfile.serverapp`` in
``examples/quickstart-pytorch``.

The ``Dockerfile.serverapp`` contains the instructions that assemble the ServerApp image.

Expand All @@ -303,36 +306,16 @@ The ``Dockerfile.serverapp`` contains the instructions that assemble the ServerA
FROM flwr/serverapp:1.8.0
chongshenng marked this conversation as resolved.
Show resolved Hide resolved

WORKDIR /app
COPY requirements.txt .
RUN python -m pip install -U --no-cache-dir -r requirements.txt && pyenv rehash

COPY server.py task.py ./
COPY server.py ./
ENTRYPOINT ["flower-server-app", "server:app"]
chongshenng marked this conversation as resolved.
Show resolved Hide resolved

In the first two lines, we instruct Docker to use the ServerApp image tagged ``1.8.0`` as a base
chongshenng marked this conversation as resolved.
Show resolved Hide resolved
image and set our working directory to ``/app``. The following instructions will now be
executed in the ``/app`` directory. Next, we install the ServerApp dependencies by copying the
``requirements.txt`` file into the image and run ``pip install``. In the last two lines,
we copy the ServerApp code (``server.py`` and ``task.py``) into the image and set the entry
point to ``flower-server-app`` with the argument ``server:app``. The argument is the object
reference of the ServerApp (``<module>:<attribute>``) that will be run inside the ServerApp
container.

.. important::

If the requirement.txt contains the `flwr <https://pypi.org/project/flwr/>`__ or
`flwr-nightly <https://pypi.org/project/flwr-nightly/>`_ package, please ensure the version in
requirement.txt matches the docker image version.

Stable:

- Docker image: ``serverapp:1.8.0``
- requirement.txt: ``flwr[simulation]==1.8.0``

Nightly:

- Docker image: ``serverapp:1.9.0.dev20240501``
- requirement.txt: ``flwr-nightly[simulation]==1.9.0.dev20240501``
executed in the ``/app`` directory. In the last two lines, we copy the ServerApp code into the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

..., we copy the ServerApp module into the ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we call it ServerApp or server.py to be consistent with change above?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right @Robert-Steiner! Let's stick to server.py.

..., we copy the server.py module into the ...

image and set the entry point to ``flower-server-app`` with the argument ``server:app``.
The argument is the object reference of the ServerApp (``<module>:<attribute>``) that will be run
inside the ServerApp container.

Building the ServerApp Docker image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -370,33 +353,36 @@ Let's break down each part of this command:

The ``--insecure`` flag enables insecure communication (using HTTP, not HTTPS) and should only be
used for testing purposes. We strongly recommend enabling
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`_
`SSL <https://flower.ai/docs/framework/how-to-run-flower-using-docker.html#enabling-ssl-for-secure-connections>`__
when deploying to a production environment.

* | ``--server 192.168.1.100:9091``: This option specifies the address of the SuperLinks Driver
| API to connect to. Remember to update it with your SuperLink IP.

.. note::
To test running Flower locally, you can create a
`bridge network <https://docs.docker.com/network/network-tutorial-standalone/#use-user-defined-bridge-networks>`__,
use the ``--network`` argument and pass the name of the Docker network to run your ServerApps.

Any argument that comes after the tag is passed to the Flower ServerApp binary.
To see all available flags that the ServerApp supports, run:
Any argument that comes after the tag is passed to the Flower ServerApp binary.
To see all available flags that the ServerApp supports, run:

.. code-block:: bash
.. code-block:: bash

$ docker run --rm flwr/serverapp:1.8.0 --help
$ docker run --rm flwr/serverapp:1.8.0 --help

Enabling SSL for secure connections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To enable SSL, we will need to mount a PEM-encoded root certificate into your ServerApp container.

Assuming the certificate already exists locally, we can use the flag ``-v`` to mount the local
Assuming the certificate already exists locally, we can use the flag ``--volume`` to mount the local
certificate into the container's ``/app/`` directory. This allows the ServerApp to access the
certificate within the container. Use the ``--certificates`` flag when starting the container.

.. code-block:: bash

$ docker run --rm -v ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 client:app \
$ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 client:app \
--server 192.168.1.100:9091 \
--certificates ca.crt

Expand Down