Fix Weston screen rotation not applying in a container

5 min read · Published November 4, 2026

The transform line is usually fine; the file is wrong. A Weston container reads the weston.ini inside its own image, at /etc/xdg/weston-dev/weston.ini on the common development image. Put name=DPI-1, transform=rotate-270 and the panel's native mode line under [output] in that file, restart the container, and confirm with weston-eventdemo.

Your transform line is right; the file it sits in is wrong. A Weston compositor running in a container reads the weston.ini inside its own filesystem, and the Debian-based image used for development ships that file at /etc/xdg/weston-dev/weston.ini. Editing /etc/xdg/weston/weston.ini on the host changes nothing the container can see. On the 240 × 320 portrait panel in this case, the working [output] section is name=DPI-1, transform=rotate-270 and the native mode line, written into the file the container loads, followed by a container restart. Here is how to find that file, what belongs on each line, and how to see the result in a minute with weston-eventdemo.

What each symptom points to

  • Weston starts normally and ignores your transform line. The compositor is loading a different weston.ini from the one you edited. A container image carries its own copy; the host file counts only when it is mounted into the container.
  • The [output] section is uncommented and still nothing changes. The name= line is missing or does not match a real connector. The stock file warns about this in its own comments: with no name for the output being customized, the changes do not apply.
  • The rotation worked, then came back after a rebuild. The image build copies its own configuration over the path you edited. Edits made inside a running container are gone when that container is replaced.
  • The picture is rotated the wrong way. rotate-90 and rotate-270 both turn a portrait panel landscape, in opposite directions. rotate-180 turns it end over end.
  • Weston rejects the mode line. The mode= string does not match any line the connector reports under /sys/class/drm.

This article rotates the whole desktop at the compositor level. Turning individual images inside a signage playlist is a content feature; if that is what stopped on one of our screens, the image rotation troubleshooting for offline players page covers it.

Get the connector name and mode from the kernel

The [output] section only applies when name= matches the connector exactly as the kernel prints it:

ls /sys/class/drm
cat /sys/class/drm/card1-DPI-1/modes

On this machine the listing showed one connector, DPI-1, a parallel RGB panel, carrying one mode, printed as 240x320 with a 69.1 Hz refresh. An HDMI connector appears in the same tree as card1-HDMI-A-1, and LVDS panels on other platforms show up as LVDS1. Copy the connector name into name= and the whole mode string into mode= exactly as printed. The mode stays the native portrait mode even though the desktop will run landscape.

Direction is a mounting question. The two quarter turns put the connector edge on opposite sides of the bezel, so look at the cut-out before you choose: the flush-mount and cut-out sizes guide prints the dimensions, and the portrait panel fit check walks the same decision for a portrait install.

Find the weston.ini the container loads

Read the container's startup log. Find the container id with docker ps, then run docker logs against it; the examples below use the container name weston, so substitute your own container name or id:

docker ps
docker logs weston

Weston prints the configuration file it loaded. In this case that path was /etc/xdg/weston-dev/weston.ini, not the /etc/xdg/weston/weston.ini that had been edited. Confirm both inside the container:

docker exec -it weston bash
cat /etc/xdg/weston/weston.ini
cat /etc/xdg/weston-dev/weston.ini

The copy without your transform line is the live one. The compose file that launches the stack explains why; on this OS image it was /var/sota/storage/docker-compose/docker-compose.yml, and reading it needed sudo. Its volumes list shows which host paths reach the container at all.

Then fix it at the level of persistence you need:

  • Quick test: edit /etc/xdg/weston-dev/weston.ini inside the container and restart it. The change dies at the next rebuild.
  • Persistent across restarts: add the configuration directory as a bind mount in the compose volumes and recreate the container.
  • Persistent across rebuilds: copy your file in the Dockerfile, to both paths the image ships: COPY weston.ini /etc/xdg/weston/weston.ini and COPY weston-dev.ini /etc/xdg/weston-dev/weston.ini.

The valid transform values

The weston.ini reference documents eight values for transform: normal, rotate-90, rotate-180, rotate-270, flipped, flipped-90, flipped-180, flipped-270. Rotation runs counter-clockwise, so rotate-270 is a quarter turn clockwise. The line goes under the [output] section whose name= matches your connector. On a desktop install outside a container, the same edit lands in /etc/xdg/weston/weston.ini.

Example: rotating a 240 × 320 panel at 69.1 Hz into a 320 × 240 desktop

Inputs:

  • Panel: 240 × 320 pixels, 18 bpp, portrait-native, from the panel specification.
  • Connector: DPI-1, from ls /sys/class/drm.
  • Mode: the single line that cat /sys/class/drm/card1-DPI-1/modes prints, 240 by 320 pixels at 69.1 Hz.
  • Live configuration file: /etc/xdg/weston-dev/weston.ini, named in the container startup log.
  • Target: a landscape desktop for the application.

Rule in words: mode drives the panel at its native string; transform rotates the composed desktop counter-clockwise in quarter turns. A quarter turn swaps the desktop's axes and leaves the pixel count alone.

Arithmetic:

  • Native panel: 240 × 320 = 76,800 pixels.
  • After a quarter turn: 320 × 240 = 76,800 pixels. Same panel, nothing cropped, refresh still 69.1 Hz.
  • rotate-270 = 270 degrees counter-clockwise = 90 degrees clockwise.

The [output] section written into the live file, with the mode string copied verbatim from the modes listing:

[output]
name=DPI-1
transform=rotate-270
mode=240x320

If the connector reports several modes and the compositor picks the wrong one, append the refresh to the mode line in the form the weston.ini reference documents, width by height at the rate in Hz.

Then restart the container:

docker restart weston

The desktop handed to the application now measures 320 × 240. Decision: an edit inside the running container proves the setting in minutes; move it into the image build or the compose bind mount the same day, or the next rebuild restores the shipped orientation. If the desktop lands upside down, the panel is mounted the other way round: swap rotate-270 for rotate-90, the other quarter turn that produces landscape.

Confirm it with weston-eventdemo

docker exec -it weston bash
weston-eventdemo

The demo window opens with a border and drag handles. With the rotation applied, its long axis runs horizontally on the portrait panel, and the window tracks the rotated desktop when you drag it. Then start the real application and lay it out against 320 × 240, the size it now sees, not the panel's native portrait size.

What to standardize on

Recommendation: put the rotation in the image build, not in a running container. Ship your edited file to both paths the image loads, /etc/xdg/weston/weston.ini and /etc/xdg/weston-dev/weston.ini, and add the same file as a compose bind mount when you want to retune it without a rebuild. On a portrait-native panel that must run landscape, start with rotate-270 and switch to rotate-90 when the picture lands upside down. Touch nothing else in the [output] section until name= and mode= match what /sys/class/drm prints.

A panel like this is a machine interface, and the rotation belongs to the machine's software. If the same cell also needs a plain notice or status board that plays from a card with no network, that is a separate screen; see shop-floor display boards for what fits that job.

Questions

Which weston.ini file does a Weston container actually load?

The one inside the container's own filesystem, and the startup log names it. Run docker logs on the Weston container and read the first lines; on the Debian-based image used for development the loaded path is /etc/xdg/weston-dev/weston.ini. When that path differs from the file you edited, that difference is the whole fault.

Do I need a mode= line for the rotation to work?

No. transform rotates the desktop on its own. The mode line does a separate job: it pins the resolution and refresh the panel is driven at, copied character for character from the connector's modes listing. Set both when the connector reports several modes and the compositor picks the wrong one; set only transform when the native mode is already selected.

What do the flipped transform values do?

flipped mirrors the output, and flipped-90, flipped-180 and flipped-270 combine that mirror with each quarter turn. A panel in an ordinary bezel uses normal or a plain rotate value. Reach for the flipped values when the image on the glass must come out mirrored; the plain rotate values only rotate, they never mirror.

How do I keep the rotation after the container image is rebuilt?

Put the file in the build. The image ships two copies, weston.ini to /etc/xdg/weston/weston.ini and weston-dev.ini to /etc/xdg/weston-dev/weston.ini; replace both with your edited file so whichever path loads at runtime carries the rotation. A compose bind mount over the same path keeps your file in charge through container restarts.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote