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

Open
kyrylo opened this issue Apr 21, 2025 · 6 comments

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 ```diff 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 ```diff 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 {
</details>

@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?

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

No branches or pull requests

4 participants