How to run systemd timer every ten minutes

The syntax to run a systemd timer every ten minutes is:

OnCalendar=*-*-* *:00,10,20,30,40,50:00

i.e. run it on the first second (:00) of every 10th minute (00,10,20,30,40,50).

Posted by Uli Köhler in systemd

How to use git current branch in bash scripts

# Branch is, for example, "main"
export branch=$(git branch --show-current)
Posted by Uli Köhler in git, Linux, Version management

Traefik docker container labels for custom port & ALPN certificate

See our previous post Simple Traefik docker-compose setup with Lets Encrypt Cloudflare DNS-01 & TLS-ALPN-01 & HTTP-01 challenges for the general config we’re using to deploy Traefik. This includes the configuration of the alpn certificate resolver.

If you want to automatically connect Traefik to your docker container on a specific port running on the docker container (17029 in this example), use labels like

    labels:
        - "traefik.enable=true"
        - "traefik.http.routers.my-webservice.rule=Host(`subdomain.mydomain.com`)"
        - "traefik.http.routers.my-webservice.entrypoints=websecure"
        - "traefik.http.routers.my-webservice.tls.certresolver=alpn"
        - "traefik.http.services.my-webservice.loadbalancer.server.port=17029"

 

Posted by Uli Köhler in Traefik

Recommended PostgreSQL docker-compose service configuration

I use the following docker-compose.yml service:

version: '3.5'
services:
  postgres:
    image: postgres
    restart: unless-stopped
    volumes:
      - ./pg_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}

With the following .env:

POSTGRES_DB=headscale
POSTGRES_USER=headscale
POSTGRES_PASSWORD=vah2phuen3shesahc6Jeenaechecee

Using .env has the huge advantage that other services like my backup script can access the configuration in a standardized manner using environment variables.

Posted by Uli Köhler in Container, Databases, Docker

How I run pg_dump in my docker-compose setup

I have the following docker-compose.yml service:

version: '3.5'
services:
  postgres:
    image: postgres
    restart: unless-stopped
    volumes:
      - ./pg_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}

With the following .env:

POSTGRES_DB=headscale
POSTGRES_USER=headscale
POSTGRES_PASSWORD=vah2phuen3shesahc6Jeenaechecee

Given that setup, I run pg_dump like this:

source .env && docker-compose exec postgres pg_dump -U${POSTGRES_USER} > pgdump-$(date +%F_%H-%M-%S).sql
Posted by Uli Köhler in Container, Databases, Docker

How to connect Synology NAS to Headscale

First, install the Tailscale App using the Synology Package manager. Don’t try to initialize using the UI since this will only work with the commercial tailscale service, not with headscale.

Then login to the NAS using SSH (I’m using the admin account) and run sudo su to run

You should see the following shell prompt:

ash-4.4#

Now you can initialize tailscale using the tailscale command similar to our previous post How to connect tailscale to headscale server on Linux. In my case, I needed to use the --reset flag in order for the command to work.

tailscale up --reset --login-server https://headscale.mydomain.com --authkey ... --accept-routes

This will login to your server just like the normal (non-synology) tailscale client does.

Posted by Uli Köhler in Headscale, VPN

How to generate filename containing date & time on the command line

The following snippet is useful for backups to generate a unique yet sortable filename containing both date and time:

mysqldump-$(date +%F_%H-%M-%S).sql

This generates filenames like

mysqldump-2022-03-26_20-47-01.sql

which are compatible with both Windows and Linux as they don’t contain special characters like :

Posted by Uli Köhler in Linux

How to delete all files containing a specific string using ack-grep (ag)

Based on our previous post How to list filenames containing a specific string using ack-grep (ag) this example shows how to delete all files in the current directory containing the string 403 Forbidden.

For example, in order to list filenames containing the string 403 Forbidden, use

ag -0 -l "403 Forbidden" | xargs -0 rm -v

Using ag -0 is neccessary to handle filenames containing spaces correctly.

Posted by Uli Köhler in Linux

How to list filenames containing a specific string using ack-grep (ag)

Use ag -l to list only filenames that contain the given string.

For example, in order to list filenames containing the string 403 Forbidden, use

ag -l "403 Forbidden"

 

Posted by Uli Köhler in Linux

How to list directory with millions of files

ls -1U

 

Posted by Uli Köhler in Linux

ufw: How to allow traffic to all ports on specific interface

sudo ufw allow in on tailscale0 to any

This will allow any traffic (including routed traffic, if packet forwarding is enabled) coming from the tailscale0 interface.

Posted by Uli Köhler in Linux, Networking, VPN

How to install tailscale on Ubuntu

In order to instal tailscale, on any Ubuntu version, you can use the official tailscale install command:

sudo apt -y install curl apt-transport-https
curl -fsSL https://tailscale.com/install.sh | sh
Posted by Uli Köhler in Headscale, Raspberry Pi, VPN

How to install Xen guest utilities on Ubuntu

On Ubuntu 22.04, this package is not available any more and the best way to install it that is known to me at the moment is to use the guest tools ISO.

Install the package using

sudo apt -y install xe-guest-utilities

Now reboot, which will automatically start the management agent service:

sudo reboot

 

Posted by Uli Köhler in Linux, Virtualization

How to get Jitsi meet list of participants using Tapermonkey script

Use this code in Javascript:

APP.conference.listMembers()

If no members are present, this will simply be an empty list:

> APP.conference.listMembers()
[]

But if there is another participant, it will show some info:

> APP.conference.listMembers()
[ci]
0: ci {_jid: '[email protected]/b009ae10', _id: 'b009ae10', _conference: nd, _displayName: 'Foo', _supportsDTMF: false, …}
length: 1

 

Posted by Uli Köhler in Audio/Video, Javascript

How to autojoin Jitsi Meet meeting using Tapermonkey script

This code clicks the join button:

document.querySelector(".prejoin-preview-dropdown-container div[role='button']").click()

By using the correct @match, you can activate this only for a specific conference:

Complete script:

// ==UserScript==
// @name         AutojoinJitsiMeet
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  ?
// @author       You
// @match        https://meet.jit.si/TestAutoJoin
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    document.querySelector(".prejoin-preview-dropdown-container div[role='button']").click()
})();

 

Posted by Uli Köhler in Audio/Video, Javascript

NodeJS typescript simple auto-reload on file change

First install ts-node-dev:

npm i --save-dev ts-node-dev

Then add

"start": "./node_modules/.bin/tsnd --respawn app.ts"

to package.json in the scripts section, example:

{
  "name": "myapp-backend",
  "version": "1.0.0",
  "description": "To make it easy for you to get started with GitLab, here's a list of recommended next steps.",
  "main": "index.js",
  "scripts": {
    "build": "./node_modules/.bin/tsc -b tsconfig.json",
    "start": "./node_modules/.bin/tsnd --respawn app.ts"
  }
  /* ... */
}

 

Posted by Uli Köhler in Javascript, NodeJS

A simple systemd service autoinstall script

I use this in git repositories to ease the deployment process

#!/bin/bash
# This script installs and enables/starts a systemd service
# It also installs the service file
export NAME=MyService

cat >/etc/systemd/system/${NAME}.service <<EOF
# TODO Copy & paste the systemd .service file here
EOF

# Enable and start service
systemctl enable --now ${NAME}.service

The following example automatically installs a docker-compose systemd .service:

#!/bin/bash
# This script installs and enables/starts a systemd service
# It also installs the service file
export NAME=MyService

cat >/etc/systemd/system/${NAME}.service <<EOF
[Unit]
Description=${NAME}
Requires=docker.service
After=docker.service

[Service]
Restart=always
User=root
Group=docker
WorkingDirectory=$(pwd)
# Shutdown container (if running) before unit is being started
ExecStartPre=$(which docker-compose) -f docker-compose.yml down
# Start container when unit is started
ExecStart=$(which docker-compose) -f docker-compose.yml up
# Stop container when unit is stopped
ExecStop=$(which docker-compose) -f docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service
systemctl enable --now ${NAME}.service
Posted by Uli Köhler in Docker, systemd

Fullscreen camera view using libcamera-vid

libcamera-vid --width 1920 --height 1080 -f -t 10000000000

-t 10000000000 means to run for 10000000000 milliseconds (almost 4 months)

Posted by Uli Köhler in Audio/Video, Electronics, Raspberry Pi

How to fix raspistill ERROR: the system should be configured for the legacy camera stack

Problem:

While trying to capture an image using raspistill, you see the following error message

ERROR: the system should be configured for the legacy camera stack

and no image is being produced

Solution 1 (recommended): Use libcamera

Recent versions of Raspbian use libcamera instead of the broadcom legacy camera API. You can capture an image using libcamera-still similarly to raspistill:

libcamera-still -o test.jpg

Solution 2: Enable legacy camera API

If you absolutely need raspistill specifically to work, you can still enable the legacy camera API using rpi-config:

sudo raspi-config

Go to:

  • 3 Interface Config
  • I1 Legacy Camera

and choose Yes to enable the legacy camera API.

Posted by Uli Köhler in Audio/Video, Raspberry Pi

Raspberry Pi libcamera VLC livestreaming (1920×1080)

On the Pi, run

libcamera-vid -t 0 --width 1920 --height 1080 --codec h264 --inline --listen -o tcp://0.0.0.0:8888

On the client, run

vlc tcp/h264://192.168.1.185:8888/

where 192.168.1.185 is the IP address of the Raspberry Pi.

Posted by Uli Köhler in Audio/Video, Raspberry Pi
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPTPrivacy &amp; Cookies Policy