Anonymous
и проблема решится
Dmitriy
Так, еще раз. Я изучаю разработку на Go на Mac. Для разработки использую VS Code. Все прекрасно работает. Для запуска использую команду: go run "/Users/dmitriy/Documents/Work/DS/GO/Hermes/cmd/main.go" Сейчас изучаю сборку докер-контейнера, для размещения его на DigitalOcean. Сборка контейнера происходит нормально. Он размещается в докере. Но при старте контейнера не находится файл .env. Хотя сами переменные прописанные в этом файле - становятся видны в инспекторе докера. Т. е. докер то сам этот файл читает успешно.
Dmitriy
FROM golang:1.17.9-alpine AS builder COPY . /hermes/ WORKDIR /hermes/ RUN go mod download RUN go build -o ./bin/server cmd/main.go FROM alpine:latest WORKDIR /root/ COPY --from=0 /hermes/bin/server . COPY --from=0 /hermes/internal/configs internal/configs EXPOSE 80 CMD ["./server"]
Dmitriy
http://joxi.ru/DmBPGVkcqgPn7A
Dmitriy
Разве его нужно копировать? Там же конфиденциальная информация. Насколько я знаю, он должен вычитываться контейнером, но не входить в его состав. И на скрине видно, что он вычитывается правильно.
Dmitriy
скинь докерфайл
Есть идеи по поводу докер-файла?
Dmitriy
я уже успел испугаться
Anonymous
но тебе уже ответили
Dmitriy
ее выше правильно нарисовали. Но вот скрин: http://joxi.ru/VrwdwK0CojvPXm
Dmitriy
А как нужно? Какая строка у меня задана неправильно?
Dmitriy
я же контейнер запускаю, а не main.go
Dmitriy
в корне проекта. да. лежит. сервис стартует правильно, и вычитывает данные из него. на локаальной машине. Проблема возникаает только при старте контейнера в докере.
Dmitriy
и либо вы не понимаете сути проблемы, либо я ваших ответов.
Dmitriy
то что у меня нет опыта - признаю. поэтому мне очень хотелось бы чуть более побробных ответов
Anonymous
коперни енв файл прямо в точку входа
Dmitriy
не знаю, но такое ощущение что ./server не видит енв файл
у меня тоже такое ощущение. исходя из сообщения ошибки. Но разве он должен вообще иметь этой файл? Контейнер его вычитал. Переменные окружения установил правильно.
Dmitriy
коперни енв файл прямо в точку входа
В этом случае он будет частью контейнера. что абсолютно неправильно.
Dmitriy
Если добавить COPY --from=0 /hermes/.env . то все запускается нормально. Но так же, вроде, не должно быть?
Alexey
Если добавить COPY --from=0 /hermes/.env . то все запускается нормально. Но так же, вроде, не должно быть?
Почему не должно быть? Ты в билдере кладёшь все в /hermes/ , env лежит тут же Билдишь программу в /hermes/bin/server В тот образ что запускает программу копируешь прогу и конфиги. А енв так и остался в первом контейнере (в /hermes/)
Dmitriy
А, т. е. при втором этапе он не перемещается в контейнер? но в таком случае не понятно следующее: если переменные окружения определены для контейнера, то зачем ему вообще наличие .env?
Alexey
Вообще в контейнер можно зайти и посмотреть. И что куда скопировалось и через echo $ENV_VAR посмотреть что в переменных)
Dmitriy
Вообще в контейнер можно зайти и посмотреть. И что куда скопировалось и через echo $ENV_VAR посмотреть что в переменных)
Вот поэтому и вопрос. Фактически, я перемещаю закрытый ключ внутрь контейнера. я не понимаю почему без этого контейнер не запускается.
Dmitriy
на скриншоте же видно, что эти данные правильно были прочитаны
Alexey
вообще. используй compose))
Alexey
на скриншоте же видно, что эти данные правильно были прочитаны
а это точно финальный контейнер, а не builder? Просто по твоему Dockerfile, .env не должен был попасть в финальный контейнер, потому что: COPY --from=0 /hermes/bin/server . COPY --from=0 /hermes/internal/configs internal/configs А .env лежит в /hermes/
Dmitriy
а это точно финальный контейнер, а не builder? Просто по твоему Dockerfile, .env не должен был попасть в финальный контейнер, потому что: COPY --from=0 /hermes/bin/server . COPY --from=0 /hermes/internal/configs internal/configs А .env лежит в /hermes/
Изначально в докфайле его и не было. но параметры устанавливались. я так понимаю, за это отвечает команда в make файле start-container: docker run --name hermes -p 8000:80 --env-file .env hermes-server:v0.1
Alexey
🤔
Alexey
стоп. а ты как читаешь переменные?
Alexey
«Environment didn't load: open .env: no such file or directory» нашел, файл читаешь. Так его там нет. докер с помощью —env-file заинжектил твои переменные из .env файла в контейнер. т.е. по сути сделал: export varname="someval" при этом сам .env файл он туда не клал
Alexey
у меня идеи кончились 🤷‍♂️ это странно
Dmitriy
М1?
Нет, intel. Mac book pro 17-го года
Nikita
Сегодня на пытались заставить работать баш скрипт на маке
Nikita
Но мы на м1 мах пытались
Nikita
Была проблема Мак не умеет в envsubst
Nikita
Эта штука нужна что бы читать энв переменные
Nikita
Пришлось отдельно скачивать envsubst
Nikita
Потом завелось
Nikita
Попробуй, может поможет )
Nikita
Но у нас вот такая штука в скрипте была if [ -f .env ]; then export $(echo $(cat .env | sed 's/#.*//g'| xargs) | envsubst) fi
Nikita
И скрипт с такой инструкцией не работает на маках из коробки, надо доустанавливать
Dmitriy
Ну тогда бы оно не запускалось локально. Так ведь? Образ же - это уже убунту контейнер.
Nikita
Ну тогда бы оно не запускалось локально. Так ведь? Образ же - это уже убунту контейнер.
А вот это интересно. Оказалось, что докер берет инструменты из системы, на которой блидится контейнер Т.е. если ты пытаешься сделать npm install в alpine образе, у тебя не получится этого сделать на маке
Nikita
Потому что на маке из коробки нет питона
Nikita
И make
Nikita
Если делать npm install на обычном образе, все работает
Alexey
просто в apline нет почти ничего. он нужен чтобы мог запуститься на любом калькуляторе с 500мгц и 100мб памяти) Все что надо надо устанавливать
Nikita
Типа в alpine питона нету, потому что он alpine И он будет искать питон на твоей системе, на которой ты билдишь образ А если и на твоей системе его нету, то ты получишь ошибку и образ не сбится
Dmitriy
у меня сейчас мозг взорвется
Dmitriy
так образ то билдится. и устанавливается успешно. даже стартануть пытается
Dmitriy
чего там точно нет - это postgres. каак раз сейчас собирался его добавлять.
Alexey
мне кажется не должен... это же контейнер. он как раз сделан чтобы в систему хоста не лезть
Nikita
так образ то билдится. и устанавливается успешно. даже стартануть пытается
Ну, это детально смотреть надо, я просто предлагаю поставить envsubst Вдруг поможет Может он не может прочитать .env без неё
Nikita
мне кажется не должен... это же контейнер. он как раз сделан чтобы в систему хоста не лезть
Сегодня проверяли пол дня, и сильно удивились Реально. Делаешь докерфайл, ставишь туда alpine образ и делаешь npm install И ошибка
Nikita
Ставишь локально питон и оно начинает работать
Alexey
а почему питон то? npm это же nodejs. у питона pip
Dmitriy
Вот участок кода чтения переменных окружений: http://joxi.ru/8Anqw4yhNoRzk2
Ваня Гречка
для временных окружений не нужен питон
Nikita
а почему питон то? npm это же nodejs. у питона pip
Это же npm Некоторые пакеты юзают питон. Зачем? Не знаю Как? Да хер пойми Но эт факт )
Dmitriy
postgres:alpine есть
а как запустить postgres после старта контейнера внутри самого контейнера? обычно, я делаю это путем старта внешнего контейнера: docker run --name=hermes-db -e POSTGRES_PASSWORD='qwerty' -p 5432:5432 -d --rm postgres а затем запускаю миграцию
Andrey
компос тебе в помощь
Dmitriy
компос тебе в помощь
это ж просто веб-интерфейс для докера. или я ошибаюсь?
Nikita
а почему питон то? npm это же nodejs. у питона pip
https://russianblogs.com/article/41461496270/ Для gyp
Andrey
это ж просто веб-интерфейс для докера. или я ошибаюсь?
ну или docker compose если у тебя версия 2 и выше
Nikita
это ж просто веб-интерфейс для докера. или я ошибаюсь?
Это обёртка для докера Удобная, если несколько контейнеров Порядок поднятия, нетворки, настройки и т.д.
Alexey
app не запуститься пока не будет готов postgres. из-за depends on а у тебя будет pg->migrate->app
Dmitriy
app не запуститься пока не будет готов postgres. из-за depends on а у тебя будет pg->migrate->app
да, то что не запустится - это понятно. на локальном компе тоже так. пока не запущу докер и не сделаю миграцию - не работает. я не делал автоматический старт принципиально, чтоб не оставлять занятой память, пока не занимаюсь бэкендом. А вот насчет оркестровки в целом - мне кажется, это не совсем правильный путь. Т. е. в таком случае придется держать несколько «сайтов» на DigitalOcean, и настраивать их по отдельности. Целью же было создать образ, который можно будет забросить куда угодно где есть докер, стартануть его и старзу получить нужный сервис.
Nikita
да, то что не запустится - это понятно. на локальном компе тоже так. пока не запущу докер и не сделаю миграцию - не работает. я не делал автоматический старт принципиально, чтоб не оставлять занятой память, пока не занимаюсь бэкендом. А вот насчет оркестровки в целом - мне кажется, это не совсем правильный путь. Т. е. в таком случае придется держать несколько «сайтов» на DigitalOcean, и настраивать их по отдельности. Целью же было создать образ, который можно будет забросить куда угодно где есть докер, стартануть его и старзу получить нужный сервис.
Что бы такое делать, нужно следующее. Сервер с линуксом, если юзать образы на серваках, то лучше Debian Билдишь контейнер, добавляешь его в докер репозиторий. Все переменные и всю шелуху в билде делаешь. Пушишь сбилженый образ На любом серваке пулишь образ и запускаешь. Будет работать как ты хочешь
whois
Друзья, подскажите. Есть ли годная статья о проблемах коннекшенов между go и postgres. Я кое-что нашел, но слишком абстрактно: https://habr.com/ru/company/oleg-bunin/blog/461935/
Alexander
не знаю насчет постгресса, но там примерно все общее: func (db *DB) SetMaxOpenConns(n int) - в разумных пределах func (db *DB) SetMaxIdleConns(n int) - это уже из целесообразности, можно и то же самое значение поставить, что выше func (db *DB) SetConnMaxLifetime(d time.Duration) - тут минуту-пару наверное макс, я ставлю полминуты func (db *DB) SetConnMaxIdleTime(d time.Duration) - если предыдущее время большое, то можно вот выставить и использовать значение поменьше
Alexander
все - 3 или 4 пункта эти выставляешь, и тут уже не важно посгря или что-то другое. отваливается - значит со стороны гошки особо ничего не поделаешь (можно конечно db.Conn() вызывать и самому разбираться)