Deploy a Docker application with Greengrass

Introduction

Since I learned about AWS IoT Greengrass in my company's business, I would like to introduce Ubuntu-based devices and applications that use AWS IoT. This time, I will introduce how to deploy Docker application with Greengrass [^ gg-docker] [^ gg-blog].

Past Articles: Install AWS IoT Greengrass on Ubuntu Create a Greengrass Lambda and deploy it to an edge device (https://qiita.com/Yokogawa_Ishino/items/3ceb9029afcc7a58f2f9)

environment

Operation confirmed device (OS)

These devices work with packages of the armhf architecture. I'm also operating a device on a Windows 10 PC.

Workflow

architecture.png

  1. ** Create Docker application ** Develop a Docker application on your development PC.

  2. ** Docker image push ** Create a Docker image and push it to Amazon Elastic Container Registry (ECR).

  3. ** docker-compose upload ** Create docker-compose and upload it to Amazon Simple Storage Service (S3).

  4. ** Deploy Docker application ** Grant the required role to the Greengrass Group and deploy the Docker application to your device using the Docker application deployment connector [^ gg-docker]. The Docker container will start and the application will run.

Preparation

AWS CLI installation

** Install the AWS CLI on your PC **. Please refer to the following guide for the installation method. Install, update, and uninstall AWS CLI version 2 on Windows (https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-windows.html)

It is necessary to set it when using it for the first time. Please refer to the following guide for details. Configuration Basics-AWS Command Line Interface (https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)

Install Docker Desktop on Windows

** Install Docker Desktop on Windows on your PC. Please refer to this page for the installation method.

Install Python 3.7

** Install Python 3.7 on your device, which is required to deploy Docker applications with Greengrass.

-** For e-RT3 **

```bash
sudo apt update
sudo apt install python3.7
```

```bash
username@ubuntu:~$ python3.7 --version
Python 3.7.5
```

-** For Raspberry Pi (Ubuntu Server 20.04 32bit) ** Since it cannot be installed with apt, build it from source and install it. Install the packages required for the build.

```bash
sudo apt update
sudo apt install build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev
```

Download the Python 3.7 source from the official website and build it.

```bash
wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz
tar xvf Python-3.7.9.tar.xz
cd Python-3.7.9
./configure
make
sudo make altinstall
cd ~
```

Confirm the installation is successful.

```bash
username@ubuntu:~$ python3.7 --version
Python 3.7.9
```

install docker

** Install docker and docker-compose on your device. docker -** For e-RT3 **

To install the latest version, install according to the official documentation [^ docker-install]. Install the packages required to install docker.

```bash
sudo apt update
sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
```

Install the required packages for your credentials [^ login].

```bash
sudo apt install pass
```

Add the GPG key.

```bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

Search by the last 8 digits of the fingerprint to confirm that the key has been added.

```bash
username@ubuntu:~$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <[email protected]>
sub   rsa4096 2017-02-22 [S]
```

Add a repository.

```bash
sudo add-apt-repository \
   "deb [arch=armhf] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

Install the docker engine.

```bash
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
#Service start
sudo systemctl start docker
#Service automatic start
sudo systemctl enable docker
```

```bash
username@ubuntu:~$ docker --version
Docker version 20.10.1, build 831ebea
```

-** For Raspberry Pi (Ubuntu Server 20.04 32bit) **

There is no package for Ubuntu 20.04 armhf in the official Docker repository, so install it with docker.io.

```bash
sudo apt install docker.io
#Service start
sudo systemctl start docker
#Service automatic start
sudo systemctl enable docker
```

```bash
username@ubuntu:~$ docker --version
Docker version 19.03.8, build afacb8b7f0
```

Confirm the installation is successful. Start the container with the test image, and if the following message is displayed, it is successful.

username@ubuntu:~$ sudo docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

docker-compose Install using pip [^ docker-pip].

Install the required packages.

sudo apt update
sudo apt install libffi-dev libssl-dev python3-dev python3-venv

Create a virtual environment and install it with pip.

python3 -m venv venv
source venv/bin/activate
(venv) username@ubuntu:~$ pip install wheel
(venv) username@ubuntu:~$ pip install docker-compose
(venv) username@ubuntu:~$ sudo cp venv/bin/docker-compose /usr/bin
(venv) username@ubuntu:~$ deactivate

Confirm the installation is successful.

username@ubuntu:~$ docker-compose --version
docker-compose version 1.27.4, build unknown

User Setting

Set the user to run the Docker application deployed from Greengrass. The default is ggc_user, so this time we will use this user.

Create a directory to save docker-compose downloaded from your S3 bucket and set permissions.

sudo mkdir /home/ggc_user/myCompose
sudo chown ggc_user:ggc_group /home/ggc_user/myCompose
sudo chmod 700 /home/ggc_user/myCompose

Add ggc_user to the docker group.

sudo usermod -aG docker ggc_user

Log out once to reflect the settings.

1. Create a Docker application

** Create a Docker application on your PC. This time, we will create a Python web application that will display the message "Hello World from Docker Container!" When accessed. Save the following three files in the same folder.

A Python program that uses Flask. When accessed, the message "Hello World from Docker Container!" Is displayed.

app.py


from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World from Docker Container!"

if __name__ == "__main__":
    app.run()

A file that describes the required Python packages. This time I will only use Flask.

requirements.txt


Flask

This is a file that describes the commands for creating a Docker image. I have installed the files and packages needed for the image for 32bit arm.

Dockerfile


FROM arm32v7/python:3.7-alpine
WORKDIR /usr/src/app
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["flask", "run"]

2. Push Docker image

Create a Docker image and push it to ECR.

Creating a repository

  1. From the service in the upper left, go to Elastic Container Registry and click "Repositories"-> "Create Repository". docker-24.png

  2. Enter a repository name of your choice and click Create Repository. docker-25.png

Image creation and push

  1. Start Docker Desktop on Windows on your PC.

  2. Go to the repository page and click View Push Command. docker-31.png

  3. Open a command prompt in the directory containing the Dockerfile created in Create Docker Application, and execute the displayed commands in order. docker-32.png

  4. Confirm that the docker image has been pushed to the ECR. Make a note of the image URI as you will use it in a later step. docker-37.png

3. Upload docker-compose

Create docker-compose

** Create a docker-compose on your PC. Save the following content as docker-compose.yml. Replace the <image-uri> with the URI you wrote down in Create and Push Image.

docker-compose.yml


version: '3'
services:
  web:
    image: "<image-uri>"
    ports:
      - "5000:5000"

Creating an S3 bucket

  1. From the top left menu, go to S3 and click Bucket → Create Bucket. docker-26.png

  2. Enter a bucket name of your choice and click Create Bucket. docker-27.png

Upload docker-compose

  1. Click the bucket you created and click Upload. docker-28.png

  2. Click "Add File" and upload the docker-compose.yml created by Create docker-compose. docker-29.png

4. Deploy Docker application

Create and attach roles

Create the roles that Greengrass needs to access your S3 bucket, ECR, and attach them to your Greengrass group.

Creating a policy

  1. Go to IAM → Policies and click Create Policy. docker-7.png

  2. Click the JSON tab and enter the following JSON to allow access to your S3 bucket. Replace <bucket-name> with the S3 bucket name you created in Create S3 Bucket (#s3バケットの作成). Click Check Policy when you are done.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowAccessToComposeFileS3Bucket",
                "Action": [
                    "s3:GetObject"
                ],
                "Effect": "Allow",
                "Resource": "arn:aws:s3:::<bucket-name>/*" 
            }
        ]
    }
    

    docker-17.png

  3. Enter a name and description of your choice and click Create Policy. docker-16.png

  4. Follow the same procedure to create a policy that allows access to ECR using the following JSON. The <region> and <account-id> parts are the region and account ID you are using, and the <repository-name> part is the repository name created in Create Repository. Please replace.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowGetEcrRepositories",
                "Effect": "Allow",
                "Action": [
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:BatchGetImage"
                ],
                "Resource": [
                    "arn:aws:ecr:<region>:<account-id>:repository/<repository-name>"
                ]	
            },
            {
                "Sid": "AllowGetEcrAuthToken",
                "Effect": "Allow",
                "Action": "ecr:GetAuthorizationToken",
                "Resource": "*"
            }
        ]
    }
    

Creating a role

  1. Go to IAM → Roles and click Create Role.

  2. Select Greengrass in the use case selection and proceed to the next. docker-19.png

  3. Select the two policies you created in Create Policy (#ポリシーの作成). docker-20.png

  4. Proceed to the next without setting the tag.

  5. Enter a name and description of your choice to create the role. docker-21.png

Attach roll

  1. Go to the Greengrass group and click Settings → Add Roles. docker-22.png

  2. Select the role you created in Create Role (#ロールの作成) and click Save. docker-23.png

Deployment and operation check

  1. Go to the group page and click Connector → Add Connector. docker-33.png

  2. Select Docker Application Deployment and click Next. docker-34.png

  3. Specify docker-compose.yml saved in S3 and the directory to save docker-compose on the device created in User Settings, and click "Add". docker-35.png

  4. Go to the group page and click Deploy. docker-30.png

  5. After the deployment is complete, wait for a while and then access http: // <device IP address>: 5000 on your PC.

  1. If the following screen is displayed, it is successful. docker-38-2.png

Supplement

The settings differ depending on the environment, but for reference, I will introduce the proxy settings I made this time.

Command proxy settings

At the Windows command prompt, enter the following:

set HTTP_PROXY=http://username:[email protected]:port/
set HTTPS_PROXY=http://username:[email protected]:port/

docker proxy settings

Set the proxy according to the Docker document [^ docker-proxy].

  1. First, create a directory and then create files in that directory.

    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
    
  2. Write the environment variables HTTP_PROXY and HTTPS_PROXY to a file and save them in the following format. If you only need one or the other, or if you need to set NO_PROXY, change the content appropriately according to your environment.

    [Service]
    Environment="HTTP_PROXY=http://username:[email protected]:port/"
    Environment="HTTPS_PROXY=http://username:[email protected]:port/"
    
  3. Reload and restart the daemon for the settings to take effect.

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  4. Check if the settings are reflected.

    #For general user username
    username@ubuntu:~$ sudo systemctl show --property=Environment docker
    Environment=HTTP_PROXY=http://username:[email protected]:port/ HTTPS_PROXY=http://username:[email protected]:port/
    

reference

[^ gg-v2]: AWS IoT Greengrass 2.0 Announced — Open Source Edge Runtime and New Developer Features | Amazon Web Services Blog

Recommended Posts

Deploy a Docker application with Greengrass
Deploy your application with VPC + EC2 + Docker.
Rails deploy with Docker
Deploy with EC2 / Docker / Laravel
Web application built with docker (1)
Create a Vue3 environment with Docker!
Build a Node.js environment with Docker
Build a web application with Javalin
Operate a honeypot (Dionaea) with Docker
Web application creation with Nodejs with Docker
Java: Start WAS with Docker and deploy your own application
Procedure for building a Rails application development environment with Docker [Rails, MySQL, Docker]
Create a simple web application with Dropwizard
Build a PureScript development environment with Docker
Deploy to heroku with Docker (Rails 6, MySQL)
Create a MySQL environment with Docker from 0-> 1
[docker] [nginx] Make a simple ALB with nginx
Build a Wordpress development environment with Docker
Creating a java web application development environment with docker for mac part1
I tried to build a Firebase application development environment with Docker in 2020
[Java] Deploy a web application created with Eclipse + Maven + Ontology on Heroku
heroku: docker: deploy
Create a java web application development environment with docker for mac part2
[Memo] Create a CentOS 8 environment easily with Docker
Build a Laravel / Docker environment with VSCode devcontainer
Build a WordPress development environment quickly with Docker
Prepare a scraping environment with Docker and Java
Deploy a Spring Boot application on Elastic Beanstalk
Deploy Line bot with rails5 + Docker + Heroku Note
Create a Spring Boot development environment with docker
I tried to make a machine learning application with Dash (+ Docker) part3 ~ Practice ~
A simple CRUD app made with Nuxt / Laravel (Docker)
Practice making a simple chat app with Docker + Sinatra
How to deploy to Heroku from a local docker image
Launch MariaDB with Docker
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (5)
Run Pico with docker
Easily build a Vue.js environment with Docker + Vue CLI
Explode Docker with WSL2
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (6)
Use Puphpeteer with Docker
[Personal application work memo] Make a calendar with simple_calendar
[Note] Build a Python3 environment with Docker in EC2
Operate Emby with Docker
Try WildFly with Docker
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (3)
Use ngrok with Docker
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (2)
Run Payara with Docker
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (1)
Display ROS application on Docker with GUI on host side
[Note] Create a java environment from scratch with docker
[Docker] Connection with MySQL
Php settings with Docker
Getting Started with Docker
[Rails AWS Docker] Build an existing Ruby on Rails + MySQL application with Docker and deploy it on AWS (4)
Let's develop a full stack application with NextJS / NestJS / PostgreSQL / Docker! Hands-on ① (Server-side edition)
Disposable PHP with Docker
Install Composer with Docker
Deploy a Java application developed locally with the Cloud Toolkit to an Alibaba Cloud ECS instance
Let's develop a full stack application with NextJS / NestJS / PostgreSQL / Docker! Hands-on ② (Front end, Docker edition)