Skip to content

Commit 1122993

Browse files
authored
Merge pull request lf-lang#223 from lf-lang/docker-docs
Updated Docker docs
2 parents 6c94b90 + 359370e commit 1122993

File tree

1 file changed

+33
-43
lines changed

1 file changed

+33
-43
lines changed

docs/reference/containerized-execution.mdx

+33-43
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,34 @@ title: Containerized Execution
33
description: Containerized Execution using Docker
44
---
55

6-
For the `C` target at least, the Lingua Franca code generator is able to generate a Dockerfile when it generates the C source files. To enable this, include the `docker` property in your target specification, as follows:
6+
The `C`, `Python`, and `TypeScript` target support the generation of a Dockerfile to conveniently run the generated code in a container. To enable this feature, include the `docker` property in your target specification, as follows:
77

88
```lf-c
99
target C {
1010
docker: true
11-
};
11+
}
1212
```
1313

1414
The generated Docker file has the same name as the LF file except that the extension is `.Dockerfile` and will be put in the `src-gen` directory. You can also specify options. Currently, only the base image (`FROM`) can be customized, but this will be extended to allow further customization is the future. To customize the Docker file, instead of just `true` above, which gives default options, specify the options as in the following example:
1515

1616
```lf-c
1717
target C {
1818
docker: {FROM: "alpine:latest"}
19-
};
19+
}
2020
```
2121

2222
This specifies that the base image is the latest version of `alpine`, a very small Linux. In fact, `alpine:latest` is the default value for this option, so you only need to specify this option if you need something other than `alpine:latest`.
2323

2424
How to use this depends on whether your application is federated. You will need to [install Docker](https://docs.docker.com/get-docker/) if you haven't already in order to use this.
2525

2626
## Unfederated Execution
27+
Suppose your LF source file is `src/Foo.lf`. When you run `lfc` or use the IDE to generate code, a file called `Dockerfile` and a file called `docker-compose.yml` will appear in the `src_gen/Foo` directory, see [Structure of an LF project](/docs/handbook/a-first-reactor#structure-of-an-lf-project) for more info.
2728

28-
### Using docker build and docker run
29+
### Using docker compose up
30+
After running `lfc`, change to the directory that contains the generated sources. Then, use `docker compose up --build` to automatically build the Docker image and run the container. Once the container finishes execution, use `docker compose down` in the same directory where `docker-compose.yml` is located to remove the container.
2931

30-
Suppose your LF source file is `src/Foo.lf`. When you run `lfc` or use the IDE to generate code, a file called `Dockerfile` will appear in the `src_gen/Foo` directory, see [Structure of an LF project](<../writing-reactors/a-first-reactor.mdx#structure-of-an-lf-project>) for more info. You can build a Docker image as follows. First, navigate into the directory where `Dockerfile` is located. Then issue the command:
32+
### Using docker build and docker run
33+
You can also build the image and run the container in separate steps. Again, make sure that you have changed directory to the location of the `Dockerfile`. Then issue the command:
3134

3235
```sh
3336
docker build -t foo .
@@ -38,7 +41,7 @@ This will create a Docker image with tag `foo`. The tag is required to be all lo
3841
You can then use this tag to run the image in a container:
3942

4043
```sh
41-
docker run -t --rm foo
44+
docker run -t --rm foo
4245
```
4346

4447
The `-t` option creates a pseudo terminal, which is necessary for you to see any output produced by your program to `stdout`. If your program also reads from `stdin`, then you will need to give the `-i` option as well, or combine the two as `it`.
@@ -53,64 +56,51 @@ The above run command can include any supported command-line arguments to the LF
5356
docker run -t --rm foo --timeout 20 sec
5457
```
5558

56-
### Using docker compose up
57-
58-
When you use `lfc` to compile `Foo.lf`, a file called `docker-compose.yml` will also appear in the same directory where `Foo.Dockerfile` is located. `cd` to that directory. Then, use `docker compose up` to automatically build and run the container. Once the container finishes execution, use `docker compose down` in the same directory where `docker-compose.yml` is located to remove the container.
59-
6059
## Federated Execution
60+
Suppose your LF source file is `src/Fed.lf`. When you run `lfc` or use the IDE to generate code, a file called `Dockerfile` is created for each federate alongside its sources. Just like in the unfederated case, a single `docker-compose.yml` will appear in the `src_gen/Fed` directory, see [Structure of an LF project](/docs/handbook/a-first-reactor#structure-of-an-lf-project) for more info.
6161

62-
### Using docker build and docker run
63-
64-
For a federated Lingua Franca program, one Dockerfile is created for each federate plus an additional one for the RTI. The Dockerfile for the RTI will be generated at `src-gen/RTI`. You will need to run `docker build` for each of these. For example, to build the image for the RTI, you can do this:
65-
62+
### Using docker compose up
63+
Change directory to where the `docker-compose.yml` is located, and simply run:
6664
```sh
67-
docker build -t distributedcountcontainerized_rti -f src-gen/DistributedCountContainerized_RTI.Dockerfile .
65+
docker compose up --build
6866
```
67+
This will build images for all the federates (and the RTI, which is pulled from [Docker Hub](https://hub.docker.com/r/lflang/rti)), and run them on jointly on a shared network.
6968

70-
This is for the [DistributedCountContainerized.lf](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/docker/federated/DistributedCountContainerized.lf), a federated that automatically runs in multiple Docker containers (one for the RTI and one for each federate) in continuous integration.
69+
### Using docker build and docker run
70+
You can also build the images and run the containers in separate steps, for each container individually.
7171

72-
Now, there are several options for how to proceed. One is to create a named network on which to run your federation. For example, to create a network named `lf`, do this:
72+
To build a particular federate that we assume is called `foo`, change directory to `src-gen/Fed/federate__foo` (there should be a `Dockerfile` in this directory). Then issue the command:
7373

7474
```sh
75-
docker network create lf
75+
docker build -t foo .
7676
```
7777

78-
You can then run the RTI on this network and assign the RTI a name that the federates can use to find the RTI:
78+
Assuming there is one more federate in the program that is called `bar`, change directory to `src-gen/Fed/federate__bar` and run:
7979

8080
```sh
81-
docker run -t --rm --network lf --name distributedcount-rti distributedcount_rti
81+
docker build -t bar .
8282
```
8383

84-
Here, the assigned name is not quite the same as the tag that was specified when building the image (the last argument is the tag of the image to run in a container) because a host name is not allowed to have an underscore in it.
85-
86-
Currently, you will also have to specify this host name in the LF source file so that the federates know where to find the RTI. E.g., in [DistributedCount.lf](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/federated/DistributedCount.lf), change the end of the file to read as follows:
87-
88-
```lf
89-
federated reactor DistributedCount at distributedcount-rti {
90-
c = new Count();
91-
p = new Print();
92-
c.out -> p.in after 200 msec;
93-
}
84+
To pull the RTI from DockerHub, run this command:
85+
```sh
86+
docker pull lflang/rti:rti
9487
```
95-
96-
Notice the `at distributedcount-rti`, which must match the name you use when running the RTI. **FIXME:** We should find a way to make this more automatic!
97-
98-
In two other terminals, you can now run the other federates on the same network:
88+
Now, create a named network on which to run your federation. For example, to create a network named `lf`, do this:
9989

10090
```sh
101-
docker run -t --rm --network lf distributedcount_c
91+
docker network create lf
10292
```
10393

104-
and
94+
You can then launch the RTI on this network (do this in a separate terminal):
10595

10696
```sh
107-
docker run -t --rm --network lf distributedcount_p
97+
docker run -t --rm --name rti --network lf lflang/rti:rti -n 2 -i 1234
10898
```
10999

110-
### Using docker compose up
111-
112-
For a federated Lingua Franca program, once you use `lfc` to compile `Foo.lf`, on top of the `docker-compose.yml` for the reactors, an additional `docker-compose.yml` will be generated for the RTI and placed in `src-gen/RTI`.
100+
Here, the `-n 2` indicates that the total number of federates is two and `-i 1234` assigns an identifier for the federation.
113101

114-
To run the federated program, open two terminals. In the first terminal, go to `src-gen/RTI` and use `docker compose up` to build and run the containerized RTI. Wait until the RTI is booted up. Then, open a second terminal and `cd` to the top level folder of the program (this is the folder that contains one folder for each of the federated reactors). You should see a `docker-compose.yml` there. Run `docker compose up` to build and run the containers.
115-
116-
Once the program finished executing, run `docker compose down` in both the folder that contains the `docker-compose.yml` for the RTI as well as the folder that contains the `docker-compose.yml` for the reactors to remove the containers.
102+
The federates `foo` and `bar`, the images of which have already been built, can be started using the following commands:
103+
```sh
104+
docker run -t --rm --network lf foo
105+
docker run -t --rm --network lf bar
106+
```

0 commit comments

Comments
 (0)