Skip to content

Styles aren't generated when building a Docker image for ARM64 on a 2019 Intel MacBook Pro #17728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kyrylo opened this issue Apr 21, 2025 · 21 comments
Labels

Comments

@kyrylo
Copy link

kyrylo commented Apr 21, 2025

What version of Tailwind CSS are you using?

v4.1.3

What build tool (or framework if it abstracts the build tool) are you using?

Rails 8.0.2

What version of Node.js are you using?

What browser are you using?

Chrome

What operating system are you using?

macOS -> ARM64

Describe your issue

I've prepared detailed steps you can follow.

  1. I'm on a MacBook Pro 2019 (Intel):

    % arch
    i386
    
    % uname
    Darwin
    
  2. Generate a new Rails 8 app with Tailwind enabled (zip attached):

    rails new TailwindOnARM --css tailwind
    
  3. Scaffold a resource that uses Tailwind classes:

    rails g scaffold Post
    
  4. Start the dev server and check that Tailwind styling is applied (https://localhost:3000/posts):

    bin/dev
    
    Screenshot 2025-04-16 at 11 44 38 AM
  5. Build and push a Docker image for ARM64:

    docker buildx build --platform linux/arm64 -t kyrylo/tailwind-on-arm:latest --push .
    
  6. On an ARM server (I use Hetzner CAX11), install Docker, then run the image:

    docker run -d -p 80:80 -e RAILS_MASTER_KEY=90279f1e5d289cb437ba0c2f959a2ea5 --name tailwind_on_arm kyrylo/tailwind-on-arm
    
  7. Check the result at http://<IP-ADDRESS>/posts and notice that Tailwind styling is not applied:

    Screenshot application.css
    Screenshot 2025-04-16 at 11 44 53 AM Screenshot 2025-04-16 at 11 49 39 AM

I'm happy to help debug this further. You can pull my image from Docker Hub so you don't have to build it yourself.

@philipp-spiess
Copy link
Member

Hey! Do you have any debug logs from the build step? There are a lot of components in your repro (rails/tailwind gem/docker) so it's hard to know what's going on. Perhaps you can try to run only the Tailwind CSS standalone build in isolation in the Dockerfile for a repro?

@xhayoz
Copy link

xhayoz commented Apr 24, 2025

Hey everyone, having similar issue as it used to work before. Building a web app with ruby on rails 8. I tried to narrow it down as far as I could.

My setup:

  • Docker Desktop (Current version: 4.38.0 (181591)) for development on Mac (M2)
  • Tailwind v4.1 for styling using tailwindcss-rails 4.2.2 and tailwindcss-ruby-4.1.4-aarch64-linux-gnu (for Mac)
  • Using docker buildx for pushing the image on a self-hosted registry as the server architecture is a linux/amd64 (Debian).

Dev:
When starting the web app in dev container on my mac (dev container is started via docker compose up) the output on localhost:3000 is as expected and tailwind.css contains all css classes.

Prod:
As my server runs under an other architecture (linux/amd64) I need to build the image and push it to self-hosted registry with docker buildx build --platform linux/amd64 --push -t registry.******.com/myapp:latest . After starting the container on the server I checked the tailwind.css in browser and saw that a lot of css-classes were missing.

During the build within the standard dockerfile, which is generated when you create a new project, the line below compiles the assets:

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile

Underneath assets:precompile the tailwindcss:build-command is executed which executes tailwind -i path/to/application.css -o path/to/tailwind.css

It seems that tailwind is not parsing all the files like mentioned in the doc when architecture is not the same as the host machine

What I tried so far:

  • Building image with docker build . -t test and inspected the content of the css-file using docker exec -it test bash --> css-file is correct and corresponds to the one in dev environment.
  • Building image locally (not pushing it to registry for inspection) with docker buildx build --platform linux/amd64 --load -t test . and same issue as above after inspecting the css-file.
  • I checked the compiled gem in the image and they correspond to the defined architecture (linux/amd64)
  • I tried to add --verbose to assets:precompile but couldn't find any infos about errors.
  • I tried to pass the paths to scan ( -c "app/views/*") but it didn't work as the tailwindcss-rails gem doesn't expose the option (only -i and -o are exposed). Anyway, this shouldn't be necessary as tailwind should scan all files (excluding the ones mentioned in the doc) starting from project-level.
  • I tried to set the source explicitly (doc). I made sure that non of the file which are needed for the generation of the tailwind.css are in my .gitignore-file.

As mentioned before in rails there are two gems for tailwind:

  • tailwindcss-ruby based on the informations on github is just a simple wrapper around tailwind
  • tailwindcss-rails is dependent of the aforementioned gem

Question:
Is the problem related to docker buildx or is related to tailwind? I don't have enough experience as I just started programming some month ago.

Thanks for any further infos / suggestions

@flavorjones
Copy link

flavorjones commented Apr 25, 2025

Hi, I'm the maintainer of tailwindcss-rails and tailwindcss-ruby, and I've received a few bug reports about this issue. I've been unable to reproduce this on my hardware, and so I have been asking affected users to report this upstream (here).

Here's what I think is happening: on some x86_64 hardware (but maybe not all chips? I certainly can't repro), running the arm64 tailwindcss CLI while building an arm64 docker image fails in a mysterious way.

In an attempt to try to simplify this, I'm going to guess at a simple repro, and I have to ask @kyrylo and @xhayoz and others to tell me if this reproduces the issue.

Here is a self-contained script that should repro on some hardware if I'm guessing correctly:

#!/usr/bin/env bash

# download binaries
wget -q -c https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.4/tailwindcss-linux-arm64
wget -q -c https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.4/tailwindcss-linux-x64

# set up target html
cat > test.html <<EOF
<html>
  <h1 class="py-2 px-3 text-green-500">Hello</h1>
</html>
EOF

# set up the script we'll run in the container
cat > test.sh <<EOF
#!/usr/bin/env bash

uname -a

if uname -m | fgrep aarch64 ; then
  bin=./tailwindcss-linux-arm64
else
  bin=./tailwindcss-linux-x64
fi

rm -f test.css
set -x
DEBUG=1 \$bin -o test.css
cat test.css | fgrep -C3 text-green-500
EOF

# run tailwind in the container
chmod +x tailwindcss-linux-* test.sh
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64  ruby:3.4 ./test.sh

When I run this on my x86_64 development machine, here's what I see as output:

$ ./runme.sh
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:07c880a5e0fd72fa6cf0ff353633c488899082839578776201266e5f9fa95de0
Status: Downloaded newer image for ruby:3.4
Linux 3bc01477206e 6.11.0-1004-lowlatency #4-Ubuntu SMP PREEMPT_DYNAMIC Mon Sep 30 10:54:09 UTC 2024 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 558ms

[559.32ms] [@tailwindcss/cli] (initial build)
[ 14.10ms]   ↳ Setup compiler
[453.22ms]   ↳ Scan for candidates
[ 77.24ms]   ↳ Build CSS
[ 13.81ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:07c880a5e0fd72fa6cf0ff353633c488899082839578776201266e5f9fa95de0
Status: Downloaded newer image for ruby:3.4
Linux a9ea127cd86c 6.11.0-1004-lowlatency #4-Ubuntu SMP PREEMPT_DYNAMIC Mon Sep 30 10:54:09 UTC 2024 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 6s

[6197.23ms] [@tailwindcss/cli] (initial build)
[ 280.95ms]   ↳ Setup compiler
[3845.68ms]   ↳ Scan for candidates
[1791.75ms]   ↳ Build CSS
[ 227.93ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {

What do y'all get as output when you run this?

@xhayoz
Copy link

xhayoz commented Apr 25, 2025

@flavorjones Thanks a lot for your help! Really appreciate it!

The script was run on a Mac M2.

Output:

xavierhayoz@MacBook-Air-XH Dev % ./runme.sh    
Linux 31b37a7976a5 6.10.14-linuxkit #1 SMP Thu Mar 20 16:32:56 UTC 2025 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 5s

[5075.10ms] [@tailwindcss/cli] (initial build)
[ 162.00ms]   ↳ Setup compiler
[4119.15ms]   ↳ Scan for candidates
[ 650.00ms]   ↳ Build CSS
[ 125.00ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .text-inherit {
Linux 2ae05eaf8c4d 6.10.14-linuxkit #1 SMP Thu Mar 20 16:32:56 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 3s

[3422.34ms] [@tailwindcss/cli] (initial build)
[  39.85ms]   ↳ Setup compiler
[3073.49ms]   ↳ Scan for candidates
[ 251.98ms]   ↳ Build CSS
[  50.09ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .text-inherit {

As far as I can tell the issue is not building the image on the same architecture (using docker build) but generating an image for an other architecture with buildx (in my case linux/amd64). I'm generating the image locally which later on is pushed on a server with an x86_64 architecture.

My Mac book specs are:
uname -a 24.4.0 Darwin Kernel Version 24.4.0: Fri Apr 11 18:33:46 PDT 2025; xxxxxxx/RELEASE_ARM64_T8112 arm64

BTW I found a workaround for my issue:

  1. In the Gemfile I moved gem "tailwindcss-rails", "~> 4.0" under group :development do .. endblock so that I still can benefit from the watch option and puma-plugin.
  2. I added node to my Dockerfile, installed tailwindcss via npm and executed the following command when building my image RUN npx @tailwindcss/cli -i /rails/app/assets/tailwind/application.css -o /rails/app/assets/builds/tailwind.css --minify

It's maybe not the best way but it works.

@kyrylo
Copy link
Author

kyrylo commented Apr 26, 2025

Thank you @flavorjones for your efforts in debugging this!

For extensive testing, I ran it on my laptop with 2 Docker engines and a Hetzner Arm64 box. Here are my results.

Host: MacBook 2019 (Intel) (OrbStack Engine)

% uname -a
Darwin Kyrylos-MacBook-Pro.local 22.3.0 Darwin Kernel Version 22.3.0: Thu Jan  5 20:53:49 PST 2023; root:xnu-8792.81.2~2/RELEASE_X86_64 x86_64
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
% docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
Linux de42dde4ad02 6.12.10-orbstack-00297-gf8f6e015b993 #14 SMP Sun Jan 19 03:00:07 UTC 2025 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 1s

[1423.26ms] [@tailwindcss/cli] (initial build)
[  22.20ms]   ↳ Setup compiler
[1265.06ms]   ↳ Scan for candidates
[ 120.37ms]   ↳ Build CSS
[  14.38ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64 ruby:3.4 ./test.sh
Linux ec1a56cf4f26 6.12.10-orbstack-00297-gf8f6e015b993 #14 SMP Sun Jan 19 03:00:07 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
error: Invalid Argument '-o'
Bun is a fast JavaScript runtime, package manager, bundler, and test runner. (1.2.8+adab0f64f)

Usage: bun <command> [...flags] [...args]

Commands:
  run       ./my-script.ts       Execute a file with Bun
            lint                 Run a package.json script
  test                           Run unit tests with Bun
  x         eslint               Execute a package binary (CLI), installing if needed (bunx)
  repl                           Start a REPL session with Bun
  exec                           Run a shell script directly with Bun

  install                        Install dependencies for a package.json (bun i)
  add       lyra                 Add a dependency to package.json (bun a)
  remove    browserify           Remove a dependency from package.json (bun rm)
  update    @remix-run/dev       Update outdated dependencies
  outdated                       Display latest versions of outdated dependencies
  link      [<package>]          Register or link a local npm package
  unlink                         Unregister a local npm package
  publish                        Publish a package to the npm registry
  patch <pkg>                    Prepare a package for patching
  pm <subcommand>                Additional package management utilities

  build     ./a.ts ./b.jsx       Bundle TypeScript & JavaScript into a single file

  init                           Start an empty Bun project from a built-in template
  create    vite                 Create a new project from a template (bun c)
  upgrade                        Upgrade to latest version of Bun.
  <command> --help               Print help text for command.

Learn more about Bun:            https://bun.sh/docs
Join our Discord community:      https://bun.sh/discord
+ cat test.css
+ fgrep -C3 text-green-500
cat: test.css: No such file or directory

Host: MacBook 2019 (Intel) (Docker Engine)

docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
Linux cdb21f62c1d0 6.10.14-linuxkit #1 SMP PREEMPT_DYNAMIC Fri Nov 29 17:24:06 UTC 2024 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 1s

[1642.04ms] [@tailwindcss/cli] (initial build)
[  36.34ms]   ↳ Setup compiler
[1347.15ms]   ↳ Scan for candidates
[ 181.75ms]   ↳ Build CSS
[  74.39ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64 ruby:3.4 ./test.sh
Linux c9d9543f6df0 6.10.14-linuxkit #1 SMP PREEMPT_DYNAMIC Fri Nov 29 17:24:06 UTC 2024 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 22s

[22571.68ms] [@tailwindcss/cli] (initial build)
[  924.29ms]   ↳ Setup compiler
[16247.18ms]   ↳ Scan for candidates
[ 5064.50ms]   ↳ Build CSS
[  270.20ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {

Hetzner CAX11 Arm64 (Docker Engine)

# uname -a
Linux ubuntu-4gb-hel1-1 6.8.0-58-generic #60-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 14 18:09:50 UTC 2025 aarch64 aarch64 aarch64 GNU/Linux
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
exec ./test.sh: exec format error
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64 ruby:3.4 ./test.sh
Linux 9fbea846e38e 6.8.0-58-generic #60-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 14 18:09:50 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 3s

[3059.73ms] [@tailwindcss/cli] (initial build)
[  32.39ms]   ↳ Setup compiler
[2768.90ms]   ↳ Scan for candidates
[ 208.71ms]   ↳ Build CSS
[  47.44ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {

@flavorjones
Copy link

My comment above was intended to demonstrate how to simplify a reproduction of this kind of problem without rails or ruby. Can someone who is having this problem on their dev machine please use this framework to reproduce what's happening?

@drwl
Copy link

drwl commented Apr 30, 2025

@flavorjones ran the script on:

  • MacOS 15.4.1
  • M1 Max
  • Docker version 28.0.4, build b8034c0
chmod +x ./runme.sh && ./runme.sh
./runme.sh: line 1: !/usr/bin/env: No such file or directory
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
cf05a52c0235: Pull complete 
63964a8518f5: Pull complete 
ca513cad200b: Pull complete 
c187b51b626e: Pull complete 
87ec079bfaf8: Pull complete 
6d417cde9601: Pull complete 
ce4f81987fcc: Pull complete 
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux 952c30d78b6c 6.10.14-linuxkit #1 SMP Thu Mar 20 16:32:56 UTC 2025 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 1s

[1555.00ms] [@tailwindcss/cli] (initial build)
[  96.00ms]   ↳ Setup compiler
[ 921.00ms]   ↳ Scan for candidates
[ 418.00ms]   ↳ Build CSS
[ 101.00ms]   ↳ Write output

+ fgrep -C3 text-green-500
+ cat test.css
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
de07ba6f486e: Pull complete 
84649bff67ea: Pull complete 
48a2a14f59a0: Pull complete 
0d41c7623f41: Pull complete 
bdad7cb423a1: Pull complete 
78b2a9eea636: Pull complete 
faea2d51befa: Pull complete 
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux a9a339b0e146 6.10.14-linuxkit #1 SMP Thu Mar 20 16:32:56 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 933ms

[934.52ms] [@tailwindcss/cli] (initial build)
[ 12.64ms]   ↳ Setup compiler
[830.92ms]   ↳ Scan for candidates
[ 76.42ms]   ↳ Build CSS
[ 12.78ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 text-green-500
  .text-\[rgba\(255\,255\,255\,0\.87\)\] {
    color: rgba(255,255,255,0.87);
  }
  .text-green-500 {
    color: var(--color-green-500);
  }
  .capitalize {

@drwl
Copy link

drwl commented Apr 30, 2025

I'm not sure if this validates what you're thinking, but I am also facing a similar issue in the tailwindrails discussion rails/tailwindcss-rails#499.

Dev on m1 mac, deployment to ubuntu host via kamal.

@flavorjones
Copy link

@drwl Just to make sure I understand: it looks like you have not reproduced the problem, given the output. The color "--color-green-500" appears in both outputs.

@jesse-spevack
Copy link

I believe I had the same issue and documented a fix involving Kamal's remote builder.

@n-studio
Copy link

n-studio commented May 4, 2025

@flavorjones text-green-500 is compiled correctly, but not py-2.

I changed your test script to: cat test.css | fgrep -C3 py-2 and here are the results (M1 Max + Docker.desktop)

$ docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux e9d6fdbed890 6.10.14-linuxkit #1 SMP Tue Apr 15 16:00:54 UTC 2025 x86_64 GNU/Linux
+ DEBUG=1
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.4

Done in 1s

[1788.00ms] [@tailwindcss/cli] (initial build)
[  94.00ms]   ↳ Setup compiler
[1227.00ms]   ↳ Scan for candidates
[ 385.00ms]   ↳ Build CSS
[  73.00ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 py-2


$ docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64  ruby:3.4 ./test.sh
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux b2c74d120d61 6.10.14-linuxkit #1 SMP Tue Apr 15 16:00:54 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG=1
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.4

Done in 813ms

[814.48ms] [@tailwindcss/cli] (initial build)
[ 14.22ms]   ↳ Setup compiler
[707.47ms]   ↳ Scan for candidates
[ 77.00ms]   ↳ Build CSS
[ 14.27ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 py-2
  .py-1\.5 {
    padding-block: calc(var(--spacing) * 1.5);
  }
  .py-2 {
    padding-block: calc(var(--spacing) * 2);
  }
  .py-\[0\.2rem\] {

@thomaswitt
Copy link

thomaswitt commented May 4, 2025

I believe I had the same issue and documented a fix involving Kamal's remote builder.

I can confirm the problem when cross-platform-building on a Mac (docker build --platform linux/aarch64,linux/x86_64).

I also would like to point out that it's there's no fix if you're building the docker image locally on your M* Mac (arm) and deploying to AWS ECS (x86) - so basically the other way around than the issue creator described.

Only "fix" is to use x86 machines on AWS to build the image. 😕

Clearly there's something broken here.

@flavorjones
Copy link

@philipp-spiess To try to separate out the signal from the noise in this issue, @n-studio appears to have a reproduction that demonstrates something going wrong.

@sumansuhag

This comment has been minimized.

@philipp-spiess
Copy link
Member

@n-studio Hey! Do you mind running your repro again with the new improved debugging feature in 4.1.6? All you need to do is to set the DEBUG env var to * and we'll create a log file that will include infos about the current file system setup.

@n-studio
Copy link

n-studio commented May 14, 2025

@philipp-spiess

Updated tests

#!/usr/bin/env bash

# download binaries
wget -q -c https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.6/tailwindcss-linux-arm64
wget -q -c https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.6/tailwindcss-linux-x64

# set up target html
cat > test.html <<EOF
<html>
  <h1 class="py-2 px-3 text-green-500">Hello</h1>
</html>
EOF

# set up the script we'll run in the container
cat > test.sh <<EOF
#!/usr/bin/env bash

uname -a

if uname -m | fgrep aarch64 ; then
  bin=./tailwindcss-linux-arm64
else
  bin=./tailwindcss-linux-x64
fi

rm -f test.css
set -x
DEBUG=* \$bin -o test.css
cat test.css | fgrep -C3 py-2
cat /repro/tailwindcss-11.log
EOF

# run tailwind in the container
chmod +x tailwindcss-linux-* test.sh
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64  ruby:3.4 ./test.sh

Results (M1 Max + Docker.desktop):

$ docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/x86_64 ruby:3.4 ./test.sh
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux f10f3866258d 6.10.14-linuxkit #1 SMP Tue Apr 15 16:00:54 UTC 2025 x86_64 GNU/Linux
+ DEBUG='*'
+ ./tailwindcss-linux-x64 -o test.css
≈ tailwindcss v4.1.6

[DEBUG] Writing debug info to: `/repro/tailwindcss-11.log`

Done in 1s

[1492.00ms] [@tailwindcss/cli] (initial build)
[ 105.00ms]   ↳ Setup compiler
[ 894.00ms]   ↳ Scan for candidates
[ 391.00ms]   ↳ Build CSS
[  94.00ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 py-2
+ cat /repro/tailwindcss-11.log
2025-05-14T14:42:13.669737Z  INFO tailwindcss_oxide::scanner: Provided sources:
2025-05-14T14:42:13.671885Z  INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/repro", pattern: "**/*", negated: false }
2025-05-14T14:42:13.674531Z  INFO tailwindcss_oxide::scanner: Optimized sources:
2025-05-14T14:42:13.674575Z  INFO tailwindcss_oxide::scanner: Source: Auto { base: "/repro" }
2025-05-14T14:42:13.699240Z  INFO scan_sources: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.710687Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:13.712270Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:13.712476Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.html"
2025-05-14T14:42:13.712612Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.sh"
2025-05-14T14:42:13.713758Z  INFO scan_sources: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:13.714181Z  INFO extract_candidates: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.714382Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.714415Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: Reading 4 file(s)
2025-05-14T14:42:13.733659Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.html"
2025-05-14T14:42:13.733672Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.sh"
2025-05-14T14:42:13.845949Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:13.854892Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:13.900891Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:13.901360Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.901566Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:14.563263Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:14.567904Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:14.577713Z  INFO extract_candidates: tailwindcss_oxide::scanner: exit



$ docker run --mount=type=bind,source=$(pwd),target=/repro -w /repro --platform=linux/arm64  ruby:3.4 ./test.sh
Unable to find image 'ruby:3.4' locally
3.4: Pulling from library/ruby
Digest: sha256:6adb999a22072227ba4ddfce8746959deb3a14bc9e32ad55e9723f5b3995aa94
Status: Downloaded newer image for ruby:3.4
Linux ac588f3a4e72 6.10.14-linuxkit #1 SMP Tue Apr 15 16:00:54 UTC 2025 aarch64 GNU/Linux
aarch64
+ DEBUG='*'
+ ./tailwindcss-linux-arm64 -o test.css
≈ tailwindcss v4.1.6

[DEBUG] Writing debug info to: `/repro/tailwindcss-11.log`

Done in 765ms

[766.33ms] [@tailwindcss/cli] (initial build)
[ 14.16ms]   ↳ Setup compiler
[662.20ms]   ↳ Scan for candidates
[ 75.26ms]   ↳ Build CSS
[ 13.33ms]   ↳ Write output

+ cat test.css
+ fgrep -C3 py-2
  .py-1\.5 {
    padding-block: calc(var(--spacing) * 1.5);
  }
  .py-2 {
    padding-block: calc(var(--spacing) * 2);
  }
  .py-\[0\.2rem\] {
+ cat /repro/tailwindcss-11.log
2025-05-14T14:42:13.669737Z  INFO tailwindcss_oxide::scanner: Provided sources:
2025-05-14T14:42:13.671885Z  INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/repro", pattern: "**/*", negated: false }
2025-05-14T14:42:13.674531Z  INFO tailwindcss_oxide::scanner: Optimized sources:
2025-05-14T14:42:13.674575Z  INFO tailwindcss_oxide::scanner: Source: Auto { base: "/repro" }
2025-05-14T14:42:13.699240Z  INFO scan_sources: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.710687Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:13.712270Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:13.712476Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.html"
2025-05-14T14:42:13.712612Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.sh"
2025-05-14T14:42:13.713758Z  INFO scan_sources: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:13.714181Z  INFO extract_candidates: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.714382Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.714415Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: Reading 4 file(s)
2025-05-14T14:42:13.733659Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.html"
2025-05-14T14:42:13.733672Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.sh"
2025-05-14T14:42:13.845949Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:13.854892Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:13.900891Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:13.901360Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:13.901566Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:14.563263Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:14.567904Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:14.577713Z  INFO extract_candidates: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:23.730497Z  INFO tailwindcss_oxide::scanner: Provided sources:
2025-05-14T14:42:23.730679Z  INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/repro", pattern: "**/*", negated: false }
2025-05-14T14:42:23.730775Z  INFO tailwindcss_oxide::scanner: Optimized sources:
2025-05-14T14:42:23.730868Z  INFO tailwindcss_oxide::scanner: Source: Auto { base: "/repro" }
2025-05-14T14:42:23.732274Z  INFO scan_sources: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:23.732786Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:23.732896Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:23.732992Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.html"
2025-05-14T14:42:23.733031Z  INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/repro/test.sh"
2025-05-14T14:42:23.733124Z  INFO scan_sources: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:23.733161Z  INFO extract_candidates: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:23.733195Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:23.733226Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: Reading 4 file(s)
2025-05-14T14:42:23.735233Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.sh"
2025-05-14T14:42:23.735229Z  INFO tailwindcss_oxide::scanner: Reading "/repro/test.html"
2025-05-14T14:42:23.828151Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-arm64"
2025-05-14T14:42:23.835786Z  INFO tailwindcss_oxide::scanner: Reading "/repro/tailwindcss-linux-x64"
2025-05-14T14:42:23.886267Z  INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:23.886457Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:23.886492Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: enter
2025-05-14T14:42:24.369626Z  INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:24.374728Z  INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: exit
2025-05-14T14:42:24.383917Z  INFO extract_candidates: tailwindcss_oxide::scanner: exit

@philipp-spiess
Copy link
Member

@n-studio Thanks! And very bizarre. What version of macOS and Docker do you have? I wonder if it has to be some specific versions that trigger that. The same issue does not repro on:

  • M4 Max
  • macOS 15.4.1
  • Docker Desktop 4.37.2

@philipp-spiess
Copy link
Member

We were able to reproduce this on @RobinMalfait's machine who had mostly the same versions as me, the only difference is that he is on the M1 Max. Lol

@n-studio
Copy link

  • M1 Max
  • macOS 15.4.1
  • Docker Desktop 4.41.2

@RobinMalfait
Copy link
Member

RobinMalfait commented May 15, 2025

Hey!

So we did a bunch of testing and figured out the bug, or at least how to give you a workaround. More in depth information here: oven-sh/bun#19677

Turns out that:

  • If you are on an M1
  • Using Docker
  • With Apple Virtualization framework
    • With the Use Rosetta for x86_64/amd64 emulation on Apple Silicon option checked
  • Running a Docker file with --platform=linux/x86_64

If you then have values such as 0.25 or 1.25, then they all get truncated to just 0 and 1 respectively.
I don't think there is anything we can do to solve this issue unfortunately.

However, if you go into your Docker settings under the Virtual Machine Options settings, then you can either:

  • Uncheck the Use Rosetta for x86_64/amd64 emulation on Apple Silicon option
  • Switch to QEMU (Legacy)
  • Switch to Docker VMM

How this bug relates to Tailwind CSS itself:

One of the checks we do internally when you use px-4, is that we check if the value 4 is a valid multiplier of 0.25 because we don't want to support px-4.123 for example. The 0.25 gets turned into 0 so our check doing 4 % 0.25 === 0 now becomes 4 % 0 === 0 instead. 4 % 0.25 correctly produces 0, but 4 % 0 produces NaN which is not 0 of course and therefore the px-4 is ignored because we consider it invalid.

This is also why other classes did work like a bg-red-500 or flex because they are not dealing with numbers.

Hopefully any of these workarounds will work for you.

@RobinMalfait
Copy link
Member

This morning I updated my M1 to macOS 15.5 (24F74) and that also seems to fix the problem. Since there are enough workarounds right now, and since we can't do anything about this bug I'm going to close it for now.

So in summary, if you run into this bug, make sure to:

  1. Update your M1 to the latest macOS version
  2. Use one of the workarounds as described above by changing the Docker desktop settings

Hope this helps!

(What a roller coaster of a bug 😅)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants