Today I Learned
How to show the journalctl entries for user services and containers on AlmaLinux
tl;dr
On AlamLinux, if you are running a container or service using systemd
, to show its journal entires, you need to use the --user-unit
parameter:
journalctl -e --user-unit my_user_local.service
Warnings and errors in Elixir macros with the line number of the macro, not the macro calling site
tl;dr
When you’ve got an error or warning in an Elixir macro, the error message will give you the location of the code that is calling the macro, not the line in the macro itself.
To report the line inside the macro, add a location: :keep
to your quote do
.
Login to Erlang node run with systemd using remote shell
tl;dr
I wanted to login into a running node using a remote shell today, but always got this error:
Could not contact remote node my_app@hostname, reason: :nodedown.
Even though the node was up. Turns out we need to source all the environment variables first:
set -a
source environment.env
set +a
How to use Erlang dbg in a remote Elixir shell
tl;dr
I was recently trying to trace some problems in production, but was unable to get the trace to be printed in the remote shell.
The correct syntax for the tracer is in the remote shell is:
:dbg.tracer(:process, {fn (msg, n) -> IO.inspect(msg); n+1 end, 0})
Using a text input with a list of predefined options
tl;dr
So today I learned that you can use a <input list="option-list">
in combination with a <datalist id="option-list"><option value="a"/></datalist>
for the often required use case of a text input with a list of available options and you no longer need to implement that manually all the time.
How to use the users preferred color scheme on your website
tl;dr
In css
, you can use the users color scheme by simply setting the color-scheme
on the :root
element:
:root {
color-scheme: light dark;
}
Postcss requires semicolons after import statement or it will only perform the import for the first line
tl;dr
When merging css
files using postcss-import
don’t forget to add semicolons after each import statement, or else postcss
will only import the first file and for some reason add a @media
directive in front of the next import and stop
processing of further imports.
Connecting to node with mix remote when using custom RELEASE_NODE name
tl;dr
If you’ve set the RELEASE_NODE
in when starting your server with mix start
and then want to connect to it using mix remote
, you
must first export the same value in RELEASE_NODE
in your current shell as well.
Phoenix Does Not Serve Webmanifest
tl;dr
My site.manifest
were not loaded with Elixir Phoenix 1.6. It turned out I have to add the file to the whitelist.
Printing full error message from :error_logger warning
tl;dr
I’ve got a problem where Phoenix.Channel.Server
receives an unexpected message to be pushed to my client via a channel. However that message is very long, and some of the important information is only printed at the very bottom of the log message that has been truncated.
Hugo .Date.Format strings have more meaning than I thought
tl;dr
On this blog the dates were formatted incorrectly, i.e. 2022-08-30
would be printed as 30-88-022
. The solution was that
the format strings look like they are just some random date, i.e. .Date.Format "Monday, 01.11.2006"
, but actually the values
for date, month and year are hardcoded like dd.mm.yyyy
in nearly every other language. Correct would be .Date.Format "Monday, 02.01.2006"
.
Phoenix now requires explicit start of server in prod
tl;dr
In Phoenix 1.6.x you now need to start the server explicitly by setting the PHX_SERVER=true
environment variable.
Atoms are not automatically converted to strings in heex templates
tl;dr
If you’ve got a heex template where you want to insert some data attribute like true
, make sure that you convert it to a string first.
Otherwise a blank string ""
is inserted.
Elixir Optional Parentheses
tl;dr
Just discovered that you parentheses in Elixsir are optional.
Saw this example on the ecto documentation page:
case MyRepo.insert %Post{title: "Ecto is great"} do
{:ok, struct} -> # Inserted with success
{:error, changeset} -> # Something went wrong
end
Dependencies in the main mix.exs file in umbrella projects are not included in relases
tl;dr
If you’ve got a dependency that one of your apps in your umbrella project depends on, do not put it in the main mix.exs
file
at the base of the umbrella project. It will not be included in relases in that case.
Using avif images with Apache and long cache Times
tl;dr
If you want to set long cache times using the headers cache-control
and expires
for .avif
images, you will probably need to
add the mime type for avif
first like so:
<IfModule mod_expires.c>
AddType image/avif .avif
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
...
ExpiresByType image/avif A31536000
</IfModule>
Using <Source> and 'srcset' to force browser to choose correct image on mobile
tl;dr
When using responsive images using <picture>
and the sizes
attribute is not enough to force the browser to use a small
image on mobile. Instead you need to provide multiple <source>
tags with the media="(max-width: 200px)"
attribute set.
Ecto 3 breaks assoc loaded
tl;dr
After migrating to Ecto 3, the following code did not work:
Ecto.assoc_loaded?(“e9d7edb4-3aef-45d6-851c-e77a464ef352”)
The Ecto.assoc_loaded?()
does not accept any objects, check manually before you call assoc_loaded?()
Searching for Domain Names
tl;dr
Searching for a domain for your new project? Try
Do not log all queries as debug in Ecto
tl;dr
Ecto by default logs all queries as debug to the console when developing. To disable
simply add log: false
to your ecto config.
Create Empty File to Deal with Full Disk
tl;dr
Nice trick to deal with disk full issues on a server:
After setting up the server, create an empty 8GB file in /spacer.img
.
Why? In case the server goes out of space, simpley delete the file.
That gives you more to fix the actual issue.
Running Erlang and Elixir as Apps on Android or iOS
tl;dr
The guys at diode.io have build a wrapper around the BEAM so that you can run it as a native app on Android and iOS, using LiveView locally on the device.
Cleaning Up Digest Files in Phoenix
tl;dr
Digested files in priv/static can be cleaned up using mix phx.digest.clean --all
.
Beware of Zombie Watchers in Elixir
tl;dr
Running custom background watchers with e.g. watchexec
will lead to zombie processes if not wrapped in custom shell script that kills the process once elixir quits.
Use the unary plus operator in JS to parse numbers
tl;dr
Of the dozens of variants to parse a number in JS, the unary plus operator is the preferred method.
Nesting Anchors not Working in Firefox
tl;dr
Do not try to nest <a>
tags in Firefox, that will cause Firefox to mangle up the layout.
Find all Elements at Mouse Position in Javascript
tl;dr
Get an array of all elements at the specified coordinates, relative to the viewport, using Document.elementsFromPoint()
.
Explizite Ansprache in Stellenanzeige ist Besser als Binnen-I
tl;dr
Eine Studie hat gezeigt, dass eine Stellenanzeige mit der Formulierung “Geschäftsführerin oder Geschäftsführer (m/w/d)” mehr Bewerbungen von Frauen und insgesamt mehr Bewerbungen bringt als die Formulierung “Geschäftsführer (m/w/d)”.
Copy Android App Data Using Backup
tl;dr
When migrating to a new phone, you can copy most app data using the apt
backup and restore function.
For With Reduce in Elixir
tl;dr
You can perform a reduce using for
by using the reduce: []
opt.
beforeunload Deactivated on iOS
tl;dr
On Safari in iOS the event beforeunload
does not exist, but it does on Safari for MacOS. Add a
global event listener on all clicks on anchor tags as a workaround.
Using Different Erts Version With Mix Release
tl;dr
If you are using mix release
with a different erts
version, the path must point to the erts-x.x.x
directory inside the erlang installation.
You Can Simulate iOS Devices on Macos
tl;dr
Use simulator.app
from XCode to test your websites on iOS devices.
Migrations Are Silently Skipped if They Do Not Have an Exs Extension
tl;dr
If you’ve got a migration that has ex
as its extension instead of exs
its silently skipped.