You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/reference/containerized-execution.mdx
+33-43
Original file line number
Diff line number
Diff line change
@@ -3,31 +3,34 @@ title: Containerized Execution
3
3
description: Containerized Execution using Docker
4
4
---
5
5
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:
7
7
8
8
```lf-c
9
9
target C {
10
10
docker: true
11
-
};
11
+
}
12
12
```
13
13
14
14
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:
15
15
16
16
```lf-c
17
17
target C {
18
18
docker: {FROM: "alpine:latest"}
19
-
};
19
+
}
20
20
```
21
21
22
22
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`.
23
23
24
24
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.
25
25
26
26
## 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.
27
28
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.
29
31
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:
31
34
32
35
```sh
33
36
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
38
41
You can then use this tag to run the image in a container:
39
42
40
43
```sh
41
-
docker run -t --rm foo
44
+
docker run -t --rm foo
42
45
```
43
46
44
47
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
53
56
docker run -t --rm foo --timeout 20 sec
54
57
```
55
58
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
-
60
59
## 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.
61
61
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:
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.
69
68
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.
71
71
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:
73
73
74
74
```sh
75
-
docker network create lf
75
+
docker build -t foo .
76
76
```
77
77
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:
79
79
80
80
```sh
81
-
docker run -t --rm --network lf --name distributedcount-rti distributedcount_rti
81
+
docker build -t bar .
82
82
```
83
83
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
94
87
```
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:
99
89
100
90
```sh
101
-
docker run -t --rm --network lf distributedcount_c
91
+
docker network create lf
102
92
```
103
93
104
-
and
94
+
You can then launch the RTI on this network (do this in a separate terminal):
105
95
106
96
```sh
107
-
docker run -t --rm --network lf distributedcount_p
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.
113
101
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:
0 commit comments