Skip to content

Commit 1b2be32

Browse files
Added images
1 parent a610b5b commit 1b2be32

File tree

7 files changed

+42
-21
lines changed

7 files changed

+42
-21
lines changed
Loading
Loading

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

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
title: Create and Upload a Custom Container Portenta X8
2+
title: Create and Upload a Custom Container to the Portenta X8
33
difficulty: easy
4-
tags: [Linux, Python, Containers]
4+
tags: [Linux, Python, Containers, ADB]
55
description: This tutorial will show you how to create and upload your custom container to your Portenta X8
66
author: Benjamin Dannegård
77
hardware:
@@ -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 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.
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.
1616

1717
## Goals
1818

@@ -22,6 +22,8 @@ In this tutorial we will create a simple container that we can then upload to th
2222
### Required Hardware and Software
2323

2424
- [Portenta X8](https://store.arduino.cc/portenta-x8)
25+
- ADB
26+
- USB-C cable (either USB-C to USB-A or USB-C to USB-C)
2527

2628
## Instructions
2729

@@ -37,10 +39,14 @@ To create our container we need to collect our necessary files. Creating a folde
3739
- src folder
3840
- main.py (This file should be inside the src folder)
3941

42+
The complete folder will look like this:
43+
44+
![Folder structure for container](assets/custom-container-folder.png)
45+
4046
Lets go through what these files contain and do.
4147

4248
### docker-buil.conf
43-
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's help commmand.
49+
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.
4450

4551
```python
4652
TEST_CMD="python3 --help"
@@ -70,17 +76,8 @@ services:
7076
This is used to build the container.
7177

7278
```python
73-
# Copyright (c) 2022 Arduino.cc
74-
#
75-
76-
# Examples:
77-
# docker build --tag "hello-world:latest" .
78-
# docker run -it --rm --user "63" hello-world:latest
79-
8079
FROM python:3-alpine3.15
8180

82-
LABEL maintainer="Massimo Pennazio <maxipenna@libero.it>"
83-
8481
# Set our working directory
8582
WORKDIR /usr/src/app
8683

@@ -107,7 +104,7 @@ Flask==0.12.3
107104
```
108105

109106
### Source
110-
Here we will keep source code of the app you want to run in the container or simply 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.
107+
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.
111108

112109
```python
113110
from flask import Flask
@@ -123,21 +120,35 @@ if __name__ == '__main__':
123120

124121
## Uploading the Container Folder
125122

126-
First, you have to have set up your board to a factory, as shown in the [Portenta X8 Out of the Box tutorial]().
123+
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).
127124

128125
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.
129126

130-
In bash use the following command, replace the "YOUR_FACTORY" with the name of your factory, to get the container repository, where we will put our folder. The "-m" tag selects the manifest file within the repository. If no manifest name is selected, the default is "default.xml". And the "-b" tag specifies a revision.
127+
![Source on Foundries.io Factory page](assets/custom-factory-page.png)
128+
129+
![Where to find container.git](assets/custom-factory-git.png)
130+
131+
![Container.git page](assets/custom-git.png)
132+
133+
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. This token will be used as the password for all git operations while the username can be anything, except an empty string.
134+
135+
![User settings on your Factory page](assets/factory-user-settings.png)
136+
137+
![Token section in user settings](assets/token-page.png)
138+
139+
Use the following command in a Linux shell, like ADB which the previously mentioned tutorial showed how to set up. To get the repository on your board, replace the "YOUR_FACTORY" with the name of your factory. The "-m" tag selects the manifest file within the repository. If no manifest name is selected, the default is "default.xml". And the "-b" tag specifies a revision. Running this command will get the container repository, where we will put our folder.
131140

132141
```python
133142
repo init -u https://source.foundries.io/factories/YOUR_FACTORY/containers.git -m arduino.xml -b devel
134143
```
135144

136-
We can also run ```repo sync``` to get the latest version of the repository. Put the "x8-custom-test" folder in the repository.
145+
We can also run ```repo sync``` to get the latest version of the repository. Put the "x8-custom-test" folder in the repository. If you push the commit to "container.git" a new target will automatically build on your Foundries.io Factory page.
146+
147+
*** NOTE: The "repo sync" will at some point pause. This is because it is waiting for a username and password but the prompt will be hidden. Enter the username and password to move on. ***
137148

138149
### Building and Running the Container
139150

140-
After uploading the folder to the repository. 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 --tag will let us give the container a tag so we can easily keep track of what version of the build this is.
151+
After uploading the folder to the repository. 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.
141152

142153
```python
143154
docker build --tag "x8-custom-test:latest" .
@@ -151,14 +162,13 @@ docker run -it --rm --user "63" x8-custom-test:latest
151162

152163
### Using docker-compose
153164

154-
155165
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.
156166

157167
```python
158168
cd /home/fio/x8-custom-test
159169
```
160170

161-
This docker-compose command will start your application and register it as a systemd service that will presist even when a reboot occurs. So at the next boot your docker-compose app will run automatically.
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.
162172

163173
```python
164174
docker-compose up --detach
@@ -171,6 +181,17 @@ docker-compose stop
171181
```
172182

173183

184+
## Troubleshoot
185+
186+
Here are some errors that might occur in the process of this tutorial:
187+
188+
- Make sure you have followed our other tutorials that shows how to set up the [Portenta X8 out of the box](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box)
189+
- If you are having issues with the adb shell, don't forget to try and use `sudo` and `su`
190+
191+
### Next Steps
192+
193+
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.
194+
174195
## Conclusion
175196

176-
This tutorial went through how to create a container for a script or app using Python. And then how to upload this container to a Portenta X8. This is a good method for creating and quickly testing containers. Allowing you to make sure a container works before pushing it to your factory.
197+
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 usefull testing feature with docker-compose. Which lets us test our container with a faster process.

0 commit comments

Comments
 (0)