Want to get your bash shell in a running docker container?
run: deit application
(deit, as in: ‘Docker Exec -IT’)
and will show you all running containers which have ‘application’ in the name.
Add the following function to your ~/.bashrc or ~/.zshrc
# Function to display matching containers and allow user selection
function deit {
container_query="$1"
shift 1
container_command="${@:-bash}" # Default to 'bash' if no command is provided
# Get the list of matching container names
matching_containers=($(docker ps --format '{{.Names}}' | grep "$container_query"))
count=${#matching_containers[@]}
if [ "$count" -eq 0 ]; then
echo "No containers found with '$container_query' in the name."
return 1
elif [ "$count" -eq 1 ]; then
container_name="${matching_containers[0]}"
echo "Found container: $container_name"
echo "Executing: docker exec -it $container_name $container_command"
docker exec -it "$container_name" $container_command
else
echo "Multiple containers found with '$container_query' in the name:"
for i in "${!matching_containers[@]}"; do
echo "$((i + 1)). ${matching_containers[i]}"
done
while true; do
read -p "Choose the number of the container you want to use: " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
container_name="${matching_containers[$((choice - 1))]}"
echo "Selected container: $container_name"
echo "Executing: docker exec -it $container_name $container_command"
docker exec -it "$container_name" $container_command
break
else
echo "Invalid choice. Please try again."
fi
done
fi
}
Works on other versions of Ubuntu as well.
Let’s install PHP8.1, PHP8.2 and PHP8.3 on our Ubuntu machine.
Add the following script as ~/install-multiple-php-versions.sh
.
#!/bin/bash
# file: ~/install-multiple-php-versions.sh
# Check if the Ondřej Surý PPA repository is already added
if ! grep -q "ondrej/php" /etc/apt/sources.list /etc/apt/sources.list.d/*; then
echo "Adding Ondřej Surý PPA repository to get the latest PHP versions..."
sudo add-apt-repository -y ppa:ondrej/php
sudo apt update
fi
# Function to install a PHP version
install_php_version() {
local version="$1"
sudo apt install -y "php$version" "php$version-cli" "php$version-fpm" "php$version-common" "php$version-zip" "php$version-mbstring" "php$version-opcache"
}
# Start installation message
echo "Starting installation of PHP versions..."
# Install different PHP versions
versions=("8.0" "8.1" "8.2" "8.3")
for version in "${versions[@]}"; do
install_php_version "$version"
echo "PHP $version installed successfully."
done
# Completion message
echo "All PHP versions have been installed successfully."
# Set default PHP version (optional)
# sudo update-alternatives --set php /usr/bin/phpX.X # Replace X.X with desired version
# Check installed PHP versions
php -v
# Check all installed PHP versions
dpkg -l | grep php | awk '{print $2}' | grep -E "^php[0-9]+\.[0-9]+$"
Allow it to execute and then execute:
chmod +x ~/install-multiple-php-versions.sh
. ~/install-multiple-php-versions.sh
Add the script to switch php versions over at /usr/local/bin/sphp
#!/bin/bash
# file: /usr/local/bin/sphp
# switch PHP versions with: sphp 8.3
# Function to check if a command exists
command_exists() {
type "$1" &> /dev/null
}
# Function to show the current PHP version
show_current_php() {
php --version | head -n 1
}
# Main function to change PHP version for the current user
switch_php() {
if [ -z "$1" ]; then
echo "Usage: sphp <version>"
echo "Example: sphp 8.1"
exit 1
fi
VERSION=$1
PHP_BIN="php$VERSION"
if ! command_exists $PHP_BIN; then
echo "PHP $VERSION is not installed. Install it first using apt."
exit 1
fi
# Check if update-alternatives --set-user is supported
if update-alternatives --help | grep -q "\-\-set-user"; then
# Use update-alternatives --set-user if it's supported
update-alternatives --set-user php /usr/bin/$PHP_BIN
else
# Alternative method using symlinks if --set-user is not available
mkdir -p ~/.local/bin
ln -sf /usr/bin/$PHP_BIN ~/.local/bin/php
# Add ~/.local/bin to PATH if it's not already there
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
fi
fi
echo "Switched to PHP $VERSION for user $USER"
show_current_php
echo "Note: You may need to open a new terminal or run 'source ~/.bashrc' to see the change."
}
# Execute the main function
switch_php "$1"
And make it executable
sudo chmod +x /usr/local/bin/sphp
If you’re using your Mac mini as a headless server, you might have found that you cannot login using ssh or Screen Sharing after a reboot.
To overcome this, only reboot using the command sudo fdesetup authrestart
This will prompt you for the user to login with after reboot, but it won’t log in to the desktop.
It just shows the login screen on the Mac mini, but now you are able to remotely login to the Mac mini after a reboot without a monitor or keyboard attached.
# to reboot and have remote services accessible:
sudo fdesetup authrestart
# tip: make an alias of 'reboot'
echo 'sudo fdesetup authrestart' >> ~/.bash_profile
# after re-login, you can now just type: reboot
Add the following function somewhere where it will be picked up by your shell.
For example: ~/.bash_profile
Then use it like so:
$ deit api
Multiple containers found with 'api' in the name:
1. srv-captain--strippenkaart-api.1.ytwsvciqerfm3k0821tpowx23
2. srv-captain--verkooprapport-api.1.we0g3exhke86q2k2qgikzkmyk
3. srv-captain--trainingsomgeving-api.1.624q0sm2qkpbqxyn37osiq2er
4. srv-captain--funnelmonitor-api.1.phukkl9slxifjcvg3yx2ykdda
Choose the number of the container you want to use:
This is the bash function:
# in file ~/.bash_profile
# 'deit' as in: docker exec -it
function deit {
container_query="$1"
shift 1
container_command="${@:-bash}" # Default to 'bash' if no command is provided
# Get the list of matching container names
matching_containers=($(docker ps --format '{{.Names}}' | grep "$container_query"))
count=${#matching_containers[@]}
if [ "$count" -eq 0 ]; then
echo "No containers found with '$container_query' in the name."
return 1
elif [ "$count" -eq 1 ]; then
container_name="${matching_containers[0]}"
echo "Found container: $container_name"
echo "Executing: docker exec -it $container_name $container_command"
docker exec -it "$container_name" $container_command
else
echo "Multiple containers found with '$container_query' in the name:"
for i in "${!matching_containers[@]}"; do
echo "$((i + 1)). ${matching_containers[i]}"
done
while true; do
read -p "Choose the number of the container you want to use: " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
container_name="${matching_containers[$((choice - 1))]}"
echo "Selected container: $container_name"
echo "Executing: docker exec -it $container_name $container_command"
docker exec -it "$container_name" $container_command
break
else
echo "Invalid choice. Please try again."
fi
done
fi
}
I got these errors after trying to run npm install
.
# npm install
...
npm ERR! gyp ERR! UNCAUGHT EXCEPTION
npm ERR! gyp ERR! stack TypeError: Cannot assign to read only property 'cflags' of object '#<Object>'
npm ERR! gyp ERR! stack at createConfigFile (/app/node_modules/node-gyp/lib/configure.js:117:21)
npm ERR! gyp ERR! stack at /app/node_modules/node-gyp/lib/configure.js:84:9
npm ERR! gyp ERR! stack at FSReqCallback.oncomplete (node:fs:191:23)
npm ERR! gyp ERR! System Linux 6.6.12-linuxkit
npm ERR! gyp ERR! command "/usr/local/bin/node" "/app/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
npm ERR! gyp ERR! cwd /app/node_modules/node-sass
npm ERR! gyp ERR! node -v v20.11.1
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! Node-gyp failed to build your package.
npm ERR! gyp ERR! Try to update npm and/or node-gyp and if it does not help file an issue with the package author.
npm ERR! Build failed with error code: 7
I did the following to fix these
package.json
to the latest versionspackage-lock.json
filenode_modules
directorynpm install
againI installed the following packages:
# apt-get update && apt-get install -y ca-certificates curl gnupg zip unzip git software-properties-common rsyslog
Upgraded node, npm, node_gyp and cleared cache
# npm cache clean -f \
&& npm install -g n \
&& n current
# npm install -g npm@latest
# npm update -g node-gyp
# rm -rf node_modules package-lock.json
Then, update all package versions in package.json
to their latest version.
And then tried again, this time it worked.
# npm install
Did this work for you as well? Had to do less? More? Let me know and I’ll update this post.
When debugging your eloquent model queries, it’s often nice to know which SQL query is executed in the end.
By default, Laravel won’t show you the values used in the query. Instead, it shows you a questionmark ?
instead of the actual values. This is because of the parameter bindings in PDO.
Let’s create a ->toSqlWithBindings()
macro so you can have the full query.
<?php
// file app/Providers/MacroServiceProvder.php
declare(strict_types=1);
namespace App\Providers;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class MacroServiceProvider extends ServiceProvider
{
public function boot(): void
{
Builder::macro('toSqlWithBindings', function () {
/** @var Builder $this */
$bindings = array_map(
fn ($parameter) => (is_string($parameter) || $parameter instanceof Carbon) ? "'{$parameter}'" : $parameter,
/** @var Builder $this */
$this->getBindings()
);
return Str::replaceArray(
'?',
$bindings,
$this->toSql()
);
});
/** @var Builder $this */
EloquentBuilder::macro('toSqlWithBindings', fn () => $this->toBase()->toSqlWithBindings());
}
}
I’ve been debugging for days to get my Ionic app working with the Laravel API backend.
The issue: logging in worked fine, but every subsequent API request failed with a 401.
The reason (I guess): the Ionic/capacitor app works with a referrer of capacitor://localhost
. I think this messes up the cookie that is set to maintain the session.
So I had to switch over to something without cookies. Having already spend days on the issues, I went to work with JWT as I’ve done so before.
I followed this tutorial to get me a head-start: https://www.positronx.io/laravel-jwt-authentication-tutorial-user-login-signup-api/
When you want your tests to be able to run whenever you want, you should use values which are random.
In Postman, click on the name of Collection and then open the ‘Pre-request Script’ tab.
There, add the following:
// get a random number between a minimum and a maximum
// gives you current datetime with milliseconds like 2022810_171012_174
postman.setGlobalVariable("getCurrentDate", () => {
const date=new Date();
return String(date.getFullYear())
+ String(date.getMonth()+1)
+ String(date.getDate())
+ '_'
+ String(date.getHours() < 10 ? "0"+date.getHours() : date.getHours())
+ String(date.getMinutes() < 10 ? "0"+date.getMinutes() : date.getMinutes())
+ String(date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds())
+ '_'
+ String(date.getMilliseconds())
})
You can now use this function in your tests. This enables you to make your strings (like emailaddresses) random by adding the current datetime to it.
To use it, open your test, click on the ‘Pre-request Script’ tab and add the following.
var currentDate = eval(pm.globals.get("getCurrentDate"))();
var randomEmail = `postman-${currentDate}@pauledenburg.com`;
pm.environment.set("randomEmail", randomEmail);
You can now use the generated value in the body of your POST-request by referencing it as {{randomEmail}}
The full warning is:
Warning
(2728:3) autoprefixer: Replace color-adjust to print-color-adjust. The color-adjust shorthand is currently deprecated.
The easy fix:
rename color-adjust
to print-color-adjust
This didn’t work for me as the issue is in the node_modules
directory.
Other fix: add the following to your package.json
:
"resolutions": {
"autoprefixer": "10.4.5"
},
Then run the following again: yarn install
Sometimes you want to use child/parent like tests.
This enables you to treat the ‘child test’ more like a template which you can re-use. But you might want to influence the variable used in this templated test.
To test whether a variable was set and set it when it was not, you’d do the following.
Testing whether a variable was set is done with this javascript string:
"${randomResellerEmail}" == "$" + "{randomResellerEmail}"
In Selenium IDE this looks like the following.