In der heutigen Welt der Cloud kann man schnell den Überblick verlieren: VMs, Kubernetes, Serverless, die Möglichkeiten sind schier endlos, und die „beste“ Art, Anwendungen zu betreiben, nicht immer klar. Oftmals lohnt es sich, einen sogenannten Proof of Concept zu erstellen und ein Cloud Deployment einmal selbst durchzuspielen.
Genau das werden wir auch in diesem Tutorial tun: Mithilfe von Terraform und Docker setzen wir einen Server in der NETWAYS Cloud auf und deployen unsere Demo-Anwendung darauf. Das Ergebnis: Reproduzierbare, sichere Infrastruktur und eine via TLS abgesicherte Anwendung, die containerisiert darauf läuft. Das gesamte Cloud Deployment sollte dabei nicht länger als 15 Minuten dauern – vorausgesetzt, du hast die benötigten Werkzeuge zur Hand.
Du kannst also parallel mitmachen oder dir den Code bei Bedarf noch einmal anschauen.
Voraussetzungen
Für das Cloud Deployment müssen wir zunächst einige Voraussetzungen erfüllen. Folgende Dinge benötigst du, um dem Tutorial zu folgen:
- einen MyNWS Account mit einem konfigurierten NETWAYS Cloud Projekt
- Terraform, auf deinem Computer installiert
- einen SSH-Schlüssel, um auf deinen Server zuzugreifen
- das Git-Repository mit den benötigten Terraform Ressourcen und der Demo-Anwendung
- [Optional] Eine Domain für TLS-verschlüsselten Zugriff
Aktivierung des OpenStack Project Users
Stelle sicher, dass in deinem NETWAYS Cloud Projekt der OpenStack Project User aktiviert ist, da du diesen für die Provisionierung des Servers mit Terraform nutzen wirst. Wie du diesen aktivieren und das Passwort einsehen kannst, haben wir in unserer Dokumentation beschrieben.
Ist der Projektnutzer bereits aktiviert, kannst du dir schon einmal folgende Dinge notieren – du benötigst sie im nächsten Schritt für die Konfiguration von Terraform:
- Projektname – der Name deines NETWAYS Cloud Projekts, bzw. der Name des aktivierten Project Users.
- Passwort – das Passwort des aktivierten Project Users
Herunterladen des Git-Repositorys
Die letzte Voraussetzung, um dem Tutorial folgen zu können, ist das auf GitHub verfügbare Repository mit sämtlichen für unser Cloud Deployment benötigten Ressourcen. Du kannst es einfach mit git klonen und auf deinen Computer herunterladen:
git clone https://github.com/netways-web-services/15-minutes-cloud-deployment
cd 15-minutes-cloud-deploymentJetzt sollten wir alles beisammen haben, um mit dem eigentlichen Tutorial beginnen zu können.
Schritt 1: Provisionierung der Infrastruktur
Bevor wir unsere Demo-Anwendung deployen können, benötigen wir zuerst die Infrastruktur, auf der wir sie betreiben. Diese besteht aus folgenden Komponenten, die wir mithilfe von Terraform provisionieren:
- ein Cloudserver mit Ubuntu Noble 24.04 LTS und s1.small Flavor (2 CPUs, 2GB RAM, 25GB Disk)
- eine Security Group, um den Zugriff via HTTP/S (Ports 80 bzw. 443) und SSH (Port 22) zu erlauben
- ein Netzwerkport mit Floating IP, um dem Cloud Server die Security Group zuzuweisen und den Server über das Internet erreichen zu können
Bevor wir die entsprechenden Ressourcen mit Terraform provisionieren können, müssen wir allerdings erst Terraform selbst konfigurieren. Hierfür haben wir eine Datei vars.auto.tfvars.example vorbereitet, die du umbenennen und ausfüllen musst:
mv vars.auto.tfvars.example vars.auto.tfvarsFolgende Werte müssen eingetragen werden:
- ssh_pub_key: Der öffentliche Schlüssel des SSH-Schlüsselpaars, das du für die Verbindung zum Server nutzen möchtest.
- project_name: Der Projektname, den du dir im vorherigen Schritt notiert hast.
- password: Das Passwort, das du dir im vorherigen Schritt notiert hast.
Sind die Werte eingetragen, muss das Terraform-Projekt noch initialisiert werden. Das geschieht mit folgendem Befehl:
terraform initIst alles korrekt konfiguriert, bestätigt Terraform, dass die Initialisierung erfolgreich war, und wir können mit der Provisionierung loslegen.
Planung der Cloud Deployment Infrastruktur
Terraform erlaubt es uns, die zu provisionierenden Ressourcen vor der Ausführung zu planen und das errechnete Ergebnis zu betrachten. Auf diese Weise können wir noch einmal validieren, dass auch tatsächlich alle benötigten Ressourcen korrekt definiert sind, und in einem Provisionierungslauf erstellt würden:
terraform planDie Ausgabe von Terraform entspricht einer langen Liste an auszuführenden Actions. Da bisher keinerlei durch Terraform provisionierte Infrastruktur in unserem Projekt existiert, sollten alle gelisteten Aktionen vom Typ create sein.
Eine schnelle Möglichkeit, die Korrektheit des Plans zu überprüfen, findet sich am Ende der Ausgabe. Findest du hier folgende Nachricht, ist dein Projekt korrekt aufgesetzt, und du kannst die Provisionierung deiner Cloud Deployment Infrastruktur fortsetzen.
Plan: 9 to add, 0 to change, 0 to destroy.Provisionierung der Cloud Deployment Infrastruktur
Die benötigten Cloud-Ressourcen mit Hilfe von Terraform zu provisionieren funktioniert sehr ähnlich wie das Anzeigen des Plans im vorherigen Schritt:
terraform applyTerraform listet erneut alle duchzuführenden Aktionen, und fragt dich, ob es fortfahren soll. Beantworte die Frage mit yes und bestätige mit Eingabe von Enter. Terraform beginnt nun, die gelisteten Aktionen auszuführen. Dabei achtet es darauf, voneinander abhängige Ressourcen (bspw. Ports und Floating IPs) in der richtigen Reihenfolge zu erstellen.
Nach 1-2 Minuten sollte Terraform folgende Ausgabe liefern und die Provisionierung erfolgreich beenden:
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
Outputs:
floating_ip = "91.198.2.136"
instance_id = "f6a849c9-1604-4177-93a8-a058336fa223"
private_ip = "172.16.0.78"Unter Outputs sind Informationen zu unserem Server gelistet. Die konkreten Werte unterscheiden sich für deine Ressourcen in der NETWAYS Cloud logischerweise, wichtig ist für uns jedoch das Feld floating_ip, das uns verrät, unter welcher IP wir unseren Server für die nächsten Schritte unseres Cloud Deployments erreichen.
Schritt 2: Installation von Docker
Auf unserem Server in der NETWAYS Cloud müssen wir nun als Nächstes Docker installieren, um mit unserem Cloud Deployment weitermachen zu können. Da wir unseren Server mit Ubuntu Noble 24.04 LTS aufgesetzt haben, können wir uns hierbei an der Installationsanleitung für Docker auf Ubuntu orientieren.
Zuerst verbinden wir uns via SSH mit unserem Server – hierbei geben wir den für die Provisionierung mit Terraform genutzten SSH-Schlüssel an und verbinden uns mit der von Terraform ausgegebenen floating_ip:
ssh -i <ssh-key> ubuntu@<floating_ip>Im Anschluss können wir Docker mit folgenden Befehlen installieren:
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginDie erfolgreiche Installation von Docker können wir mit dem hello-world Image testen:
sudo docker run --rm hello-worldDie Ausgabe sollte wie folgt aussehen:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/Schritt 3: Deployment der Demo-Anwendung
An diesem Punkt angekommen, haben wir alle Voraussetzungen für ein erfolgreiches Cloud Deployment unserer Demo-Anwendung geschaffen: Wir haben einen Server in der NETWAYS Cloud provisioniert, den Zugriff über das Netzwerk mithilfe einer Security Group auf das Minimum beschränkt, und Docker für das Deployment der Anwendung installiert und getestet. Als (vor-)letzten Schritt deployen wir nun die Demo-Anwendung selbst.
Hierfür klonen wir zunächst das Demo-Repository von GitHub auf unserem Server in der NETWAYS Cloud und wechseln in das app/ Verzeichnis:
cd ~
git clone https://github.com/netways-web-services/15-minutes-cloud-deployment
cd 15-minutes-cloud-deployment/appIn diesem Verzeichnis befindet sich der Code der Demo-Anwendung sowie eine compose.yml Datei, mit der wir die Anwendung deployen können – zuvor müssen wir allerdings ein Docker-Image bauen. Die Definition dafür befindet sich im Dockerfile im gleichen Verzeichnis.
sudo docker compose buildNach ein paar Sekunden sollte der Bau des Docker-Images erfolgreich abgeschlossen sein und wir können unsere Demo-Anwendung zum ersten Mal starten:
sudo docker compose upDocker erzeugt daraufhin einige Ausgaben während der Erstellung des Compose-Stacks und zeigt im Anschluss die Logs des soeben gestarteten Containers an. Da wir in unserer compose.yml festgelegt haben, dass der Containerport 5000 auf den Hostport 80 gemappt werden soll, müsste unsere Demo-Anwendung nun unter der Floating IP unseres Servers über einen Webbrowser verfügbar sein. Probieren wir es aus!

Tatsächlich – die Demo-Anwendung ist erreichbar und funktioniert wie erwartet. Unser Cloud Deployment war erfolgreich. Optimal ist es allerdings noch nicht – es fehlt beispielsweise noch ein gültiges TLS-Zertifikat, um via HTTPS auf unsere Demo-Anwendung zugreifen zu können.
Schritt 4: HTTPS-Konfiguration der Demo-Anwendung
Du benötigst eine Domain, für die du einen A Record mit der Floating IP des provisionierten Servers hinterlegen kannst.
Für die automatische Erstellung eines gültigen TLS-Zertifikats sowie die regelmäßige Erneuerung des Zertifikats nutzen wir Traefik, einen Open Source Proxy für Anwendungen, vor Allem populär im Docker- und Kubernetes-Kontext.
Wir deployen Traefik als Teil unseres Compose-Stacks, indem wir unsere Datei compose.yml folgendermaßen anpassen – die zu ändernden Zeilen sind farblich hervorgehoben:
services:
todo-app:
build:
context: ./
ports:
- "5000"
restart: unless-stopped
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.todo-app.rule=Host(`<YOUR_DOMAIN>`)"
- "traefik.http.routers.todo-app.entrypoints=websecure"
- "traefik.http.routers.todo-app.tls=true"
- "traefik.http.routers.todo-app.tls.certresolver=le"
traefik:
image: traefik:latest
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme:/acme
command:
# general confiuration
- "--providers.docker=true"
- "--api.dashboard=false"
# entrypoint configuration
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
# LetsEncrypt configuration
- "--certificatesresolvers.le.acme.email=<YOUR_EMAIL>"
- "--certificatesresolvers.le.acme.storage=/acme/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entryPoint=web"
networks:
- traefik
restart: unless-stopped
networks:
traefik:
Konfiguration von Traefik
Auf den ersten Blick sieht das nach einer Menge Änderungen aus. Im Großen und Ganzen lassen sich diese aber recht kurz zusammenfassen:
Die Änderungen an unserer bereits konfigurierten Demo-Anwendung sorgen für das folgende Verhalten:
- Der Containerport der Demo-Anwendung wird nicht mehr auf den Hostport gemappt – um das Routing kümmert sich jetzt Traefik.
- Die Demo-Anwendung wird in ein Docker-Netzwerk namens traefik deployed, um das Routing zu ermöglichen.
- Die Kriterien für das Routing werden durch labels definiert:
- Der Host (also die URL in unserem Browser) muss dem von uns statt YOUR_DOMAIN gesetzten Wert entsprechen.
Für diese Domain musst du einen A Record für die Floating IP des Servers hinterlegen, den wir in Schritt 1 mit Terraform provisioniert haben. - Die Verbindung muss über HTTPS stattfinden.
- Das für die HTTPS-Verbindung benötigte Zertifikat wird von einem Resolver le bereitgestellt.
- Der Host (also die URL in unserem Browser) muss dem von uns statt YOUR_DOMAIN gesetzten Wert entsprechen.
Der neue Block für traefik beinhaltet ebenfalls einige Optionen:
- Traefiks Containerports werden auf die Hostports 80/443 (HTTP/S) gemappt
- Wir mounten zwei Dateien/Verzeichnisse:
- den Docker-Socket, um die Konfiguration für unsere Demo-Anwendung auslesen zu können.
- ein Verzeichnis
acme/, in dem die Let’s Encrypt Konfiguration gespeichert wird.
- Im Command des Traefik-Services definieren wir die restliche benötigte Konfiguration:
- Wir aktivieren den Docker-Provider und deaktivieren Traefiks Dashboard
- Wir definieren zwei Entrypoints:
- Entrypoint web auf Port 80 (HTTP)
- Entrypoint websecure auf Port 443 (HTTPS)
- TLS-Zertifikate werden durch einen Resolver namens le bereitgestellt, der HTTPChallenges von Let’s Encrypt über den web Entrypoint akzeptiert.
Bitte achte darauf, für YOUR_DOMAIN bzw. YOUR_EMAIL eigene, gültige Werte einzutragen. Andernfalls schlägt das Cloud Deployment fehl bzw. die Demo-Anwendung ist nicht erreichbar.
Sind alle Änderungen vorgenommen, können wir unser Cloud Deployment neu ausrollen. Das übernimmt Docker Compose für Container mit geänderter Konfiguration automatisch:
sudo docker compose up -dDer Moment der Wahrheit ist gekommen – wenn wir alles richtig gemacht haben, sollte unsere Demo-Anwendung jetzt unter https://<YOUR_DOMAIN> verfügbar sein – in meinem Fall wäre das https://todo-app.nws.netways.de.

Unser TLS-verschlüsseltes Cloud Deployment war erfolgreich. Der Browser bestätigt, dass ein gültiges, von Let’s Encrypt ausgestelltes TLS-Zertifikat vorliegt. Unsere wertvollen ToDos sind jetzt also über eine verschlüsselte Verbindung erreichbar.
Nächste Schritte für dein Cloud Deployment
Was dieses Tutorial angeht, sind wir nun am Ende angekommen. Die von uns provisionierte Umgebung muss deshalb aber keineswegs direkt wieder verworfen werden: Die erstellten Ressourcen für Terraform und Docker kannst du nach Belieben ausbauen, deiner Konfiguration anpassen, oder als Vorlage für ein weiteres Cloud Deployment benutzen. Auch Traefik bietet viele weitere nützliche Features, die du erkunden und in deiner Cloud-Infrastruktur nutzen kannst.
Aufräumen der Cloud Deployment Infrastruktur
Wenn du Kosten sparen und die Tutorial-Umgebung wieder aufräumen möchtest, geht das ebenfalls via Terraform:
terraform destroyWie bei terraform apply verlangt Terraform für diesen Vorgang eine Bestätigung, die du mit Eingabe von yes geben kannst. Im Anschluss löscht Terraform die provisionierten Ressourcen in der NETWAYS Cloud, und bestätigt die erfolgreiche Deprovisionierung.
Falls du einen DNS-Eintrag für die Floating IP der Demo-Anwendung eingetragen hast, solltest du diesen ebenfalls löschen.
Weiterführende Ressourcen
Wenn du nach diesem Tutorial Feuer und Flamme für die Cloud, Terraform und Docker bist, dann kannst du dich auf den folgenden Seiten informieren:
- Docker Compose Dokumentation: Lerne, wie du Anwendungen bestehend aus mehreren Services mit nur einer YAML-Datei deployen kannst.
- Terraform OpenStack Provider Dokumentation: Lerne, welche Ressourcen du in der NETWAYS Cloud sonst noch provisionieren kannst.
- Traefik Proxy Dokumentation: Erfahre mehr über Traefik, den cloud-native Anwendungsproxy.
- Let’s Encrypt Website: Auf der Website von Let’s Encrypt erfährst du mehr über ihren kostenlosen Service für TLS-Zertifikate.
- NETWAYS Cloud Dokumentation: In unserer eigenen Dokumentation kannst du dich über die NETWAYS Cloud und unsere anderen Dienste informieren.





0 Kommentare