Задать вопрос
romesses
@romesses
Backend инженер

Почему в контейнере alpine:latest программа на Го ведет себя по другому чем в golang:1.15?

В программе используется вывод от tail.
Код программы на Го

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func main() {
	if len(os.Args) != 2 {
		os.Exit(1)
	}
	logFilePath := os.Args[1]

	// fi, err := os.Stat(logFilePath)
	// if err != nil {
	// 	log.Fatal(err)
	// }
	// fmt.Printf("Stat: %s, %v\n", fi.Mode().String(), fi)

	cmd := exec.Command("tail", "-f", "-n 20", logFilePath)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}

	if err := cmd.Start(); err != nil {
		log.Fatal("cmd.Start error: " + err.Error())
	}

	go func() {
		scanner := bufio.NewScanner(stdout)
		for scanner.Scan() {
			line := scanner.Text()
			fmt.Printf("SCAN: %q\n", line)
			if line == "~~END~~" {
				break
			}
		}
		log.Println("scanner exit")
	}()

	if err := cmd.Wait(); err != nil {
		log.Fatal("cmd.Wait error: " + err.Error())
	}

	log.Println("DONE")
}

Dockerfile

FROM golang:1.15

ADD . /app
WORKDIR /app

ENV GOOS=linux
ENV GOARCH=amd64
ENV CGO_ENABLED=0

RUN go build -ldflags="-w -s" -o ttt


# FROM alpine:latest
# RUN apk --no-cache add ca-certificates tzdata
# WORKDIR /app
# COPY --from=0 /app/ttt .

# /tmp/logs/bla-bla.log  - доступен через примонтированный к Docker том
CMD ["./ttt", "/tmp/logs/bla-bla.log"]

Если разкомментировать строки с alpine, то образ перестанет работать корректно.
Выводит строки
2021/01/22 17:12:55 scanner exit
2021/01/22 17:12:55 cmd.Wait error: exit status 1


Почему так происходит? Виновато окружение Alpine? BusyBox?
  • Вопрос задан
  • 255 просмотров
Подписаться 2 Средний 10 комментариев
Решения вопроса 1
romesses
@romesses Автор вопроса
Backend инженер
На всякий случай, если кому-то интересно, отмечу, что пока удовлетворился решением с заменой на контейнер debian:stable-slim - за неимением времени в расследовании причин.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@raiboon
Либо запускайте в той же операционке, либо компильте с CGO_ENABLED=0
Ответ написан
@basrach
Кажется нужно указать флаг -a, т.е. go build -a ....
Насколько я понимаю вместе с флагом CGO_ENABLED=0 это заставляет что-то вроде "вкомпиливать" некоторые используемые std либы в бинарник. Без этого runtime рассчитывает на компоненты ОС, которых в alpine либо нет, либо они другие.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы