Blog
Notizen, Artikel und Monatsnotizen. Neueste zuerst.
2026
Feedback Loop – about to be closed
Schau an. Das Festival Team hat zurückgeschrieben. Das ist doch mal ein versöhnliches Outcome. Nächstes Jahr mal checken, ob sie es umgesetzt haben. =)
Lieber Gerhard,
vielen Dank für deine ehrliche Rückmeldung. Es tut uns sehr leid, dass du dir Zeit für unser Festival genommen und die Anreise auf dich genommen hast – und am Ende enttäuscht wieder nach Hause fahren musstest.
Dass du an beiden Shuttle-Abfahrtsorten keine ausreichende Orientierung gefunden hast, ist wirklich ärgerlich. Die Anreise hätte für dich unkompliziert sein sollen. Dass dein Festivalbesuch daran gescheitert ist, bedauern wir sehr.
Wir nehmen deine Hinweise zur Beschilderung, zu den Abfahrtsorten und den fehlenden Ansprechpartner:innen vor Ort mit in unsere Nachbereitung, damit wir die Anreise künftig besser organisieren können.
Gerne würden wir dir zumindest eine kleine Festival-Freude nach Hause schicken. Wenn du magst, schick uns deine Postadresse, dann senden wir dir eine Goodie Bag zu. Die verpassten Gespräche und Vorträge ersetzt sie natürlich nicht – wir hoffen aber, dir damit eine Freude machen zu können.
Liebe Grüße
das XXXXXX Festival TeamWünsch dein Barcamp
Interessenabfrage: Was für Barcamps würdest du besuchen?
Sag, zu welchen Themen du ein Barcamp besuchen würdest, wo und wann. Sobald genug zusammenkommen, sehen es Orgas und können eins daraus machen.
barcamp.ioI made (another) thing: Auf barcamp.io kann man sich jetzt sein eigenes Barcamp wünschen. Quasi. Also, du kannst hinterlegen, für was für ein Barcamp in welcher Region du dich interessieren würdest. Das ganze sammel ich (rollierend) über 12 Monate, und alle die wollen, können sich die Ergebnisse nehmen und ein passendes Barcamp veranstalten. Wenn es ein Community-Barcamp ist, werden sogar alle Interessierten des Themas und der Region benachrichtigt.
Festivalfreuden im Hamburger Hafen
Was für eine Woche. Viel zu tun auf der Arbeit, ein wenig Insomnia, spontaner (online) Flight Club am Mittwoch, und dann wollte ich gestern noch auf ein Business-Festival einer Buchhaltungssoftware. Unter anderem Samy Deluxe, Joy Denalane und Max Herre sind aufgetreten (nur ne halbe Stunde, aber…).
Wie es lief? Nun. Hier meine Mail an die Veranstalter*innen:
Hallo liebes XXXXXX Festival Team!
Ich habe mich sehr aufs Festival gefreut. Ich hab mir den Terminkalender halbwegs freigeschaufelt, einen Kollegen versetzt (er wusste Bescheid, keine Sorge) und mich auf den Weg in den Hafen gemacht.
Um 16:10 war ich an der Überseebrücke. Für Ortsfremde vielleicht nicht offensichtlich: Abfahrt an der Überseebrücke kann mehrere Orte meinen, direkt an der Brücke, auf dem Ponton, an den Nebenanlegern oder an der Rückseite der genannten Orte.
Kein Problem. Der Shuttle ist ja sicherlich ausgeschildert.
Nicht.
Hey. Kein Ding. Nachdem mir der Shuttle letztendlich vor der Nase weggefahren ist, dachte ich mir, ich nutze den Shuttle ab Veddel. Zeitlich sollte das ja hinhauen, und da ist es bestimmt besser ausgeschildert.
Nicht.
Zwischen 16:40 und 17:10 keine Abfahrten, keine Busse in Sicht, keine Ausschilderungen, keine Einweiser*innen, keine Karte zur Orientierung. Und es scheint, ich war nicht der Einzige, die anderen stehen bestimmt immer noch da.
Ich habe letzten Endes aufgegeben und fahre jetzt gute anderthalb Stunden wieder nach Hause. 30 Minuten durch den Regen wollte ich dann nicht laufen.
Statt ein paar Goodies, interessante Vorträge und spannende Gespräche abzustauben, werde ich mich nachher nun mit einem Kaltgetränk vor den Monitor hocken und ein wenig Buchhaltung machen.
Ich bin ehrlich: So hatte ich mir das Festival nicht vorgestellt, das war in meinen Augen nicht ideal.
Beste Grüße
GerhardDiplomatenjob wann?
Schrödingers Barcamp
It's a bird! It's a plane! It's a birdplane!!! Ich war auf einem Barcamp. Ich war auf keinem Barcamp. War ich auf einem Barcamp? Um das rauszufinden, müssen wir den Deckel aufmachen: Das erste Neurodiversity Barcamp, wir gehen rein.
LinkedInFirmenevent, aber in extra gut
Wir hatten gerade zwei Tage Firmenevent. Im Frühjahr hatte das Feedback ergeben, dass die Kolleg*innen gerne mehr Zeit für Austausch hätten und dass die vorgeplanten Programmpunkte eher nicht so den Nerv treffen.
Also hatte ich diesmal vorgeschlagen, einen Open Space zu machen. Technisch gesehen eigentlich eher ein Barcamp. So oder so: keine vorgeplanten Inhalte, sondern nur Themen aus der Mitte der Belegschaft.
Dazu der Auftakt mit den Infos, wie es uns als Unternehmen aktuell geht, die Challenges für die nächste Zeit, ein wenig Umstrukturierung, und vor allem eine Frage-Runde an den Management Circle.
Und was soll ich sagen? Das erste Feedback ist überwältigend positiv. Die offizielle Umfrage ist zwar gerade erst rausgegangen, aber es scheint vom direkten Feedback vor Ort her so, dass wir damit tatsächlich einen Nerv getroffen haben.
Gut, ist jetzt nicht so, dass mich das überraschen würde, ich halte das Format ohnehin für das Bestmögliche, was in so kurzer Zeit so viel fürs Wissensmanagement tut.
Übernächste Woche geht es für mich mit dem Agile Barcamp in Leipzig weiter. Und im November dann auch schon mit meinem KANBANcamp.
Hatte ich schon erwähnt, dass ich aktuell auf einer Barcamp-Mission bin? =)
Mein Profil auf barcamp.io
Gørd zu Elbblick, Hamburg. Frag mich zu Barcamps, Kanban, koreanischem Essen.
barcamp.ioMein Artikel zum #bcnue26 muss leider noch ein, zwei Tage warten. Dafür hab ich heute die Profilfunktion auf barcamp.io ein wenig aufgebohrt.
Wer ist wieder da? Ni… Na, ich!
Ich kann gar nicht sagen, warum, aber ich habe wieder Bock aufs Bloggen. Mehr braucht’s eigentlich auch gar nicht. Ich will das hier nicht overengineeren, die Seite ist pures HTML, wird lokal generiert und dann hochgeladen. Einfacher geht es eigentlich gar nicht.
Themen? Wie gehabt: Bisschen was aus meinem Hauptjob, bisschen was aus meiner Freiberuflichkeit, inklusive der Lehre an der iu, und bisschen was aus meinem Gewerbe, zum Beispiel über Barcamps, barcamp.io und das KANBANcamp.
Und natürlich ganz viel Privates. Meinung. Politik und Gesellschaft. Und vor allem Musik.
Wie lange ich diesmal durchhalte? Keine Ahnung. Ne Woche? Einen Monat? Ein Jahr? Ewig? Abwarten.
Ich bin wieder da. Ohne Nina! Nina!
2024
Nextcloud with Docker and NGINX on Ubuntu 22.04
There are a ton of cloud storage providers out there including the large players: Dropbox, OneDrive, Apple Cloud and so on. Though some of these have pretty good security, the files in those storages are still accessible to the admins of said services – and in extension to governments and other third party actors.
Do I have anything to hide? No. Do I want the government or random hackers and script kiddies looking at my personal picture archives? No again. So a self-hosted solution is the way to go.
Enter Nextcloud, an ownCloud fork. I decided to run the Docker version behind an NGINX proxy server.
It’s pretty simple this time, let’s jump into it!
Step 1 – Install Docker and docker-compose
We will use
sudo,aptandapt-getfor this. All these tools usually come with Ubuntu, so no need to install them. Let’s grab us some nice Docker stuff.# Make sure everything is up to date sudo apt update # Get stuff sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common # Get ourselves some sweet gpg keys for docker curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # Add the Docker repository sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # Get Docker sudo apt update && sudo apt-get install docker-ce docker-ce-cli containerd.io # Get docker-compose (you may need to adjust the version number, 'v2.24.5') … sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # … and make it writeable sudo chmod +x /usr/local/bin/docker-composeIn addition, you might need to add the server user for the website to the Docker group (and create a docker group, if not in place already):
sudo groupadd docker sudo usermod -aG docker usernameobviouslyuseyourwebsiteusernamehereThat’s all the installation stuff server-wise. Next, let’s set up NGINX.
Step 2 – Set up NGINX
Let’s create a configuration file for the webpage (or add a new server to an existing configuration file).
/etc/nginx/sites-available/example.comserver { server_name cloud.example.com; # Website URL root "/var/www/example.com/cloud.example.com"; # Website Folder location / { proxy_pass http://localhost:3000/; # Port as set in docker-compose (we'll do this later) proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; } location = /.well-known/carddav { return 301 $scheme://$host/remote.php/dav; } location = /.well-known/caldav { return 301 $scheme://$host/remote.php/dav; } listen 80; }At this point you’d typically make sure to add a certificate, e. g. utilising
certbot --nginxto do so. I won’t cover that here.Step 3 – Add docker-compose.yml and db.env
Let’s start with the
docker-compose.ymlfile. You can copy it from here, just make sure to use a free port. 30xx should be fine. Usenetstat -tunlep | grep LISTEN | awk '{print $4}'to make sure.version: '3' services: db: image: mariadb command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW restart: always volumes: - ./db:/var/lib/mysql env_file: - db.env redis: image: redis restart: always app: image: nextcloud:latest build: ./app restart: always ports: - 127.0.0.1:3000:80 # remember the port (3000) in the nginx file? # Make sure this one is the same. And it's not in use, of course. volumes: - ./nextcloud:/var/www/html environment: - MYSQL_HOST=db env_file: - db.env depends_on: - db - redis cron: build: ./app restart: always volumes: - ./nextcloud:/var/www/html entrypoint: /cron.sh depends_on: - db - redis volumes: db: nextcloud:Save and add another file, this time
db.env:db.envMYSQL_ROOT_PASSWORD=UseSomeCrypticPasswordHere MYSQL_PASSWORD=UseAnotherCrypticPasswordHere MYSQL_DATABASE=nextcloud MYSQL_USER=nextcloudStep 4 – Add the Dockerfile and the redis configuration file
Create a folder named
appin your site directory, and add two files to it.mkdir app cd app touch Dockerfile touch redis.conf.phpAdd some content to those files.
app/DockerfileFROM nextcloud:apache COPY redis.config.php /usr/src/nextcloud/config/redis.config.phpapp/redis.config.php<?php $CONFIG = array ( 'memcache.local' => '\\OC\\Memcache\\Redis', 'memcache.locking' => '\\OC\\Memcache\\Redis', 'filelocking.enabled' => 'true', 'redis' => array( 'host' => 'redis', 'port' => 6379, ), );Step 5 – Cross your fingers and …
… run
docker-compose.docker-compose upCheck the output for errors. If you don’t see any, terminate the containers with Ctrl-C (once!).
Step 6 – Fire up a detached container
Run docker-compose again, so it starts some detached containers. Head to your website, and you should be able to follow the frontend installation process.
docker-compose up -dIf everything went well, you should have a running Nextcloud instance. If not, let me know and I might add more to this tutorial.
2023
WordPress with NGINX, PHP-FPM and MariaDB (for MySQL) on Ubuntu 22.04
There are a lot of ways to run WordPress. Here is the one I chose, maybe it helps you as well. If you have any questions, don’t hesitate to leave them in the comments. I will try my best to help you out. I am assuming you install this on your own server and have root access, or at least sudo access with your account.
That being said: Let’s jump into it!
- Step 1 – Install packages
- Step 2 – Set up the database
- Step 3 – Set up PHP-FPM
- Step 4 – Install WordPress
- Step 5 – Configure WordPress
- Step 6 – Set up NGINX
Step 1 – Install packages
Before you start installing and configuring WordPress, you need to make sure you have all the tools you need. Use apt to install all the needed packages:
sudo apt install software-properties-common sudo add-apt-repository -y ppa:ondrej/php sudo apt update sudo apt install nginx sudo apt install php-fpm sudo apt install mariadb-serverStep 2 – Set up the database
The next step is setting up the database. This should be done rather quickly. All you need to do is login to mysql.
sudo systemctl status mariadb # check if mariadb is up and running sudo mariadbIf you have set a password for mysql, use the interactive mode instead.
sudo systemctl status mariadb # check if mariadb is up and running sudo mariadb -u root -p“Inside” we need to create a database, a user and then grant the needed privileges for the database to the generated user.
mariadbCREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON wordpress.* TO 'user'@'localhost'; QUIT;You can change the database name, user and password as you like. Make sure to jot them down, you will need them later.
Step 3 – Set up PHP-FPM
For this you will use PHP-FPM to handle everything php, passed on by NGINX. This utilizes a pool, for that we need to create a file in
/etc/php/8.2/fpm/pool.d. Replace “8.2” with the version of php that you are using.php -v # find out which php-version you are using, I will use 8.2 here sudo vim /etc/php/8.2/fpm/pool.d/example.com.conf # replace <example.com> with your domain or anything you likeIn that file is the configuration for php, if used through the FastCGI Process Manager (FPM). Here is an example configuration. Remember to activate the vim insert mode by typing
i, before you paste it in./etc/php/8.2/fpm/pool.d/example.com.conf[examplecom] ; change to a unique name ; replace with the user and group of your php files: user = example_com group = example_com ; replace example-com with your domain listen = /run/php/example-com-fpm.sock ; should be user and group of your web server, probably leave it be: listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 120 pm.start_servers = 12 pm.min_spare_servers = 6 pm.max_spare_servers = 18 clear_env = no php_admin_value[opcache.save_comments] = 1 php_admin_value[opcache.interned_strings_buffer] = 16 php_admin_value[opcache.revalidate_freq] = 60 php_admin_value[opcache.validate_timestamps] = 0 env[HOSTNAME] = $HOSTNAME env[PATH] = /usr/local/bin:/usr/bin:/bin env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp ; you can use your domain here as well php_admin_value[error_log] = /var/log/fpm-php.example-com.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 1GThat should do it. Write to the file and exit vim by typing
:wq. After that, restart PHP-FPM.sudo systemctl restart php8.2-fpmStep 4 – Install WordPress
Change into your web root folder and create a folder for your page. Change path and folder name as needed. If you do not know how to do this, you probably should not have root access, tbh. … 😬
mkdir /var/www/html/example.com cd /var/www/html/example.comIn that folder, download wordpress and untar it.
wget https://wordpress.org/latest.tar.gz tar --strip-components=1 -xvzf latest.tar.gz rm latest.tar.gzNote that
--strip-components=1strips the first part of the files’ paths, in this case the folderwordpressit would normally extract into.That should do it for now, next we need to configure your WordPress.
Step 5 – Configure WordPress
We will do this by editing the wp-
config.phpwith our editor of choice, which of course is vim.cp wp-config-sample.php wp-config.php vim wp-config.phpWe’ll make it a short one, of course you can keep all the comments in there. If you want to put in more stuff, you can find a generator at generatewp.com.
Link for the salt: api.wordpress.org
wp-config.php<?php /* MySQL settings */ define( 'DB_NAME', 'wordpress' ); // database from step 2 define( 'DB_USER', 'user' ); // user from step 2 define( 'DB_PASSWORD', 'password' ); // password from step 2 define( 'DB_HOST', 'localhost' ); define( 'DB_CHARSET', 'utf8mb4' ); /* MySQL database table prefix. */ $table_prefix = 'wp_'; /* Authentication Unique Keys and Salts. */ /* head to https://api.wordpress.org/secret-key/1.1/salt/ and copy it here */ define('AUTH_KEY', 'I$RCe|Avd6q<^q~}r@!mwq^ds-f+{po'); define('SECURE_AUTH_KEY', '3.}i|OH|UEG3Ap|p#bJ+P{P%4N-WP)^'); define('LOGGED_IN_KEY', '0(a gw|-/d7z3T=yN)fh?WD,sWCjDD%'); define('NONCE_KEY', 'm}(s:T%xu]gwKgwuHcThe_TEY9l7v_?'); define('AUTH_SALT', 'JrRb)}~KaZcL5P?v|)h{m$(:m!wb9EU'); define('SECURE_AUTH_SALT', 'enY94*k/e80(F]]_+Z}4as|B&+KX)b1'); define('LOGGED_IN_SALT', '=;ir6WRQj,ahn=5$? /h6|~&%0QWg=q'); define('NONCE_SALT', 'c&hjS7e9xe{x*ip=7LoYMO@|t4d`w5B'); /* Absolute path to the WordPress directory. */ if ( !defined('ABSPATH') ) define('ABSPATH', dirname(__FILE__) . '/'); /* Sets up WordPress vars and included files. */ require_once(ABSPATH . 'wp-settings.php');Aaaand with that done, all we finally need to do is configure NGINX to do what it’s supposed to do.
Step 6 – Set up nginx
In order to do that, we are going to create a file in the
sites-availablefolder of NGINX.sudo vim /etc/nginx/sites-available/example.com/etc/nginx/sites-available/example.comserver { listen 80; root /var/www/html/example.com; # replace example.com index index.php index.html index.htm; server_name example.com; # replace example.com client_max_body_size 500M; location / { try_files $uri $uri/ /index.php?$args; } location = /favicon.ico { log_not_found off; access_log off; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~ \.php$ { include snippets/fastcgi-php.conf; # replace example-com-fpm with socket from step 3 fastcgi_pass unix:/var/run/php/example-com-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }Save it with
:wq, link theexample.comfile from/etc/nginx/sites-enabled, test and restart NGINX.sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginxThat’s it. Head to
example.comand finish the installation from the web installer. Happy blogging!Edit: You still need to install a Certificate for the website, but that's not part of this post. If you need any help with that, let me know and I will add a tutorial for Let's Encrypt.Batch change permissions for folders and files
If you ever need to change permissions for a bunch of folder and/or files without a GUI, you can utilize find and xargs to achieve that in the shell in a flash:
find -xtype d | xargs chmod 755 # directories, standard permissions find -xtype f | xargs chmod 644 # files, standard permissions find -xtype d | xargs chmod 775 # directories, writeable for group find -xtype f | xargs chmod 664 # files, writeable for groupBasically what we are doing here is using
findto find every directory or file, depending on the type. The optionxtype, followed bydorf, helps us limit the (recursive) search to directories and files respectively.xtypeincludes symbolic links into the results, whiletypewould not. the resulting directory/file names are then piped intoxargs, which applies the command it is followed by (here:chmod 755andchmod 644) to the list it receives from the pipe.#1476107295 TYPO3\CMS\Core\Error\Exception
I ran into a a small problem after activating the TYPO3 debug mode in my ddev TYPO3 development installation. When opening the Configuration Presets again, I was greeted with the following error:

Something went wrong Please use Check for broken extensions to see if a loaded extension breaks this part of the install tool and unload it. The box below may additionally reveal further details on what went wrong depending on your debug settings. It may help to temporarily switch to debug mode using Settings > Configuration Presets > Debug settings. If this error happens at an early state and no full exception back trace is shown, it may also help to manually increase debugging output in %config-dir%/system/settings.php:['BE']['debug'] => true, ['SYS']['devIPmask'] => '*', ['SYS']['displayErrors'] => 1,['SYS']['exceptionalErrors'] => 12290Upon investigating the Ajax error shown below the message I saw it was throwing an exception:
/typo3/module/tools/settings(1/1) #1476107295 TYPO3\CMS\Core\Error\Exception PHP Runtime Deprecation Notice: str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated in /var/www/html/vendor/typo3/cms-install/Classes/Configuration/Image/ImageMagick6Preset.php line 85Instead of increasing the debugging output as suggested, I guessed that – short of fixing the underlying function – deactivating deprecation notices would do the trick for now, hoping that the TYPO3 devs will fix this in an upcoming release. So I jumped into the console, navigated to
/config/systemand edited the fileadditional.php, and found the following lines:/config/system/additional.php'SYS' => [ 'trustedHostsPattern' => '.*.*', 'devIPmask' => '*', 'displayErrors' => 1, ],A little addition, and everything worked out fine:
/config/system/additional.php'SYS' => [ 'trustedHostsPattern' => '.*.*', 'devIPmask' => '*', 'displayErrors' => 1, 'exceptionalErrors' => 8191 ],I might need to adjust this, if other errors show up, but for now it’s fine. On the downside I will not catch any deprecated stuff for now, but I can live with that.
Documentation used: