Skip to content

Commit 9fd45f6

Browse files
authored
[PC-1031] Portenta X8: Create and Upload a Custom Container to the Portenta X8 Redefinition (#357)
* Initial commit - Tutorial content minor update * Tutorial content title update (Pending Suggestion) * Tutorial content title readjustment * Tutorial content update * Tutorial content update * Tutorial content update (Added Docker Hub Upload Section WIP) * Tutorial content minor update
1 parent c7c8f86 commit 9fd45f6

File tree

1 file changed

+52
-28
lines changed
  • content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container

1 file changed

+52
-28
lines changed

content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/content.md

+52-28
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: Create and Upload a Custom Container to the Portenta X8
2+
title: 'Create & Upload a Custom Container with Portenta X8 Manager'
33
difficulty: intermediate
44
tags: [Linux, Python®, Containers, ADB]
5-
description: This tutorial will show you how to create and upload your custom container to your Portenta X8
6-
author: Benjamin Dannegård
5+
description: 'This tutorial will show you how to create and upload your custom container to your Portenta X8.'
6+
author: 'Benjamin Dannegård'
77
hardware:
88
- hardware/04.pro/boards/portenta-x8
99
software:
@@ -12,7 +12,7 @@ software:
1212

1313
## Overview
1414

15-
In this tutorial we will create a simple container that we can then upload to the Arduino Portenta X8. A container consists of an image file and all it's dependencies if there are any. This tutorial will go through the different files needed to create a container and their functions. Building this container locally and then uploading it to a Portenta X8. Using docker with ADB to build, run and attach our container to the Portenta X8.
15+
In this tutorial, we will create a simple container and upload it to the Arduino Portenta X8 with its manager. A container consists of an image file and all its dependencies if required. This tutorial will go through the needed files to create a container and its functions. Building this container locally and then uploading it to a Portenta X8. Using docker with ADB to build, run and attach our container to the Portenta X8.
1616

1717
## Goals
1818

@@ -24,16 +24,17 @@ In this tutorial we will create a simple container that we can then upload to th
2424
- [Portenta X8](https://store.arduino.cc/portenta-x8)
2525
- ADB
2626
- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®)
27-
- Arduino Pro Cloud Subscription. [Learn more about the Pro Cloud](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud).
28-
27+
- Arduino Pro Cloud Subscription [Learn more about the Pro Cloud](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud)
28+
- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor)
2929

3030
## Instructions
3131

32-
When running a container, it uses an isolated filesystem. This custom filesystem is provided by a container image. Since the image contains the container’s filesystem, it must contain everything needed to run an application - all dependencies, configuration, scripts, binaries, etc. The image also contains other configuration for the container, such as environment variables, a default command to run, and other metadata.
32+
An active container uses an isolated filesystem. The container image provides its custom filesystem. Since the image contains the container’s filesystem, it must have everything required to run an application - all dependencies, configuration, scripts, binaries, etc. The image also contains further configurations for the container, such as environment variables, a default command to run, and other metadata.
3333

3434
## Container File Structure
3535

36-
To create our container we need to collect our necessary files. Creating a folder called **x8-custom-test**, the following files needs to be in the folder:
36+
To create the container, we need to collect the necessary files. Creating a folder called **x8-custom-test**, the following files need to be in the folder:
37+
3738
- docker-build.conf
3839
- docker-compose.yml
3940
- Dockerfile
@@ -45,17 +46,18 @@ The complete folder will look like this:
4546

4647
![Folder structure for container](assets/custom-container-folder.png)
4748

48-
Lets go through what these files contain and do.
49+
Let us go through what these files contain and do.
50+
51+
### Container File: Docker-build.conf
4952

50-
### Docker-build.conf
51-
A file containing the minimal "unit test" command to be executed on the container to prove it's working. Our file will make our containers minimal unit test a test of Python3 help command.
53+
A file containing the minimal "unit test" command is to be executed on the container to prove it's working. Our file will make our containers minimal unit test a test of the Python3 help command.
5254

5355
```python
5456
TEST_CMD="python3 --help"
5557
```
5658

57-
### Docker-compose.yml
58-
This file defines the app name through the Factory, permissions and settings for the involved containers. The argument in the image tag will make it so our image file builds locally.
59+
### Container File: Docker-compose.yml
60+
This file defines the app name through the Factory, permissions, and settings for the involved containers. The argument in the image tag will make it, so our image file builds locally.
5961

6062
```python
6163
version: '3.6'
@@ -74,8 +76,9 @@ services:
7476
- /tmp
7577
```
7678

77-
### Dockerfile
78-
This is used to build the container.
79+
### Container File: Dockerfile
80+
81+
This is used to build the container. A Dockerfile is a text file that contains all the instructions (FROM, COPY, COMMAND, ENTRYPOINT, etc.) that a user can use from the command line to create different image layers. Although the final image can be created using the docker `build` command, the dockerfile serves just as an image definition.
7982

8083
```python
8184
FROM python:3-alpine3.15
@@ -99,14 +102,17 @@ ENV UDEV=1
99102
CMD ["python","-u","main.py"]
100103
```
101104

102-
### Requirements.txt
105+
### Container File: Requirements.txt
106+
107+
The requirements text file defines needed dependencies. These dependencies serves as useful tools to build the application of the container.
103108

104109
```python
105110
Flask==0.12.3
106111
```
107112

108-
### Source
109-
Here we will keep source code of the app you want to run in the container or a startup script. We will create a file and name it **main.py** in this folder. This script will print "Hello World!" in the CLI window.
113+
### Container File: Source
114+
115+
Here we will keep the source code of the app you want to run in the container or a startup script. We will create a **main.py** file in this folder. This script will print "Hello World!" in the CLI window.
110116

111117
```python
112118
from flask import Flask
@@ -122,17 +128,17 @@ if __name__ == '__main__':
122128

123129
## Uploading the Container Folder
124130

125-
First, you have to have set up your board to a Factory, as shown in the [Portenta X8 Out of the Box tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box).
131+
First, you will need to set up your board to a Factory setting, as shown in the [Portenta X8 Out of the Box tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box).
126132

127-
Once this is done, we will push our folder to a repository within the Factory. Lets place our folder "x8-custom-test" inside the "containers.git" repository. You can find this repository inside your Factory page, if you click on "Source". And then on "container.git", the url of this page will be used in the next command.
133+
Once finished, we will push our folder to a repository within the Factory. Let us place our folder "x8-custom-test" inside the "containers.git" repository. You can find this repository inside your Factory page under "Source". Then, on "container.git", the page URL will be used in the following command.
128134

129135
![Source on Foundries.io Factory page](assets/custom-factory-page.png)
130136

131137
![Where to find container.git](assets/custom-factory-git.png)
132138

133139
![Container.git page](assets/custom-git.png)
134140

135-
In order to pull or push repositories you have to generate an API key. This can be done by going to the user settings on the Factory page. First click on the user drop-down menu, then go into the tokens page and follow the steps of creating a new API key. When creating the API key make sure you select the "Use for source code access" option and the correct factory that you want to use the key for. This token will be used as the password for all git operations while the username can be anything, except an empty string.
141+
To pull or push repositories, you have to generate an API key. This is done by going to the user settings on the Factory page. Click on the user drop-down menu, go into the tokens page and follow the steps of creating a new API key. When creating the API key, please make sure to select the "Use for source code access" option and the correct Factory that you want to use the key for. This token will be used as the password for all git operations while the username can be anything, except an empty string.
136142

137143
![User settings on your Factory page](assets/factory-user-settings.png)
138144

@@ -144,31 +150,31 @@ Use the following command in git on your machine. To get the repository on your
144150
git clone https://source.foundries.io/factories/YOUR_FACTORY/containers.git -b devel
145151
```
146152

147-
Put the "x8-custom-test" folder in the repository and push it with git. When you have put the folder into the git folder, use `git status` to see the changed files in the folder, it will show the unadded changes in red, then use `git add` to add the changes you want to your git commit. Then use `git commit` and `git push` to finally push the changes to the repo. If you push the commit to "containers.git" a new target will automatically build on your FoundriesFactory, you can inspect it in the "Targets" page.
153+
Put the "x8-custom-test" folder in the repository and push it with git. When you have put the folder into the git folder, use `git status` to see the changed files in the folder, it will show the unadded changes in red, then use `git add` to add the changes you want to your git commit. Then use `git commit` and `git push` to finally push the changes to the repo. If you push the commit to "containers.git" a new target will automatically build on your FoundriesFactory, you can inspect it on the "Targets" page.
148154

149155
### Building and Running the Container
150156

151-
After the build is finished, it can take up to 10 minutes for your device to OTA update to this new version. You can inspect it via the "Devices" tab of your FoundriesFactory. After your device takes the update, navigate into the "x8-custom-test" folder, that should be located on your board now. This allows us to build our container with a simple command. Using ```docker build``` with a ```--tag``` will let us give the container a tag so we can easily keep track of what version of the build this is.
157+
After the build finishes, it can take up to 10 minutes for your device to update over-the-air to this new version. You can inspect it via the "Devices" tab of your FoundriesFactory. After your device takes the update, navigate into the "x8-custom-test" folder, which should be located on your board now. This allows us to build our container with a simple command. Using ```docker build``` with a ```--tag``` will let us give the container a tag so we can easily keep track of what version of the build this is.
152158

153159
```python
154160
docker build --tag "x8-custom-test:latest" .
155161
```
156162

157-
Now that it is built we can run it with ```docker run```, finding it with the tag that we chose to give to the build we want to run. Here we will have to enter the user information into the --user tag. This information is found inside the "docker-compose.yml" file.
163+
Now that it is built, we can run it with ```docker run```, finding it with the tag that we chose to give to the build we want to run. Here we need to enter the user information into the --user tag. This information is found inside the "docker-compose.yml" file.
158164

159165
```python
160166
docker run -it --rm --user "63" x8-custom-test:latest
161167
```
162168

163169
### Using Docker-Compose
164170

165-
A option for testing an app or container is to use "docker-compose". This is helpful when we have a lot of settings in our "docker-compose.yml" file, since we don't have to use those settings in the run argument with this method. First navigate into the container folder.
171+
An option for testing an app or container is to use "docker-compose". It is helpful when we have a lot of settings in our "docker-compose.yml" file since we don't have to use those settings in the run argument with this method. First, navigate into the container folder.
166172

167173
```python
168174
cd /home/fio/x8-custom-test
169175
```
170176

171-
This docker-compose command will start your application and register it as a systemd service that will persist even when a reboot occurs. So at the next boot your docker-compose app will run automatically.
177+
This docker-compose command will start your application and register it as a systemd service that will persist even when a reboot occurs. So at the next boot, your docker-compose app will run automatically.
172178

173179
```python
174180
docker-compose up --detach
@@ -180,15 +186,33 @@ To stop the docker-compose app from running, use the following command:
180186
docker-compose stop
181187
```
182188

189+
## Deploying with Docker Hub
190+
191+
An alternative method to deploy the custom container is by using the Docker Hub platform. For this, it needs a [Docker Hub account](https://hub.docker.com/) to have your own repository to have the custom container uploaded. When you have the repository ready, the following command will let you upload the custom container image.
192+
193+
```
194+
docker push HUB_USERNAME/x8-custom-test
195+
```
196+
197+
The custom container image can now be found within `HUB_USERNAME` Docker Hub repository. The image can be accessed whenever any connectivity type grants access to the container image. To pull the image and deploy the container, you will need to connect the Portenta X8 via ADB and use following commands in sequence:
198+
199+
```
200+
adb shell
201+
docker pull x8-custom-test
202+
```
203+
204+
It will pull the container image and deploy the container on your Portenta X8.
205+
206+
***To know more about how to create and manage repositories on Docker Hub to manage your custom containers for Portenta X8, check out [here](https://docs.docker.com/docker-hub/repos/#:~:text=To%20push%20an%20image%20to,docs%2Fbase%3Atesting%20).)***
207+
183208
## Conclusion
184209

185-
This tutorial went through what goes into a container, how the folder should be built and what files it should contain. It then explained what each files purpose is and what they should contain for this example. Then we went through how this relates back to the Factory, and how Foundries.io makes the whole process easier for us. We then showed how to build the container and run it on the Portenta X8. Lastly, we showed a useful testing feature with docker-compose. Which lets us test our container with a faster process.
210+
This tutorial covered what goes into a container, how the folder should be structured, and what files it should contain. It then explained the purpose of each file and what they should have for this example. Then we went through how this relates to the Factory, and how Foundries.io makes the whole process easier for us. We then showed how to build the container and run it on the Portenta X8. Lastly, we showed a useful testing feature with docker-compose, letting us test our container with a faster process.
186211

187212
### Next Steps
188213

189214
To get a better understanding of how to manage containers with Docker, take a look at our [Managing Containers with Docker on Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/docker-container). This tutorial will show some useful commands to use with the docker service and ADB or SSH.
190215

191-
192216
## Troubleshooting
193217

194218
Here are some errors that might occur in the process of this tutorial:

0 commit comments

Comments
 (0)