Skip to content
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

docs: Air **requires** tty, a detail that may be more important for Docker users #737

Open
aentwist opened this issue Feb 5, 2025 · 6 comments

Comments

@aentwist
Copy link

aentwist commented Feb 5, 2025

Description

Air runs my program, but does not live reload, when using Docker. It works on the host machine.

As a... for now... WSL developer, I really tried to get it working however I could.

Here's what I've tried:

Host machines
  • Windows 11 / WSL2 Debian 12 (amd64) [Docker Desktop]
  • AWS EC2 Ubuntu 24.04.1 (amd64) [Docker engine]

-> does not appear to be a host issue (WSL/Windows/Docker Desktop)

Docker configurations
  • copy code into container. docker run
  • copy code into container. docker compose up
  • bind mount code into container. docker run
  • bind mount code into container. docker compose up

-> does not appear to be either a bind mount or docker compose issue

Go versions
  • 1.23.6 (go install air + air -c .air.toml)
  • 1.24rc2 (go get -tool air + go tool air -c .air.toml)

-> does not appear to be incompatibility with the upcoming go get -tool + go tool or other unstable release bug

Air versions
  • 1.61.7
  • 1.60.0
  • 1.51.0

-> does not appear to be a regression in Air

Enabling poll = true

-> I mean it doesn't seem like a fsnotify bug... because of all of the above, and because this isn't working for me either...

Reproduction

https://github.com/aentwist/air-repro

Environment / Preferred Environment

  • linux + docker engine - sanity
  • Docker version 27.5.1, build 9f9e405 (latest installed via Docker's apt repo)
  • go 1.24rc2 - really excited to use the new dev dependencies feature
  • air 1.61.7
@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

Related to #190 #26 <- I work on the WSL FS, not the Windows FS
Potentially related to #272 <- Probably not

@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

This note is probably missing in the README. I cant use the air docker image if it isnt open source (I cant find the source). Reading its source code might have saved me this.

First problem
  • go embeds vcs information into binaries
  • when copying files, ownership of .git is transferred to the docker user
  • when bind mounting volumes, ownership is not transferred
  • git has a safety mechanism safe.directory
    • prevents interacting with non-owned git data (because all git data should always be owned)
    • causes go build to fail - cannot embed vcs information (error obtaining VCS status: exit status 128 Use -buildvcs=false to disable VCS stamping.)
    • try git status to check whether this is being triggered
Solution
  • can tell go to not embed vcs information. this is ok to do for development only
    • add -buildvcs=false to build command
  • can tell git to add the directory as a safe directory. this adds coupling between git and the code, which is a weird antipattern
  • can tell git to add the directory as a safe directory globally inside the container. seems ok, although with some security downside if your config also applies it to production
    • git config --global --add safe.directory /usr/src/app
  • can tell git to turn off safe directory protections by setting it to *. there isnt really any reason to do this, it has much worse security
  • use docker compose watch instead. press release, docs

@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

At this point from what I can tell, air runs successfully if I run it manually inside the container but not when docker runs it via command. So it seems like an environment issue. Probably, I think air will say if it can't find the code, so it should not be an issue of directories/paths.

@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

Working:

docker build -t app .
docker run -it --rm -p 3000:3000 -v .:/usr/src/app app go tool air

Not working: docker compose up

FROM golang:1.24rc2-bookworm

WORKDIR /usr/src/app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .
RUN go build -v -o /usr/local/bin/app ./...

CMD ["app"]
services:
  app:
    build: .
    ports:
      - 3000:3000
    volumes:
      - .:/usr/src/app
    command: bash -c 'go tool air'

See https://docs.docker.com/reference/compose-file/services/#command

Unlike the CMD instruction in a Dockerfile, the command field doesn't automatically run within the context of the SHELL instruction defined in the image. If your command relies on shell-specific features, such as environment variable expansion, you need to explicitly run it within a shell.

polling doesnt help

@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

Solution

Before opening an issue on Docker Compose I wanted to make sure the two (docker run vs. my Compose file) were actually spec'd to be identical. https://forums.docker.com/t/docker-compose-vs-docker-run/138216/7

Air requires tty. When using Docker run I do this by default (-t, I always use -it). However, nobody really specifies this by default for Compose. So we need to add tty: true to the Compose file.

 services:
   app:
     build: .
+    tty: true
     ports:
       - 3000:3000
     volumes:
      - .:/usr/src/app
    command: go tool air

If -buildvcs=false was not a documentation oversight, this feels like a massive documentation oversight..

Is there a setting you can use to turn off the need for tty? Why is tty needed?

@aentwist aentwist changed the title Air live reload does not work in Docker docs: Air **requires** tty, a detail that may be more important for Docker users Feb 8, 2025
@aentwist
Copy link
Author

aentwist commented Feb 8, 2025

Given that I just spent about 8h on this, a PR would be no big deal

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

No branches or pull requests

1 participant