Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Flutter | Troubleshooting

Basic

flutter doctor

Error: Exception: Bad UTF-8 encoding
Solution: Use the current version of vswhere

Download from: https://github.com/microsoft/vswhere/releases

Store/overwrite: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe

PS> Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer"                                                                                                                                              
PS> Move-Item vswhere.exe vswhere.exe.original
PS> Invoke-WebRequest https://github.com/microsoft/vswhere/releases/download/3.0.3/vswhere.exe -O vswhere.exe
Null safety features are disabled for this library.
lib/main.dart:8:19: Error: Null safety features are disabled for this library.
Try removing the package language version or setting the language version to 2.12 or higher.
  const MyApp({Key? key}) : super(key: key);
Solution: Edit pubspec.yaml
environment:
  sdk: '>=2.17.3 <3.0.0'

Migration Dart Plugins

import 'package:flutter/services.dart';
client =createHttpClient();

 

import 'package:http/http.dart' as http;
client = new http.Client();

Your app is not using AndroidX

GoTo Flutter_Project -> android -> gradle.properties file. Open the gradle.properties file in any Text editor.

Add below lines in this file and Save the file.

android.useAndroidX=true
android.enableJetifier=true

Open your Flutter Project Root directory in Command Prompt or Terminal and execute

flutter clean

Flutter | Getting started

Installation

Installation of Flutter

Details are here

Installation of Dart SDK

Details are here

$ brew tap dart-lang/dart
$ brew install dart --devel

Create your first App

Copied from here and here

Create the starter Flutter app

$ flutter create starter
$ cd starter

Run Flutter App on the Web

$ flutter config --enable-web
$ flutter config --enable-web
$ flutter build web

Run Flutter App on Android Emulator

$ flutter devices
$ flutter run [--verbose]
$ flutter emulators
5 available emulators:

Android_Accelerated_Oreo
Nexus_5X_API_28_x86      • Nexus 5X      • Google • Nexus 5X API 28 x86
Pixel_3_API_28           • pixel_3       • Google • Pixel 3 API 28
Pixel_XL_API_28          • pixel_xl      • Google • Pixel XL API 28
apple_ios_simulator      • iOS Simulator • Apple

To run an emulator, run 'flutter emulators --launch <emulator id>'.
To create a new emulator, run 'flutter emulators --create [--name xyz]'.
$ flutter emulators --launch apple_ios_simulator

Read More

Official websitehttps://flutter.io/ will supply from step by step to install and start with the simple example.

Dart language

Flutter training online

Google CodeLab: https://codelabs.developers.google.com/?cat=Flutter

Flutter Samples: https://github.com/flutter/samples

Flutter Cookbook: https://flutter.dev/docs/cookbook

Github Awesome-Flutter

Flutter challenge series has been building by Matt Carroll who is owners of Fluttery (Youtube channel https://www.youtube.com/fluttery)

Blogs 

App builder: It is an amazing tool to build the Flutter UI online that mean you only need choose your UI widget and drag to screen -> You can get the source code for your app.

The Flutter Pub is a medium publication to bring you the latest and amazing resources such as articles, videos, codes, podcasts, etc. about this great

What’s next

  • Learn Dart
    Go to Dart guides and see a preview of the four most visited websites. Initially, these two are worth focusing on: Language tour and Language samples. A complete and detailed Dart course supported by examples can also be found here.
  • Install Flutter SDK – Prepare IDE
    The entire process is described step by step depending on the system on which we want to install Flutter.
  • Study Material Design Concept
    If we want to create user-friendly interfaces, it is important to read material design rules. 
  • Widgets
    Widgets are an indispensable part of Flutter. You can browse them alphabetically.
  • API Calls and Database Integration
    The Pub provides great packages such as: http or dio to perform HTTP requests. Hive is a lightweight and blazing fast key-value database written in pure Dart. You should also consider integrating with Firebase.

Links

Angular | Starting with Capacitor

Introduction

Install Angular

$ npm -g install @angular/cli

Create sample app

❯ ng new app-capacitor
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/syntax#scss]

❯ cd app-capacitor

Change output path to capacitor defaults

Change line in angular.json

      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",

 Add capacitor support

❯ ng add @capacitor/angular
ℹ Using package manager: npm
✖ Unable to find compatible package.  Using 'latest'.
✖ Package has unmet peer dependencies. Adding the package may not succeed.

The package @capacitor/angular will be installed and executed.
Would you like to proceed? Yes

Capacitor initialisieren

❯ npx cap init
[?] What is the name of your app?
    This should be a human-friendly app name, like what you'd see in the App Store.
√ Name ... app-capacitor
[?] What should be the Package ID for your app?
    Package IDs (aka Bundle ID in iOS and Application ID in Android) are unique identifiers for apps. They must be in
    reverse domain name notation, generally representing a domain name that you or your company owns.
√ Package ID ... com.example.app
√ Creating capacitor.config.ts in D:\CLOUD\Online-Seminare\Kurse\Angular\Einsteiger\App_Capacitor in 5.31ms
[success] capacitor.config.ts created!

Next steps:
https://capacitorjs.com/docs/v3/getting-started#where-to-go-next
[?] Join the Ionic Community! 💙
    Connect with millions of developers on the Ionic Forum and get access to live events, news updates, and more.
√ Create free Ionic account? ... no
[?] Would you like to help improve Capacitor by sharing anonymous usage data? 💖
    Read more about what is being collected and why here: https://capacitorjs.com/telemetry. You can change your mind at
    any time by using the npx cap telemetry command.
√ Share anonymous usage data? ... no

Build your app

We will need the dist directory with the web files

❯ ng build --prod
Option "--prod" is deprecated: No need to use this option as this builder defaults to configuration "production".
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.

Initial Chunk Files               | Names         |      Size
main.b633c9096acdb457c421.js      | main          | 212.34 kB
polyfills.e4574352eda6eb439793.js | polyfills     |  35.95 kB
runtime.d66bb6fe709ae891f100.js   | runtime       |   1.01 kB
styles.31d6cfe0d16ae931b73c.css   | styles        |   0 bytes

                                  | Initial Total | 249.29 kB

Build at: 2021-05-28T09:32:28.905Z - Hash: ed2ed2d661b0d58b48f2 - Time: 28225ms
❯ npm install @capacitor/ios @capacitor/android
npm WARN @capacitor/angular@1.0.3 requires a peer of rxjs@~6.4.0 but none is installed. You must install peer dependencies yourself.
npm WARN @capacitor/angular@1.0.3 requires a peer of typescript@~3.4.3 but none is installed. You must install peer dependencies yourself.
npm WARN ajv-keywords@3.5.2 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ @capacitor/ios@3.0.0
+ @capacitor/android@3.0.0
added 2 packages from 1 contributor, removed 1 package and audited 1375 packages in 7.385s

88 packages are looking for funding
  run `npm fund` for details

found 35 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Add Platform Android

❯ npx cap add android
√ Adding native android project in android in 167.07ms
√ Syncing Gradle in 1.45ms
√ add in 169.83ms
[success] android platform added!
Follow the Developer Workflow guide to get building:
https://capacitorjs.com/docs/v3/basics/workflow
√ Copying web assets from dist to android\app\src\main\assets\public in 55.26ms
√ Creating capacitor.config.json in android\app\src\main\assets in 3.50ms
√ copy android in 164.93ms
√ Updating Android plugins in 7.76ms
√ update android in 75.79ms

Open Android Studio to build App

❯ npx cap open android
[info] Opening Android project at: android.

Python | Working with virtual environments

Introduction

  • venv module
  • virtualenv
  • pipenv

pipenv

Introduction

Pipenv — the officially recommended Python packaging tool from Python.org, free (as in freedom).

Read here how to install in details

Installation

For Mac OS and brew package manager

brew install pipenv

Prepare environment

venv module

Installation

Nothing required. Module venv is part of the Python distribution

Prepare environment

python3 -m venv env

virtualenv

Prepare environment

$ virtualenv -p python3 .env/python

Ionic | Working with moments.js

Introduction

With moment.js, you can

Parse, validate, manipulate, and display dates and times in JavaScript.

With a npm-Module, you can integrate this functionality into your Ionic App

Preparation

Create your empty app

$ ionic start working-with-moments blank --no-git --no-link

Install npm Module

$ cd  working-with-moments
$ npm install moment
+ moment@2.20.1
added 1 package in 3.001s

Start Editor and serve your app

$ vscode .
$ ionic serve

Add moments.js functionality

Change pages/home/home.ts

Add the moments.js reference to pages/home/home.ts

import { Component } from '@angular/core'; 
import { NavController } from 'ionic-angular';
import * as moment from 'moment';

Create a var for the current date/time

export class HomePage {
  public date: any;

  constructor(public navCtrl: NavController) {
    this.date = moment();
  }
}

Change pages/home/home.html

<ion-content padding>
  The current date/time is {{ date }}
</ion-content>

Summary

A lot more examples could be found in my repository. Just create a starter app with this template and begin to play

$ ionic start app https://github.com/ionic4-toolbox/Working-with-moment.js

Build separated development environments with direnv

TL;DR

Working with Ionic sometimes means to handle different versions of Ionic/Cordova and Ionic/Cordova Plugins. My goal was, to setup an Ionic environment specify for each project. And I want do activate the environments automatically.

I started with autoenv, but unfortunately there is no unload/deactivate mechanism. So, finally, i switched to direnv. But i also tried different solutions with Vagrant or Docker.

Requirements

You will need a package manager to install the different software packages. There are a variety of package manager for the different platforms. 

For macOS, i will use Homebrew.

Things about my directory structure

Mostly, i try to group files in different directories, depending on their functionality.

Environment files goes to a directory .env. But, wait: there could be more environments (node.js, ruby, python), which all could be used in my project.

So, i decide to use subfolders for each possible environment. Here it looks like:

$ tree myproject
myproject
└── .env
    ├── nvm
    ├── pyenv
    └── ruby

Some small example

Suppose, you have this directory structure

.
├── home
│   ├── .envrc
│   └── bath
│       └── .envrc
└── office
    └── .envrc

If you walk between this different rooms, you will see how direnv follow you

~/tmp$ cd home
direnv: loading .envrc
You are at home
~/tmp/home$ cd bath
direnv: loading .envrc
You are in the bath
~/tmp/home/bath$ cd ..
direnv: loading .envrc
You are at home
~/tmp/home$ cd ..
direnv: unloading
~/tmp$ cd office
direnv: loading .envrc
You are at work
~/tmp/office$ cd ../home/bath
direnv: loading .envrc
You are in the bath
~/tmp/home/bath$

Installation

There is a detailed installation instruction here, but for macOS, here is the simple step

$ brew install direnv
==> Downloading https://homebrew.bintray.com/bottles/direnv-2.14.0.high_sierra.bottle.tar.gz
Already downloaded: /home/user/Library/Caches/Homebrew/direnv-2.14.0.high_sierra.bottle.tar.gz
==> Pouring direnv-2.14.0.high_sierra.bottle.tar.gz
  /usr/local/Cellar/direnv/2.14.0: 8 files, 3.7MB

Finally, check if installation has succeed

$ direnv version
2.14.0

Configuration

Directory specific configuration is made through the file .envrc. It’s like a normal Shell profile script, so mostly all commands are allowed and possible.

Entering the directory triggers this configuration file, so a normal cd into the directory does the environment setup.. pretty cool!

In my simple example, i used this configuration files

~/tmp$ find . -name .envrc
./home/.envrc
./home/bath/.envrc
./office/.envrc
~/tmp$ find . -name .envrc -exec cat {} \;
echo "You are at home"
echo "You are in the bath"
echo "You are at work"

Setting up a sample project

Ionic heavily depends on node.js So, the challenge is to setup different node.js environments. Luckily, there is already a solution for that: Node Version Manager nvm.

Install nvm

For macOS, this is quit simple (details could be found here)

$ brew install nvm

Or, manually

$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash

Setup directory structure

Create the desired directory structure

$ cd $HOME/tmp
$ mkdir -p myproject2/.env/nvm

Configure direnv

Add the following lines (with some additional lines) into your direnv configuration file .envrc

#!/bin/bash

export NVM_DIR=$HOME/tmp/.env/nvm

echo setup nvm with NVM_DIR=$NVM_DIR
. /usr/local/opt/nvm/nvm.sh

nvm --version

Hint: When you created the file (for example with vi), you get the error message, that the .envrc file is blocked

$ vi .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

Follow the suggested solution: run direnv allow

$ direnv allow
direnv: loading .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8
direnv: export +NVM_CD_FLAGS +NVM_DIR +NVM_RC_VERSION

Now, test the configuration: Leave the directory and enter it again

$ cd ..
direnv: unloading
$ cd myproject
direnv: loading .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8
direnv: export +NVM_CD_FLAGS +NVM_DIR +NVM_RC_VERSION

Hint: If this does not work, try to start the configuration file manually for the first time, 

$ cd $HOME/tmp/myproject
$ . .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8

Fix possibile warnings and errors

If you get this error message

nvm is not compatible with the npm config "prefix" option: currently set to ...

Then, issue this command

$ npm config delete prefix

Install node

Now, the real task: install node.js

$ cd $HOME/tmp/myproject
$ nvm --version
0.33.8
$ node --version
-bash: node: command not found
$ nvm install 9.4.0
Downloading and installing node v9.4.0...
Downloading https://nodejs.org/dist/v9.4.0/node-v9.4.0-darwin-x64.tar.xz...
######################################################################## 100,0
Computing checksum with shasum -a 256
Checksums matched!
Now using node v9.4.0 (npm v5.6.0)
Creating default alias: default -> 9.4.0 (-> v9.4.0)

Test the installation

$ which node
/home/user/tmp/myproject/.env/nvm/versions/node/v9.4.0/bin/node
$ node --version
v9.4.0

If you want to use an additional node version (maybe the latest LTS version), just install it

$ nvm install lts/carbon
Downloading and installing node v8.9.4...
Downloading https://nodejs.org/dist/v8.9.4/node-v8.9.4-darwin-x64.tar.xz...
######################################################################## 100,0
Computing checksum with shasum -a 256
Checksums matched!
Now using node v8.9.4 (npm v5.6.0)

You can switch between the different versions with nvm use

$ nvm use lts/carbon
Now using node v8.9.4 (npm v5.6.0)
$ node --version; npm --version
v8.9.4
5.6.0
$ nvm use default
Now using node v9.4.0 (npm v5.6.0)
$ node --version; npm --version
v9.4.0
5.6.0

Setting up Ionic Environment

After this required preparation, we can start setting up our Ionic Environment

For this example, I choose the following start path: ~/Workspace/Ionic3

Setup directory structure

$ mkdir -p $HOME/Workspace/Ionic3/.env/nvm
$ cd $HOME/Workspace/Ionic3
$ vi .envrc

Create the direnv configuration file

Configuration file

#!/bin/bash
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
  HERE="$PWD"

#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
  _USE_NODE_VERSION=9.4.0

#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
  export NVM_DIR="$HERE/.env/nvm"

  echo "setup nvm: $NVM_DIR"
  . /usr/local/opt/nvm/nvm.sh

  nvm use $_USE_NODE_VERSION --silent

  echo "enabled nvm :  $(nvm  --version) $(which nvm  | sed 's#'$NVM_DIR'/##')"
  echo "enabled node:  $(node --version) $(which node | sed 's#'$NVM_DIR'/##')"
  echo "enabled npm :  $(npm  --version) $(which npm  | sed 's#'$NVM_DIR'/##')"

Allow the configuration file for use

$ direnv allow
direnv: loading .envrc
setup nvm: /home/user/Workspace/Ionic3/.env/nvm
enabled nvm : 0.33.8
enabled node: v9.4.0 versions/node/v9.4.0/bin/node
enabled npm : 5.6.0 versions/node/v9.4.0/bin/npm
direnv: export +NVM_CD_FLAGS +NVM_DIR

Test the configuration

~$ cd
~$ cd Workspace/Ionic3
direnv: loading .envrc
setup nvm: /home/user/Workspace/Ionic3/.env/nvm
enabled nvm :  0.33.8
enabled node:  v9.4.0 versions/node/v9.4.0/bin/node
enabled npm :  5.6.0 versions/node/v9.4.0/bin/npm
direnv: export +NVM_CD_FLAGS +NVM_DIR

Well done!

Setup Ionic

Install required parts

$ npm -g install ionic@latest cordova@latest

Test your installation

~/Workspace/Ionic3$ ionic --version
3.19.1
~/Workspace/Ionic3$ cordova --version
8.0.0
~/Workspace/Ionic3$ $ which ionic
/home/user/Workspace/Ionic3/.env/nvm/versions/node/v9.4.0/bin/ionic

And, finally, work with Ionic

$ ionic start super super --cordova --no-link
$ cd super
$ ionic serve

Next steps

Happy with this, maybe you want to try other things.

Docker

Docker | Cookbook

Useful apps

portainer.io: MAKING DOCKER MANAGEMENT EASY. Build and manage your Docker environments with ease today.

dive: About A tool for exploring each layer in a docker image

Useful commands

  • docker ps — Lists running containers.
    Some useful flags include: -a / -all for all containers (default shows just running) and —-quiet /-q to list just their ids (useful for when you want to get all the containers).
  • docker pull — Most of your images will be created on top of a base image from the Docker Hub registry. Docker Hub contains many pre-built images that you can pull and try without needing to define and configure your own. To download a particular image, or set of images (i.e., a repository), use docker pull.
  • docker build — Builds Docker images from a Dockerfile and a “context”.
    A build’s context is the set of files located in the specified PATH or URL. Use the -t flag to label the image, for example docker build -t my_container . with the . at the end signalling to build using the currently directory.
  • docker run — Run a docker container based on an image.
    You can follow this on with other commands, such as -it bash to then run bash from within the container. 
    Also see Top 10 options for docker run — a quick reference guide for the CLI command
    docker run my_image -it bash
  • docker logs —  Display the logs of a container.
    You must specify a container and can use flags, such as --follow to follow the output in the logs of using the program. 
    docker logs --follow my_container
  • docker volume ls — Lists the volumes,.
    Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.
  • docker rm — Removes one or more containers.
    docker rm my_container
  • docker rmi — Removes one or more images. 
    docker rmi my_image
  • docker stop — Stops one or more containers.
    docker stop my_containerstops one container, while docker stop $(docker ps -a -q) stops all running containers. A more direct way is to use docker kill my_container, which does not attempt to shut down the process gracefully first.
  • Use them together, for example to clean up all your docker images and containers:
  • kill all running containers with docker kill $(docker ps -q)
  • delete all stopped containers with docker rm $(docker ps -a -q)
  • delete all images with docker rmi $(docker images -q)

Create new container

Start a new docker image with a given name

You can start a new container by using the run command and specify the desired image 

$ docker run -it --name playground ubuntu:17.10 /bin/bash
....
root@c106fbb48b20:/# exit

As a result, you are in the container at the bash command line

Reconnect to image
$ docker attach playground
Commit changes in container
$ docker start playground
$ docker attach playground
root@c106fbb48b20:/# echo 1.0 >VERSION
root@c106fbb48b20:/# exit
$ docker commit playground playground:1.0
$ docker tag playground:1.0 playground:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
playground 1.0 01703597322b Less than a second ago 94.6MB
playground latest 01703597322b Less than a second ago 94.6MB

Add tools and utilities

Python

$ apt-get update 
$ apt-get upgrade 
$ apt-get install python3 python3-pip

Java

$ apt-get install default-jre

Manage File Shares

File shares with Docker Desktop on Mac OS

Configuration is stored under

~/Library/Group Containers/group.com.docker/settings.json

Monitor Docker Logs

Logs with Docker Desktop on Mac OS

pred='process matches ".*(ocker|vpnkit).*" || (process in {"taskgated-helper", "launchservicesd", "kernel"} && eventMessage contains[c] "docker")'
/usr/bin/log stream --style syslog --level=debug --color=always --predicate "$pred"

Alternative you can run

/usr/bin/log show --style syslog --debug --info --last 1d --predicate "$pred" >/tmp/logs.txt

Add Timezone Konfiguration

ENV TZ 'Europe/Berlin'

RUN echo $TZ > /etc/timezone 
RUN    apt-get install -y tzdata \
    && rm /etc/localtime \
    && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
    && dpkg-reconfigure -f noninteractive tzdata \
    && apt-get clean

Install local apps in a docker container

Install Atom Editor

Start docker image

$ docker run -it --name docker-atom -v /Dockerfiles/HOME:/home -e DISPLAY=192.168.99.1:0 ubuntu /bin/bash

Install Atom

# apt-get update
# apt-get install curl
# curl -sL https://deb.nodesource.com/setup_7.x | bash -
# apt-get install nodejs
# node -v
v7.4.0
# apt-get -y install git
# apt-get -y install software-properties-common
# add-apt-repository -y ppa:webupd8team/atom
# apt-get update
# apt-get -y install atom
# apt-get install libxss1

Commit changes  and build a image

# docker commit -a "Docker Tutorial 1.0.0" -m ionic d378e8647af9 atom:1.0.0
# docker tag atom:1.0.0 atom:latest

Links and Resources

Docker quick reference guides

Docker in more depth

Working with networks

I’ve got a lot of inspiration from wsargent/docker-cheat-sheet.

Goal

We will setup to applications, each in his one container, running on the smae network, so they can communication together.

Setup

Starting with the default configuration, you will see 4 networks

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6742a11bff1e        bridge              bridge              local
3af0a1c9eaac        host                host                local
e60f68aad9d6        none                null                local

Create a bridged network for running two apps inside: web and database

$ docker network create -d bridge playground_bridge
c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6742a11bff1e        bridge              bridge              local
3af0a1c9eaac        host                host                local
e60f68aad9d6        none                null                local
c97a80b449d9        playground_bridge   bridge              local

Start the database application using the bridges network

$ docker run -d --net=playground_bridge --name playground_db training/postgres
88abb9d018c628ed1abe7da0466289846a8342a28b2cbef3305ea5313c46d647
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db| python -m json.tool
{
    "playground_bridge": {
        "Aliases": [
            "88abb9d018c6"
        ],
        "DriverOpts": null,
        "EndpointID": "9fdfe9baf5b159471a39601779ee451aa555a9a9be72be4472e56bd3fcfd1350",
        "Gateway": "172.18.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAMConfig": null,
        "IPAddress": "172.18.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "Links": null,
        "MacAddress": "02:42:ac:12:00:02",
        "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"
    }
}

Now, start the web application with the default network (not the playground_bridge used by the database)

$ docker run -d --name playground_web training/webapp python app.py
2f31761168d75d10c2f1bffc805fb8963a18529e17c2592c2b279afd9e364e7b

They cannot communication, because they are running in different networks:

$ docker exec -it playground_db ifconfig | grep inet
         inet addr:172.18.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
         inet addr:127.0.0.1 Mask:255.0.0.0
$ docker exec -it playground_web ifconfig | grep inet
         inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
         inet addr:127.0.0.1 Mask:255.0.0.0

Now check the connectivity. The Web application can reach itself:

$ docker exec -it playground_web ping -c 5 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.033 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.036 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.031 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.029 ms

But could not reach the database application (because of the different network):

$ docker exec -it playground_web ping -c 5 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.

--- 172.18.0.2 ping statistics ---
5 packets transmitted, 0 received, 100



To connect both apps together, put them in the same network:

Before, they use different networks:

$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_web | python -m json.tool|grep NetworkID
        "NetworkID": "6742a11bff1ebcdeaee9151f146a74b1c3d77db95d4931e4e79f48f7d7f491f7"
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db | python -m json.tool|grep NetworkID
        "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"

Connect Web Application to network playground_bridge:

$ docker network connect playground_bridge playground_web

 Now, they use the same network:

$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_web | python -m json.tool|grep NetworkID
        "NetworkID": "6742a11bff1ebcdeaee9151f146a74b1c3d77db95d4931e4e79f48f7d7f491f7"
        "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db | python -m json.tool|grep NetworkID
        "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"

And they can communication

$ docker exec -it playground_web ping -c 5 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.033 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.033 ms

--- 172.17.0.2 ping statistics ---
5 packets transmitted, 5 received, 0
rtt min/avg/max/mdev = 0.032/0.034/0.044/0.008 ms

$ docker exec -it playground_web ping -c 5 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.056 ms
64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.052 ms
64 bytes from 172.18.0.2: icmp_seq=5 ttl=64 time=0.053 ms

--- 172.18.0.2 ping statistics ---
5 packets transmitted, 5 received, 0
rtt min/avg/max/mdev = 0.052/0.069/0.134/0.033 ms

Usefull Links

https://blog.docker.com/2019/07/intro-guide-to-dockerfile-best-practices/

Ionic | App from Scratch | Linkes und Rechtes Menu

Definieren der beiden Seitenmenüs in app.html

<ion-menu [content]="contentLeft"> ....</ion-menu>
<ion-menu side="right" [content]="contentRight">....</ion-menu>
 ....

 <ion-nav [root]="rootPage" #contentLeft #contentRight swipeBackEnabled="false"></ion-nav>
<ion-menu [content]="contentLeft"> 
	....
</ion-menu> 
<ion-menu side="right" [content]="contentRight">
	....
</ion-menu> 
.... 
<ion-nav [root]="rootPage" 
	#contentLeft 
	#contentRight 
	swipeBackEnabled="false">
</ion-nav>

Zwei Schaltflächen hinzufügen

<ion-header>
   <ion-navbar>
      <button ion-button start menuToggle>
         <ion-icon name="menu"></ion-icon>
      </button>
      <ion-title>Demo of two Sidemenus</ion-title>
      <button ion-button end menuToggle="right">
         <ion-iconname="menu"></ion-icon>
      </button>
   </ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>

Ergebnis

Github Repository

Hier liegt der Beispielcode.

Ionic | App from Scratch – Two Sidemenus

Prepare your starter App

ionic start App sidemenu --type angular --no-git

Change into the newly create folder and start the Ionic App

cd App
ionic serve

You will see the default Ionic Sidemenu App

The entries of the sSidemenu are defined in app.components.ts:

export class AppComponent {
	public appPages = [
		{ title: 'Home', url: '/home', icon: 'home' },
		{ title: 'List', url: '/list', icon: 'list' }
	];

The sidemenu itself and his apperance are defined in app.component.html:

<ion-app>
  <ion-split-pane contentId="main-content">
    <ion-menu contentId="main-content" type="overlay">
      <ion-header>
        <ion-toolbar>
          <ion-title>Menu</ion-title>
        </ion-toolbar>
      </ion-header>
      <ion-content>
        <ion-list>
          <ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
            <ion-item [routerDirection]="'root'" [routerLink]="[p.url]">
              <ion-icon slot="start" [name]="p.icon"></ion-icon>
              <ion-label>{{p.title}}</ion-label>
            </ion-item>
          </ion-menu-toggle>
        </ion-list>
      </ion-content>
    </ion-menu>
    <ion-router-outlet id="main-content"></ion-router-outlet>
  </ion-split-pane>
</ion-app>

The Sidemenu entries and the Icon are added in line 13 and 14 to the sidemenu.

Define two sidemenus in app.html

<ion-menu [content]="contentLeft"> ....</ion-menu>
<ion-menu side="right" [content]="contentRight">....</ion-menu>
 ....

<ion-nav [root]="rootPage" #contentLeft #contentRight swipeBackEnabled="false"></ion-nav>

Add buttons to page

<ion-header>
   <ion-navbar>
      <button ion-button start menuToggle>
         <ion-icon name="menu"></ion-icon>
      </button>
      <ion-title>Demo of two Sidemenus</ion-title>
      <button ion-button end menuToggle="right">
         <ion-iconname="menu"></ion-icon>
      </button>
   </ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
Result
Github Repository

You can find the code here