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
).
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
).
# Branch is, for example, "main" export branch=$(git branch --show-current)
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"
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.
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
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.
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 :
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.
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"
ls -1U
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.
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
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
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
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() })();
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" } /* ... */ }
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
libcamera-vid --width 1920 --height 1080 -f -t 10000000000
-t 10000000000
means to run for 10000000000
milliseconds (almost 4 months)
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
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
If you absolutely need raspistill specifically to work, you can still enable the legacy camera API using rpi-config
:
sudo raspi-config
Go to:
and choose Yes to enable the legacy camera API.
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.