How to Install a Private Docker Registry on Raspberry Pi with Portainer (Home Network)
Run your own private Docker image registry on a Raspberry Pi using Portainer. This guide uses HTTP only (no TLS) with basic auth enabled. You will deploy the registry and a web UI via a Portainer Stack, configure clients to allow an insecure registry, and verify everything works on your home network. Note: A registry is the server (e.g., registry:2). Repositories are image collections inside the registry. TL;DR Image: registry:2 Runs on LAN over HTTP: :5000 (no TLS) UI: joxit/docker-registry-ui:latest on :5001 Auth: htpasswd basic auth Persist storage: bind mount /var/lib/registry Clients: add 192.168.1.100:5000 to Docker insecure-registries Prerequisites Raspberry Pi 4/5 (ARM64 preferred) Raspberry Pi OS 64‑bit or another 64‑bit Linux Docker and Portainer CE installed on Raspberry Pi A stable hostname or IP (e.g., 192.168.1.100) Check architecture: ...
How to Self-Host n8n on Raspberry Pi 4 (ARM64) with Docker Compose
This guide shows a clean, reliable way to run n8n on a Raspberry Pi 4 using Docker Compose. Note: I want to use this setup primarily for AI workflows (transcription, summarization, RAG, content drafting). TL;DR / Quick start Check architecture (arm64 preferred): uname -m # aarch64 -> 64-bit, armv7l -> 32-bit Create docker-compose.yml using the snippet below. Set WEBHOOK_URL, GENERIC_TIMEZONE, and TZ for your locale. Start: docker compose up -d Open: http://raspi.local:5678 (or your Pi’s IP) Logs: docker compose logs -f n8n — Stop: docker compose stop What is n8n? n8n is an open‑source, self‑hostable workflow automation tool. You build automations by connecting nodes in a visual editor: triggers (webhooks, schedules/cron, IMAP, polling) start a workflow; you transform data, branch logic, handle errors, and call services/APIs or databases. It’s ideal for glue code and recurring tasks without writing and deploying full apps. ...
Pass Docker Env Variables to Vite Containerized Vue.js on Docker Run
Environment variables can only be used in Vue.js applications at build time and the variables are hardcoded in javascript files during build. When you build docker image for the Vue.js application, you use the same image for test and production environments. But the Vue.js application config values can be different in test and production environments. For example: api url configuration value. Since the variables are different in those environments you must pass the configuration values for test and production environments at docker run: ...
How to Transfer Files with scp on Linux
Need to copy files to a headless Raspberry Pi over SSH? The scp command lets you securely transfer files and folders between machines on Linux. This guide covers local↔remote and remote↔remote copies, plus useful flags. What is the scp command? scp (secure copy) securely transfers files over an SSH connection. It uses the same authentication and encryption as SSH. In plain terms, scp is like copying a file from one folder to another, except the other “folder” is a computer you can reach over SSH. It’s simple, fast to use for everyday tasks, and available on most Linux and macOS systems by default. ...
Typescript: Extend Array type with sum count avg min max Aggregates
In this article i’ll show you how to implement sum, count, avg, min and max aggregate functions that applies to all Array instances in typescript. First we will learn how to extend Array type: Extend Array prototype In javascript, you can extend an existing class by adding a new function to its prototype without modifying its source code. To add new function to Array type, you basically set the new function to Array.prototype.<functionName> and you can use the new function for all the instances of the class you create. ...
How to Reduce Node.js Docker Image Size?
I had a web application which is written in Node.js and I wanted to dockerize it. So went to the Node.js official site and found Dockerizing a Node.js web app article. I created the Dockerfile as it says in the article. Then I built the docker image with docker build, the created image size was 1.09GB Dockerfile which produce 1.09GB docker image FROM node:18 # Create app directory WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ RUN npm install # If you are building your code for production # RUN npm ci --omit=dev # Bundle app source COPY . . EXPOSE 8080 CMD [ "node", "server.js" ] Bigger images requires disk space and downloading them takes longer time. 1GB size was too big for me and i thought it could be reduced and investigated. ...
Build Multi-Platform Docker Images with Docker Buildx
Intro I developed a Node.js application and wanted to run it on a Raspberry Pi in a Docker container. I built a Docker image on my x64 laptop (Ubuntu) and pushed it to Docker Hub. On the Raspberry Pi, I pulled the image and tried to run the container — but it failed with exit code 139. Problem By default, docker build creates an image for the architecture of the machine you build on. In my case, I produced an amd64 image on an amd64 machine. A Raspberry Pi 3 Model B typically runs a 32‑bit OS, so it expects linux/arm/v7 (armhf). It will only use linux/arm64 if you run a 64‑bit OS. The architecture mismatch caused the runtime error. ...
Managing Multiple Github Accounts with Git Credential Manager
If you have more than one github account and want to contribute your projects from one computer, you can manage accounts using git credential manager. Step 1 Install git credential manager. (You can read install instructions) For debian users, download the latest .deb package, and run the following: sudo dpkg -i <path-to-package> Step 2 Configure git credential manager: git-credential-manager configure Output Configuring component 'Git Credential Manager'... Configuring component 'Azure Repos provider'... Step 3 To configure Git to cache credentials for the full remote URL of each repository you access on GitHub, enter the following command. ...
Ubuntu: Fix Touchpad Tap-to-Click via Xorg (libinput)
Problem Tap-to-click on the touchpad was not working after I installed Ubuntu. Here are quick and advanced fixes. Note: This guide’s fix targets Xorg. Under Xorg, the libinput driver reads options from xorg.conf.d, so we can enforce Tapping system-wide. On Wayland, these options are managed by GNOME; use the GUI toggle instead—Xorg configs do not apply to Wayland sessions. TL;DR / Quick start Wayland/GUI: Settings → Mouse & Touchpad → enable “Tap to Click”. Xorg (terminal): create config and enable tapping, then re-login. # Create config dir and write touchpad config sudo install -d /etc/X11/xorg.conf.d/ sudo tee /etc/X11/xorg.conf.d/30-touchpad.conf >/dev/null <<'EOF' Section "InputClass" Identifier "libinput touchpad" MatchIsTouchpad "on" MatchDriver "libinput" Driver "libinput" Option "Tapping" "on" Option "TappingButtonMap" "lmr" EndSection EOF # Reboot or log out/in, then verify grep -i "Using input driver 'libinput'" /var/log/Xorg.0.log || \ grep -i "Using input driver 'libinput'" ~/.local/share/xorg/Xorg.0.log || \ sudo journalctl -b _COMM=Xorg | grep -i "Using input driver 'libinput'" Quick fix (GUI/Wayland) If you use Wayland or the default GNOME session: ...
Firefox Executable File not Found in $PATH for Flatpak on Linux
Intro When an application is installed via apt package management tool, you can start running the application when you type the application name in terminal, for example firefox. But when you install the application with Flatpak utility you must run the Flatpak application using this command: flatpak run org.mozilla.firefox Problem But when i want to authenticate my command-line sessions with GitHub using Github CLI Tool command gh auth login with HTTPS protocol and Login with a web browser options, i get this error: ...