Kategorien
Allgemein

Willkommen 2020

Das Team von Develovers wünscht euch einen guten Start ins neue Jahr und möchte auch dieses Jahr einen sinnvollen Überblick über die Bewegungen in der Webentwicklungs-Welt berichten.

Und nicht nur hier, auch beruflich hat sich (für mich) ein bisschen was verändert, mal schauen ob das hier abfärbt, aber ich denke eher nicht, mein Aufgabenfeld bleibt auch beim neuen Arbeitgeber recht ähnlich.

Ich wünsche mir für 2020 auf jeden Fall Zeit für ein paar Feature-Posts, die ich letztes Jahr nur sehr begrenzt hinbekommen habe. Außerdem hoffe ich, eine bessere Kontinuität bei den Wochenberichten zu schaffen, das war ja zwischendrin zeitlich auch eher etwas durcheinander. Dazu habe ich mir ja mittlerweile Hilfe gebaut.

Dafür hat der Kollege Alex dann letztes Jahr ein paar Dinge zu PHP und Docker gepostet, was ich sehr großartig fand.

Ich bin auf jeden Fall gespannt, wie es dieses Jahr weiter geht.

Kategorien
Allgemein Code Werkzeuge

Running PHP with Docker

As a developer who works on multiple projects you often need different PHP versions for running tests or installing Composer packages.

I created a little Bash script that runs Docker for executing PHP in your project context. The script looks like this (don’t be scared, I will walk you through it step by step):

#!/usr/bin/env bash

phpVersion=7.2
remainingArguments="$@"

if [[ "$1" =~ (5.6|7.0|7.1|7.2|7.3) ]]; then
    phpVersion=$1
    remainingArguments="${@:2}"
fi

echo "Using PHP version $phpVersion"

docker run  --interactive --rm --tty \
    --user $(id -u):$(id -g) \
    -v ${HOME}/.ssh:${HOME}/.ssh:rw \
    -v ${SSH_AUTH_SOCK}:/ssh-auth.sock \
    --env SSH_AUTH_SOCK=/ssh-auth.sock \
    -v /etc/passwd:/etc/passwd:ro \
    -v /etc/passwd:/etc/group:ro \
    -v ${HOME}/.config/composer:${HOME}/.config/composer:rw \
    -v ${HOME}/.cache/composer:${HOME}/.cache/composer:rw \
    --env COMPOSER_CACHE_DIR=${HOME}/.cache/composer \
    --env COMPOSER_HOME=${HOME}/.config/composer \
    -v "$(pwd)":"$(pwd)":rw -w "$(pwd)" \
    --add-host db:127.0.0.1 \
    --net=host \
    intera/docker-ci-php:${phpVersion}-ubuntu \
    php${phpVersion} ${remainingArguments}

The script can be used like this:

php.sh 7.3 vendor/bin/phpunit

The first argument 7.3 is the PHP version. After that you can provide the arguments to the PHP command. The example above would run phpunit with PHP version 7.3.

You can also omit the PHP version argument and it will use the default PHP version that is defined in the script. The following command executes phpunit with PHP 7.2:

php.sh vendor/bin/phpunit

Argument Handling

The first block of the script handles the PHP version switching and extracting the remaining arguments that should be passed on to the PHP command.

By default PHP 7.2 is used and all arguments are passed on:

phpVersion=7.2
remainingArguments="$@"

If the first argument is a known PHP version it overwrites the default version and is removed from the arguments that are passed on:

if [[ "$1" =~ (5.6|7.0|7.1|7.2|7.3) ]]; then
    phpVersion=$1
    remainingArguments="${@:2}"
fi

The docker command parts

Let’s walk though the different parts of the docker command.

The first parameters will start an interactive terminal. Without them you won’t get nicely colored output:

--interactive --tty

The container is removed after the command is finished:

--rm

We switch the user and group to the currently logged on user to prevent permission problems. We also need to mount /etc/passwd and /etc/group. Otherwise the container would not know about the name of the current user and his groups. These volumes can be read-only (:ro).

--user $(id -u):$(id -g) \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/passwd:/etc/group:ro \

The Composer directories from the user’s home directory are mounted to make sure the Composer cache is persisted and it has access to its config:

-v ${HOME}/.config/composer:${HOME}/.config/composer:rw \
-v ${HOME}/.cache/composer:${HOME}/.cache/composer:rw \
--env COMPOSER_CACHE_DIR=${HOME}/.cache/composer \
--env COMPOSER_HOME=${HOME}/.config/composer \

The current directory is mounted as a volume and the working directory of the Docker command is changed to this directory. Without access to your project files executing PHP would not make much sense 😉

Important! Please be aware that all files required by PHP (or Composer) must be subfolders of the current working directory. Symlinks that point outside that folder will not work.

-v "$(pwd)":"$(pwd)":rw -w "$(pwd)" \

The network part

In some of my (TYPO3) projects a Composer script is executed after install / update that needs access to the database (TYPO3 Console).

The database is running in a docker container and its port is mapped to my localhost. This allows me to use the following configuration:

--net=host \
--add-host db:127.0.0.1 \

The net=host option connects the container with the host network which allows it to access the database.

With add-host you can add additional hostname entries. In my case the Docker container running the database is called db which is also used as database hostname in the application config. With the entry above the db host will be resolved to your localhost.

The SSH part

This part is only required when you need SSH authentication. A common use case is loading private Git repositories via Composer.

The .ssh folder is mounted from the user’s home directory. This gives us access to the SSH config, the key files and the known_hosts file. You might be able to change this to a read-only volume when neither of these two conditions apply:

  • not all SSH hosts are present in your known_hosts file and SSH needs to update it
  • you are using a persistent SSH connection (ControlMasterControlPathControlPersist) and its path is located in your ~/.ssh folder

We also forward the socket of your SSH agent to use passwordless authentication:

-v ${HOME}/.ssh:${HOME}/.ssh:rw \
-v ${SSH_AUTH_SOCK}:/ssh-auth.sock \
--env SSH_AUTH_SOCK=/ssh-auth.sock \

The image

The Docker image is custom made and based on Ubuntu and the awesome PPA of Ondřej Surý.

It is publicly available on Docker Hub in PHP version 5.6 to 7.3.

The tag is switched depending on the selected PHP version.

Of course you can use your own image.

intera/docker-ci-php:${phpVersion}-ubuntu \

The PHP command (finally!)

The PHP command is switched based on the selected PHP version.

Finally the arguments passed to the command are forwarded to Composer.

php${phpVersion} ${remainingArguments}

Composer addon

The Docker images described above already contain a Composer executable at /usr/local/bin/composer.phar. This is an example to make use of it:

php.sh /usr/local/bin/composer.phar install

You can make your life even easier when you wrap the command above in another shell script that directly calls Composer:

#!/usr/bin/env bash

THIS_SCRIPT_DIR="$( cd "$( dirname `readlink -f "${BASH_SOURCE[0]}"` )" >/dev/null && pwd )"

phpVersion=7.2
remainingArguments="$@"

if [[ "$1" =~ (5.6|7.0|7.1|7.2|7.3) ]]; then
    phpVersion=$1
    remainingArguments="${@:2}"
fi

${THIS_SCRIPT_DIR}/php.sh ${phpVersion} /usr/local/bin/composer.phar ${remainingArguments}

Now you can just call

composer.sh install

SELinux

There might be issues with Linux distributions using SELinux.

I will publish another article soon that will provide solutions to these problems.

Kategorien
Allgemein Werkzeuge

Automate all the things

Wer hasst es nicht, Arbeiten doppelt und dreifach zu machen? Ich habe in der letzten Zeit den Wochenbericht meistens gerade so fertig bekommen und das ein oder andere Mal eben auch nicht.

Meine Idee war eigentlich von Anfang an, das ganze soweit wie möglich zu automatisieren. Nicht das Kuratieren, sondern das posten. Kleinteiliges Sammeln die Woche mit einem Tool der Wahl, am besten dann automatisiert posten. Und das dann auch automatisch bei Twitter, LinkedIn und Xing veröffentlichen. Ein Traum wäre das.

Nun bin ich vor ein paar Wochen über Nodemation und Node-RED gestolpert und der Plan schien fast aufzugehen. Ich habe nach einer Einarbeitung die letzten 2 Wochen viel über den Workflow mit NodeRED gelernt und hatte das ganze fertig bis auf den letzten Schritt (und einigem Fehlerhandling):

Fertig

  1. Subreddit abfragen und die Links zusammenführen
  2. RSS Feeds von Monkeyuser und Commitstrip abrufen und nur Einträge neuer als 7 Tage mitnehmen
  3. Alles zusammen in einem Template als OL und P nach dem bekannten Muster zusammenfassen.
Screenshot meines Vorbeitungs-Workflows

Unfertig

  1. Posten an WordPress. Dazu müsste ich in dem Flow auch Authentication handlen um die WP-Rest-API zu bespielen. Das ist ein größeres Problem als Anfangs gedacht.
  2. Posten verhindern und mich benachrichtigen, wenn zuwenig Links im Subreddit sind oder kein „Was zum Lachen“ aus den beiden Blogs ermittelt werden kann.

Pareto: Automate erstmal half the things.

Danach bin ich auf das Dashboard-Modul von Node-RED gestoßen und habe das ganze dann als Dashboard-Widget umgesetzt. Damit sind die Probleme bzw. unfertigen Teile auch direkt abgehakt, denn ich bekomme einen Artikel-Entwurf in dem Dashboard generiert, den ich dann nur ins WordPress kopieren muss und ggf. korrigieren kann.

Natürlich muss ich Überschrift, Tags und Bild noch per Hand vergeben. Aber das Links hin- und herkopieren und suchen kann ich mir sparen. Der letzte Wochenbericht ist bereits mit dieser Unterstützung von Node-RED entstanden.

Den Pfad mit dem automatischen Posten habe ich allerdings noch nicht ganz aufgegeben, wie man dem Screenshot oben entnehmen kann.

Setzt ihr Projekte oder ähnliche Workflows mit Automatisierungstools um? Wenn ja, habt ihr Lust, diese hier zu präsentieren?

Kategorien
Allgemein

Wir sind umgezogen

Wir sind zu einem neuen Hoster gewechselt, sollte hier etwas komisch sein, sagt uns bitte Bescheid.

Kategorien
Allgemein

Selbstversuch: Agile Family #2

Eigentlich wollte ich ja ein 1-Monats und ein 2-Monats-Fazit  schreiben. Aber erstens kommt es anders und zweitens als man denkt. Die letzten Monate waren für uns beide ein harter Ritt. Beruflich und persönlich. Wir haben nicht aufgegeben, mussten aber klar feststellen, dass unsere Schritte zur besseren Organisation kleiner waren (und vorerst vermutlich auch bleiben werden), als erhofft.

Aber auch das gehört ja eben auch zu einer agilen Vorgehensweise: Inspect & Adapt. Warum also nicht auch hier?