gem install fails when building an image on Docker for Windows - ruby

I'm trying to build a Docker image from a Dockerfile. The image is based on the latest node:alpine image. It installs Ruby and a few gems on top of it. Here is the Dockerfile:
FROM node:alpine
ENV BUNDLE_SILENCE_ROOT_WARNING=1 BUNDLE_APP_CONFIG=/usr/local/bundle \
BUNDLE_BIN=/usr/local/bundle/bin BUNDLE_PATH=/usr/local/bundle
RUN apk add ruby ruby-io-console ruby-bundler ca-certificates \
build-base ruby-dev ruby-json libffi-dev \
python zlib-dev --no-cache && \
update-ca-certificates
WORKDIR /opt/middleman
COPY Gemfile* ./
RUN bundle install --clean
COPY package.json ./
RUN npm install
I can build the image on Linux and MacOS, but on Windows bundler fails randomly, on a different gem every time, with the following message:
Gem::RemoteFetcher::FetchError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (https://rubygems.org/gems/rack-2.0.1.gem)
I've googled the SSL error and most solutions suggest installing some SSL certificates. However, in my case the base Docker image is the same. Only the Docker host OS is different. And if the problem were the SSL certs, bundler would always fail on the first gem not a random one each time. So my guess is there's something wrong when Docker runs on Windows, but I have run out of ideas. Any help?
PS: I've made sure that all machines have the same snapshot of node:alpine which happens to be this:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node alpine 37434f668ea8 30 hours ago 55.3 MB
Update:
I also tried building the quick-start Rails image and it fails.
I tried building the quick-start image with the older Docker Toolbox which uses VirtualBox instead of Hyper-V. It failed again, each time on a different gem, but the error is now different:
Gem::RemoteFetcher::FetchError: Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/gems/minitest-5.10.1.gem)
Still an SSL error, though.

Thanks for all your comments. I finally found the culprit. It's a "feature" of my Killer Wireless card... For future reference, I had to disable "Advanced Stream Detect" in the "Killer Network Manager" app. Here's a screenshot:
They should probably call it SSL killer.

Related

Laravel Sail Up never finishes building during GPG command

I'm trying to setup the dev environment for an existing project on another computer under WSL2 and Windows 10. Having installed the project from its own repo with composer install and making sure a basic .env file is in place, I ran /vendor/bin/sail up to do the initial build.
Docker starts normally, but then during stage 4 of 11 RUN apt-get update && apt-get install...., it just halts when it gets to the line gpg: keybox '/root/.gnupg/pubring.kbx' created the build halts, the clock is still ticking but the operation never finishes.
I'm able to hit Ctrl + C and it Cancels cleanly.
Editing Laravel's dockerfile, I added a -v to the gpg --recv-key ... line in the script and got additional output with the operation halting after gpg: connection to dirmngr established instead.
I'm running Ubuntu under WSL2, fully updated, docker freshly installed and configured to talk to it as on my other machine where I'm not having any issues.
Removing the portnumber (:80) for the keyserver from the PHP 8.x docker file seems to be a workaround for this problem.
echo "keyserver hkp://keyserver.ubuntu.com" >> ~/.gnupg/dirmngr.conf \
Tested with PHP 8.1.
Source: https://github.com/laravel/sail/issues/503#issuecomment-1336273951

expired ca certificates in ruby docker image (2.6.8-bullseye)

Last Friday I started seeing issues (on an environment that has been live for months) this issue on ruby on this docker image:
RestClient::SSLCertificateNotVerified: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
I then proceeded trying adding a custom PEM (wget https://curl.se/ca/cacert.pem) to link in the environment variable SSL_CERT_FILE (as explained in many other stack overflow questions).
but I get:
bash-4.4# wget https://curl.se/ca/cacert.pem
Connecting to curl.se (151.101.2.49:443)
ssl_client: curl.se: certificate verification failed: certificate has expired
wget: error getting response: Connection reset by peer
I tried saving the file on my local machine then docker cp it to the container, but that didn't help either.
I tried running the console with:
bash-4.4# SSL_CERT_FILE=/cacert.pem bundle exec rails c
irb(main):001:0> RestClient.get('https://curl.se/ca/cacert.pem', headers={})
RestClient.get "https://curl.se/ca/cacert.pem", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client/2.0.2 (linux-musl x86_64) ruby/2.3.8p459"
RestClient::SSLCertificateNotVerified: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
I tried running update-ca-certificates both manually in the console, and in the dockerfile, but I get:
bash-4.4# update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
When I tried this with the cacert.pem copied to the container as above, update-ca-certificates added a warning to that file too, similar to the ca-certificates.crt one.
the issue doesn't seem to improve with anything.
running
curl -Lks 'https://git.io/rg-ssl' | ruby
say it's all ok, and all (3) green checks
any ideas?
Thanks.
update
I think this issue might be related to lets encrypt expiring their root certificate, I tried the first workaround they recommend, by deleting the file on a container, and also deleting it on the dockerfile, then running update-ca-certificates this didn't help either. I'm not sure how to go about the other two workarounds.
If you are on debian 9, I would recommend you to update it. Otherwise, this is my workaround solution for my image.
# Temporarily fix wrong let's encrypt R3 chain because it's chained to an expired old root CA (DST Root CA X3) on debian 9
RUN sed -i -E 's/(.*DST_Root_CA_X3.*)/!\1/' /etc/ca-certificates.conf
ADD https://letsencrypt.org/certs/isrgrootx1.pem /usr/local/share/ca-certificates/isrgrootx1.pem
RUN update-ca-certificates
FYI: there is a bug on OpenSSL 1.0.2g that causes the issue https://www.openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire/ some platforms have released the workaround fix and you just need to upgrade latest ca-certificates and latest libgnutls30. It would be better if you can upgrade to a more recent OpenSSL.
A way to fix the issue would be to run on the container's console:
apt update && apt install ca-certificates
However, this would be a Docker antipattern, as the changes would be lost when at the container deletion.
The better way would be to rebuild the image from the Dockerfile that you have linked in your question (with docker build), then deleting and recreating the container from the new image.

Unable to download Go packages from GitHub

I'm getting below error while downloading.
go get github.com/go-sql-driver/mysql: module github.com/go-sql-driver/mysql: Get "https://proxy.golang.org/github.com/go-sql-driver/mysql/#v/list": x509: certificate signed by unknown authority
Go version - 1.13/1.15(tried both)
OS - Ubuntu 18
Tried update ca-certificates as well
Can anyone help me out?
Check first the context in which this error pops up:
go version
execution environment (shell).
For instance, this error pops up during Docker build instance, where the Dockerfile uses an image without certificates installed, as in golang/go issue 35702.
Said Dockerfile would need:
RUN apk update && apk add --no-cache git ca-certificates && update-ca-certificates

`bundle` not in Docker PATH

I have a docker image (which is delivered as-is, with no Dockerfile etc.) with Ruby application in it, when I try to run docker container with docker run application_image bundle exec puma -C config/puma.rb I get starting container process caused "exec: \"bundle\": executable file not found in $PATH": unknown.. All suggested fixes for this are to specidy stuff in Dockerfile (whick is not present there). Is there away to run container this way?
There are some walk-around maybe.
Create another docker image based on the existing one, with bundle installed
Install bundle before actually running the application
It's best if you can ask the image maintainer for instructions.
If that fails try exploring the docker image first like #hmm suggested see: https://stackoverflow.com/a/58256085/5641227 on how to do that.
Then either extract the image contents if your are allowed to and build it your self from scratch.
Or try building a new image from the one you have and add new build steps to the new Dockerfile:
FROM <your-current-image:and-tag>
RUN gem install bundler -v "~>2.0.2" --no-document --quiet --force
CMD ["bundle", "exec", "puma -C config/puma.rb"]
Then just run it after you tag and build your new image:
docker run new_application_image
Also, you need to have the right version of bundler. 2.0.2 is just an example. having a conflicting version won't work.

Is it possible to run xvfb on Heroku?

I'd like to run xvfb on Heroku. On my mac, I used the dmg to install it. Would anyone have any idea how to go about this on Heroku?
I came across these buildpacks (http://github.com/douglasjsellers/heroku-xvfb-buildpack) - but following the instructions didn't seem to solve the problem as xvfb is still not installed properly. Also, I tried installing the xvfbwrapper (https://pypi.python.org/pypi/xvfbwrapper/0.1.0), but it's still not working on Heroku (apologies for what is potentially a noob question).
Here is the error I get in my logs off of Heroku:
2015-02-24T02:09:16.035298+00:00 app[web.6]: cmd=['Xvfb', '-help']
2015-02-24T02:09:16.035564+00:00 app[web.6]: Program install error!
2015-02-24T02:09:16.035302+00:00 app[web.6]: OSError=[Errno 2] No such file or directory
Here is the code:
temp = tempfile.mkstemp(suffix='.html')
html = os.fdopen(temp[0], "r+")
html.write(cv)
html.seek(0, 0)
display = Display(visible=0, size=(800, 600))
display.start()
# Open the file on Selenium to load the JavaScript
driver = webdriver.Firefox()
driver.get("file://" + temp[1])
I found this question while researching how to update Xvfb for Cedar-14, and I managed to get #2 to work. So here's how:
I used buildpack-apt to install x11-xkb-utils xvfb x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic libxfont1 xvfb.
After running the apt buildpack, you need to patch Xvfb a bit to make everything work smoothly. For that, I used my own run-bash buildpack, but everything that lets you run a bash script during Heroku compile will work. Here's the script I used to patch Xvfb and index the fonts: https://gist.github.com/fxtentacle/960cdb96ece01add8686
Now you can use heroku run bash to check with XAUTHORITY=/tmp/xvfb-run.2NG0xl/Xauthority Xvfb ":99" -screen 0 1280x1024x24 -nolisten tcp that the Xvfb is working.
Yes, it is possible, but complicated. I followed some of what fxtentacle did (in their answer), but this may be simpler. These instructions provide for a minimal Xvfb setup; it still prints out a bunch of warnings.
Use heroku-buildpack-apt to install the xvfb and libnotify4 debian packages. Then use this buildpack to fix the /usr/bin/xkbcomp issue:
https://github.com/captain401/heroku-buildpack-xvfb
Then you can use xvfb-run $PROGRAM to run your application.
I'm wondering the same thing. Seems like you already found this guy's issue. All the buildpacks mentioned are 1+ years old, and don't work anymore.
Two viable seeming options:
Compile a self-contained xvfb binary a la https://github.com/kenshin23/xvfb-portable-binary that runs on Heroku's current OS and architecture, rebuild when they update.
Install all dependencies from the apt package manager into someplace like ~/.apt, and run from there, as in the latest buildpack-apt. For me, this option dies with sh: 1: /usr/bin/xkbcomp: not found. Xvfb is looking in /, while apt installed the command to ~/.apt/usr/bin/xkbcomp. Haven't figured out how to tell Xvfb to look in ~/.apt/.

Resources