# Container demo: simple container from scratch This container demo shows how to run a simple web server container. The goal is: - run a webserver written in python3 In order to do so, we will: - create an OCI image using docker - push that image to a container registry - import it into Unwired Edge Cloud - use it on a device - access the HTTP server from the LAN ## Step #1: create your container image We can create a simple container image using this Dockerfile: ```Dockerfile FROM ubuntu:jammy # install system packages RUN apt-get update && apt-get install -y python3 && \ apt-get purge -y unattended-upgrades && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* # add the files ADD files /opt/www WORKDIR /opt/www # declare port 80 EXPOSE 80 # the command to start the python server CMD ["python3","-m","http.server","80"] ``` Creating a new HTML-File: ``` mkdir files echo '
Hello World!' > files/index.html ``` Using this Makefile: ```Makefile # build a local test image build: docker build -t uwcloud/from-scratch:0.1 . # run the image locally run: docker run --rm -it -p 8087:80 uwcloud/from-scratch:0.1 ``` We can perform these steps: - ```make build``` - build the image under the local tag from-scratch:0.1 - ```make run``` - locally run the image As soon as the image is running, please validate by calling the following command in the local shell. The command: ```shell curl localhost:8087 ``` You should see HTML output like this: ```html Hello World! ``` ## Step #2: push the image to your registry The next step depends on your available infrastructure. If you don't have a registry you can use there are multiple options: - create a free account on [dockerhub](https://hub.docker.com/) to push your image there - use our image on dockerhub: [uwcloud/from-scratch:0.1](https://hub.docker.com/r/uwcloud/from-scratch) Of course you can also customize the image to your likings. ## Step #3: import the image This step: - imports the OCI image - defines the node service - versions increase automatically (if the version parameter is not passed in node_service_input) - LAN network: dhcp server with auto generated range - WAN network: allocated IP address - amd64 hardware platform - no file or directory mounts or persistent volumes - a memory limit of 50 MB Please note that in order to use this image on a hardware platform other than amd64 you will have to use docker buildx in order to build it for multiple platforms. This could look like this: ```Makefile # build an image and push it into a registry # - direct pushes are required, since buildx does not access the local docker repository build-all-platforms-and-push: docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t YOUR_TARGET_REPOSITORY/from-scratch:0.1 --push . # run manually before buildx to start up the builder instance. if one is already running, this will error. buildx-init: docker buildx create --use --platform=linux/amd64,linux/arm64,linux/arm/v7 --name multi-platform-builder docker buildx inspect --bootstrap .PHONY: build-all-platforms-and-push buildx-init ``` In order to import this image in the [Unwired Edge Cloud Console dev tools](https://admin.wifi.unwired.at/developer/playground) the following GraphQL mutation will work. Please make sure to customize the image URL to your image URL and also only import platforms that exist in your image repository: ``` mutation import_container_from_scratch { DM_import_node_service( input: { customer_id: "102e88a2-86cf-4a2d-8712-99e8e652db48" node_service_input: { container_image: "from-scratch" name: "from-scratch" apikey_roles: [] wipe_on_update: false access_gpsd_enabled: false network_config: { lan_configure_network: dhcp access_interfaces: { name: "eth1" label: "lan" } access_provided_subnet: "10.140.0.1/16" dhcp_range_template: "10.140.0.1/24" dhcp_lease_time_seconds: 600 wan_configure_network: allocated wan_dns_override: [] masq: true } } image_sources: [ { arch: amd64 image_reference: "uwcloud/from-scratch:0.1" } { arch: armhf image_reference: "uwcloud/from-scratch:0.1" } { arch: arm64 image_reference: "uwcloud/from-scratch:0.1" } ] metadata: { memory_limit_mb: 50 } } ) } ``` ### Checking job status This query allows you to check the job status with the job IDs received from the import mutation. ``` query job_status { DM_get_node_service_import_jobs(ids: ["44f68578-1234-49dd-8c12-ccdd275ef123", "ef895fb3-1235-491e-a711-2cb3ac165124", "4393a8d0-1236-4d37-a9e2-edc2b4c1a125"]) { node_service_import_job_id node_service_id state logs created last_modified arch } } ``` The output will show the state (in_progress, ok, failed) and a log of what happened after the import job is done. ### Delete node_service of failed Import Job This mutation allows you to delete a node_service from a (failed) import job. Please make sure to replace the `