firebase / firebase-tools

The Firebase Command Line Tools
MIT License
4.01k stars 929 forks source link

cannot install via `firebase.tools | bash` on docker (alpine) #2675

Open zanona opened 3 years ago

zanona commented 3 years ago

[REQUIRED] Environment info

Trying to build a Dockerfile:

FROM node:13-alpine
RUN apk update && apk add bash git curl sudo
# patch sudo https://unix.stackexchange.com/a/578950
RUN echo "Set disable_coredump false" >> /etc/sudo.conf
RUN curl -sL firebase.tools| bash

Platform: Linux

[REQUIRED] Test case

$ docker build .
[+] Building 23.7s (7/7) FINISHED
 => [internal] load .dockerignore                                                                         0.0s
 => => transferring context: 2B                                                                           0.0s
 => [internal] load build definition from Dockerfile                                                      0.0s
 => => transferring dockerfile: 200B                                                                      0.0s
 => [internal] load metadata for docker.io/library/node:13-alpine                                         0.0s
 => [1/4] FROM docker.io/library/node:13-alpine                                                           0.0s
 => CACHED [2/4] RUN apk update && apk add bash git curl sudo                                             0.0s
 => CACHED [3/4] RUN echo "Set disable_coredump false" >> /etc/sudo.conf                                  0.0s
 => ERROR [4/4] RUN curl -sL firebase.tools| bash                                                        23.6s
------
 > [4/4] RUN curl -sL firebase.tools| bash:
#7 2.771 -- Checking for existing firebase-tools on PATH...
#7 2.779 -- Checking your machine type...
#7 2.786 -- Downloading binary from https://firebase.tools/bin/linux/latest
######################################################################## 100.0%#=#=-#  #
######################################################################## 100.0% -#O#-  #   #
######################################################################## 100.0%  -#O=#  #    #
######################################################################## 100.0%
#7 23.47 -- Setting permissions on binary...
#7 23.47 bash: line 255: /usr/local/bin/firebase: No such file or directory
#7 23.48 bash: line 262: e: command not found
#7 23.48 Something went wrong, firebase has not been installed.
#7 23.48 Please file a bug with your system information on Github.
#7 23.48 https://github.com/firebase/firebase-tools/
#7 23.48 -- All done!
------
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c curl -sL firebase.tools| bash]: runc did not terminate sucessfully

[REQUIRED] Steps to reproduce

  1. run docker build .

[REQUIRED] Expected behavior

Command to finish successfully

[REQUIRED] Actual behavior

Ends with error: line 255: /usr/local/bin/firebase: No such file or director

samtstern commented 3 years ago

@zanona is it possible you have a stray : in your Dockerfile?

This line looks like it has a : at the end that shouldn't be there:

RUN curl -sL firebase.tools| bash:

And these two lines suggest the same

#7 23.47 bash: line 255: /usr/local/bin/firebase: No such file or directory
#7 23.48 bash: line 262: e: command not found
zanona commented 3 years ago

Hi, @samtstern. I believe the : is just a separator to follow with the output of the program, and not part of the Dockerfile.

The error at line 262: e: command not found was indeed strange and it seems to be part of the script (see below), however I have also manually removed the e and ran the command locally, but I'm afraid that doesn't help as it's already part of the error capturing.

# If all went well, the "firebase" binary should be located on our PATH so
# we'll run it once, asking it to print out the version. This is helpful as
# standalone firebase binaries do a small amount of setup on the initial run
# so this not only allows us to make sure we got the right version, but it
# also does the setup so the first time the developer runs the binary, it'll
# be faster.
VERSION=$("$INSTALL_DIR/firebase" --version)

# If no version is detected then clearly the binary failed to install for
# some reason, so we'll log out an error message and report the failure
# to headquarters via an analytics event.
if [ -z "$VERSION" ]
then
e
    echo "Something went wrong, firebase has not been installed."
    echo "Please file a bug with your system information on Github."
    echo "https://github.com/firebase/firebase-tools/"
    echo "-- All done!"

    send_analytics_event failure
    exit 1
fi
samtstern commented 3 years ago

@zanona I sent a Pull Request to get rid of that e and hoping @abeisgoat can chime in on the larger issue

zanona commented 3 years ago

Thanks a lot!

samtstern commented 3 years ago

@zanona is this still happening?

zanona commented 3 years ago

Hey, @samtstern. I'm afraid so.

/mnt/app # apk -q update && apk -q add bash git curl sudo
/mnt/app # echo "Set disable_coredump false" >> /etc/sudo.conf
/mnt/app # curl -sL firebase.tools| bash
-- Checking for existing firebase-tools on PATH...
-- Checking your machine type...
-- Downloading binary from https://firebase.tools/bin/linux/latest
######################################################################## 100.0% #-#O=#   #
-- Setting permissions on binary...
bash: line 255: /usr/local/bin/firebase: No such file or directory
Something went wrong, firebase has not been installed.
Please file a bug with your system information on Github.
https://github.com/firebase/firebase-tools/
-- All done!
/mnt/app #
samtstern commented 3 years ago

@zanona thank you for the quick confirmation. @abeisgoat PTAL

samtstern commented 3 years ago

This is so strange I modified the install script to ls before chmod and the file totally exists:

-- Checking for existing firebase-tools on PATH...
-- Checking your machine type...
-- Downloading binary from https://firebase.tools/bin/linux/latest
######################################################################## 100.0%#=#=#                                                                         
-- Double checking
-rw-r--r--    1 root     root     124327277 Nov 13 13:31 /usr/local/bin/firebase
-- Setting permissions on binary...
./fbt.sh: line 258: /usr/local/bin/firebase: No such file or directory

So ... I'm a bit lost!

zanona commented 3 years ago

@samtstern that's correct. I checked after the failed installation and the file was indeed in there. but invoking would throw:

/mnt/app # stat /usr/local/bin/firebase
  File: /usr/local/bin/firebase
  Size: 124327277   Blocks: 242832     IO Block: 4096   regular file
Device: 45h/69d Inode: 2112477     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-13 13:37:34.000000000
Modify: 2020-11-13 13:36:52.000000000
Change: 2020-11-13 13:36:52.000000000

/mnt/app # /usr/local/bin/firebase
sh: /usr/local/bin/firebase: not found
samtstern commented 3 years ago

@zanona @abeisgoat interesting note. I downloaded the firebase.tools script and just customized it to stop after the download. Then I added RUN sudo chmod +x ./usr/local/bin/firebase to the Dockerfile as a separate step and that succeeded.

So it's something about the chmod being part of the script but ... I dunno enough about Docker.

zanona commented 3 years ago

It looks this is an issue specifically with alpine distribution. I have run the commands from ubuntu or Debian base and firebase installed successfully. However, I believe it's quite common to find alpine based images on docker nowadays.

wischweh commented 3 years ago

sudo isn't shipped with alpine cf. https://stackoverflow.com/questions/49225976/use-sudo-inside-dockerfile-alpine

akauppi commented 3 years ago

Why would you like to use curl -sL firebase.tools| bash?

I tried it on Alpine, but as you have seen, it fails. There's the other way to install Firebase CLI (npm), and I prefer it because it allows the Dockerfile to be in charge of the version to be used.

If you need an Alpine base Firebase CLI Docker image, here is firebase-ci-builder that I've authored. It's 461MB in size and I welcome all of you to join making it good!!!

akauppi commented 3 years ago

@zanona hmm.. maybe consider mentioning "Alpine" in the title? This would help people get the right context, right from the start.

bkendall commented 2 years ago

Reviving a rather old issue, but wanted to check in on it...

It does look like this only is a real issue with alpine. If I use other base images (node:14, for example), I can get the CLI working just fine. Even adding gcompat to get the library things working, alpine gives me loads of trouble.

It sounds as though it might be easier to try and detect alpine specifically and then download a build specifically for it. I'm not 100% sure that that would work, but pkg specifically has alpine as a platform option, so maybe it would.

I don't have a ton of time to dig into this at the moment, but that seems like the path I would take from here. I'll keep this in mind though and see if I can't get someone (or me, I guess) to spend some free cycles doing further investigation.

r3wald commented 2 years ago

Same problem here. To me it seems some libraries are missing per default:

~ # ldd /usr/local/bin/firebase 
    /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
    librt.so.1 => /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
Error loading shared library libstdc++.so.6: No such file or directory (needed by /usr/local/bin/firebase)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
Error loading shared library libgcc_s.so.1: No such file or directory (needed by /usr/local/bin/firebase)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f829b58a000)
Error relocating /usr/local/bin/firebase: _ZNSs7replaceEmmPKcm: symbol not found
Error relocating /usr/local/bin/firebase: _ZNSt15basic_streambufIcSt11char_traitsIcEE9pbackfailEi: symbol not found
Error relocating /usr/local/bin/firebase: _ZSt19__throw_logic_errorPKc: symbol not found
Error relocating /usr/local/bin/firebase: __cxa_begin_catch: symbol not found
Error relocating /usr/local/bin/firebase: _ZNSs6appendERKSsmm: symbol not found
Error relocating /usr/local/bin/firebase: _ZNSt9exceptionD2Ev: symbol not found
Error relocating /usr/local/bin/firebase: _ZNSsC1ERKSs: symbol not found
Error relocating /usr/local/bin/firebase: __once_proxy: symbol not found
Error relocating /usr/local/bin/firebase: _ZSt17__throw_bad_allocv: symbol not found

In Ubuntu this work's totally fine:

$ ldd /usr/local/bin/firebase 
    linux-vdso.so.1 (0x00007ffc8bdae000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe9a5848000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe9a583e000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe9a565c000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe9a550d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe9a54f2000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe9a54cf000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe9a52db000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe9a587c000)
r3wald commented 2 years ago

Got it working:

$ docker run -ti alpine:latest
/ # apk update && apk add gcompat curl bash sudo libstdc++6 libstdc++
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz
v3.15.3-2-g9717d71770 [https://dl-cdn.alpinelinux.org/alpine/v3.15/main]
v3.15.3-1-g33a0539d1f [https://dl-cdn.alpinelinux.org/alpine/v3.15/community]
OK: 15854 distinct packages available
(1/16) Installing ncurses-terminfo-base (6.3_p20211120-r0)
(2/16) Installing ncurses-libs (6.3_p20211120-r0)
(3/16) Installing readline (8.1.1-r0)
(4/16) Installing bash (5.1.16-r0)
Executing bash-5.1.16-r0.post-install
(5/16) Installing ca-certificates (20211220-r0)
(6/16) Installing brotli-libs (1.0.9-r5)
(7/16) Installing nghttp2-libs (1.46.0-r0)
(8/16) Installing libcurl (7.80.0-r0)
(9/16) Installing curl (7.80.0-r0)
(10/16) Installing musl-obstack (1.2.3-r0)
(11/16) Installing libucontext (1.1-r0)
(12/16) Installing gcompat (1.0.0-r4)
(13/16) Installing libgcc (10.3.1_git20211027-r0)
(14/16) Installing libstdc++ (10.3.1_git20211027-r0)
(15/16) Installing libstdc++6 (6.4.0-r12)
(16/16) Installing sudo (1.9.8_p2-r1)
Executing busybox-1.34.1-r4.trigger
Executing ca-certificates-20211220-r0.trigger
OK: 15 MiB in 30 packages
/ # curl -sL firebase.tools | bash
-- Checking for existing firebase-tools on PATH...
-- Checking your machine type...
-- Downloading binary from https://firebase.tools/bin/linux/latest
######################################################################## 100.0% #-#O=#   #                                                                   
-- Setting permissions on binary...
-- Checking your PATH variable...
-- firebase-tools@10.5.0 is now installed
-- All Done!
/ # firebase
Usage: firebase [options] [command]

Options:
  -V, --version                                               output the version number
  -P, --project <alias_or_project_id>                         the Firebase project to use for this command
  --account <email>                                           the Google account to use for authorization
  -j, --json                                                  output JSON instead of text, also triggers non-interactive mode
  --token <token>                                             supply an auth token for this command
  --non-interactive                                           error out of the command instead of waiting for prompts
  -i, --interactive                                           force prompts to be displayed
  --debug                                                     print verbose debug output and keep a debug log file
  -c, --config <path>                                         path to the firebase.json file to use for configuration
  -h, --help                                                  output usage information

Commands:
  appdistribution:distribute [options] <release-binary-file>  upload a release binary
  appdistribution:testers:add [options] [emails...]           add testers to project
  appdistribution:testers:remove [options] [emails...]        remove testers from a project
  apps:create [options] [platform] [displayName]              create a new Firebase app. [platform] can be IOS, ANDROID or WEB (case insensitive).
  apps:list [platform]                                        list the registered apps of a Firebase project. Optionally filter apps by [platform]: IOS, ANDROID or WEB (case insensitive)
  apps:sdkconfig [options] [platform] [appId]                 print the Google Services config of a Firebase app. [platform] can be IOS, ANDROID or WEB (case insensitive)
  apps:android:sha:list <appId>                               list the SHA certificate hashes for a given app id. 
  apps:android:sha:create <appId> <shaHash>                   add a SHA certificate hash for a given app id.
  apps:android:sha:delete <appId> <shaId>                     delete a SHA certificate hash for a given app id.
  auth:export [options] [dataFile]                            Export accounts from your Firebase project into a data file
  auth:import [options] [dataFile]                            import users into your Firebase project from a data file(.csv or .json)
  crashlytics:symbols:upload [options] <symbolFiles...>       Upload symbols for native code, to symbolicate stack traces.
  database:get [options] <path>                               fetch and print JSON data at the specified path
  database:instances:create [options] <instanceName>          create a realtime database instance
  database:instances:list                                     list realtime database instances, optionally filtered by a specified location
  database:profile [options]                                  profile the Realtime Database and generate a usage report
  database:push [options] <path> [infile]                     add a new JSON object to a list of data in your Firebase
  database:remove [options] <path>                            remove data from your Firebase at the specified path
  database:set [options] <path> [infile]                      store JSON data at the specified path via STDIN, arg, or file
  database:settings:get [options] <path>                      read the realtime database setting at path
  database:settings:set [options] <path> <value>              set the realtime database setting at path.
  database:update [options] <path> [infile]                   update some of the keys for the defined path in your Firebase
  deploy [options]                                            deploy code and assets to your Firebase project
  emulators:exec [options] <script>                           start the local Firebase emulators, run a test script, then shut down the emulators
  emulators:export [options] <path>                           export data from running emulators
  emulators:start [options]                                   start the local Firebase emulators
  experimental:functions:shell [options]                      launch full Node shell with emulated functions. (Alias for `firebase functions:shell.)
  ext                                                         display information on how to use ext commands and extensions installed to your project
  ext:configure [options] <extensionInstanceId>               configure an existing extension instance
  ext:info [options] <extensionName>                          display information about an extension by name (extensionName@x.y.z for a specific version)
  ext:export [options]                                        export all Extension instances installed on a project to a local Firebase directory
  ext:install [options] [extensionName]                       install an official extension if [extensionName] or [extensionName@version] is provided; or run with `-i` to see all available extensions.
  ext:list                                                    list all the extensions that are installed in your Firebase project
  ext:uninstall [options] <extensionInstanceId>               uninstall an extension that is installed in your Firebase project by instance ID
  ext:update [options] <extensionInstanceId> [updateSource]   update an existing extension instance to the latest version
  firestore:delete [options] [path]                           Delete data from Cloud Firestore.
  firestore:indexes [options]                                 List indexes in your project's Cloud Firestore database.
  functions:config:clone [options]                            clone environment config from another project
  functions:config:export                                     Export environment config as environment variables in dotenv format
  functions:config:get [path]                                 fetch environment config stored at the given path
  functions:config:set [values...]                            set environment config with key=value syntax
  functions:config:unset [keys...]                            unset environment config at the specified path(s)
  functions:delete [options] [filters...]                     delete one or more Cloud Functions by name or group name.
  functions:log [options]                                     read logs from deployed functions
  functions:shell [options]                                   launch full Node shell with emulated functions
  functions:list                                              list all deployed functions in your Firebase project
  functions:secrets:access <KEY>[@version>                    Access secret value given secret and its version. Defaults to accessing the latest version.
  functions:secrets:destroy [options] <KEY>[@version>         Destroy a secret. Defaults to destroying the latest version.
  functions:secrets:get <KEY>                                 Get metadata for secret and its versions
  functions:secrets:prune                                     Destroys unused secrets
  functions:secrets:set [options] <KEY>                       Create or update a secret for use in Cloud Functions for Firebase
  help [command]                                              display help information
  hosting:channel:create [options] [channelId]                create a Firebase Hosting channel
  hosting:channel:delete [options] <channelId>                delete a Firebase Hosting channel
  hosting:channel:deploy [options] [channelId]                deploy to a specific Firebase Hosting channel
  hosting:channel:list [options]                              list all Firebase Hosting channels for your project
  hosting:channel:open [options] [channelId]                  opens the URL for a Firebase Hosting channel
  hosting:clone <source> <targetChannel>                      clone a version from one site to another
  hosting:disable [options]                                   stop serving web traffic to your Firebase Hosting site
  hosting:sites:create [options] [siteId]                     create a Firebase Hosting site
  hosting:sites:delete [options] <siteId>                     delete a Firebase Hosting site
  hosting:sites:get <siteId>                                  print info about a Firebase Hosting site
  hosting:sites:list                                          list Firebase Hosting sites
  init [feature]                                              Interactively configure the current directory as a Firebase project or initialize new features in an already configured Firebase project directory.

  This command will create or update 'firebase.json' and '.firebaserc' configuration files in the current directory. 

  To initialize a specific Firebase feature, run 'firebase init [feature]'. Valid features are:

    - database
    - emulators
    - firestore
    - functions
    - hosting
    - hosting:github
    - remoteconfig
    - storage
  login [options]                                             log the CLI into Firebase
  login:add [options] [email]                                 authorize the CLI for an additional account
  login:ci [options]                                          generate an access token for use in non-interactive environments
  login:list                                                  list authorized CLI accounts
  login:use <email>                                           set the default account to use for this project directory
  logout [email]                                              log the CLI out of Firebase
  open [link]                                                 quickly open a browser to relevant project resources
  projects:addfirebase [projectId]                            add Firebase resources to a Google Cloud Platform project
  projects:create [options] [projectId]                       creates a new Google Cloud Platform project, then adds Firebase resources to the project
  projects:list                                               list all Firebase projects you have access to
  remoteconfig:get [options]                                  get a Firebase project's Remote Config template
  remoteconfig:rollback [options]                             roll back a project's published Remote Config template to the one specified by the provided version number
  remoteconfig:versions:list [options]                        get a list of Remote Config template versions that have been published for a Firebase project
  serve [options]                                             start a local server for your static assets
  setup:emulators:database                                    downloads the database emulator
  setup:emulators:firestore                                   downloads the firestore emulator
  setup:emulators:pubsub                                      downloads the pubsub emulator
  setup:emulators:storage                                     downloads the storage emulator
  setup:emulators:ui                                          downloads the ui emulator
  target [type]                                               display configured deploy targets for the current project
  target:apply <type> <name> <resources...>                   apply a deploy target to a resource
  target:clear <type> <target>                                clear all resources from a named resource target
  target:remove <type> <resource>                             remove a resource target
  use [options] [alias_or_project_id]                         set an active Firebase project for your working directory
/ # 
tyler-jewell commented 10 months ago

For what it's worth, I struggled with this issue for days, and this is the Dockerfile that finally works (I needed it to work for Flutter and Firebase).

# Environemnt to install flutter and build web
FROM debian:latest AS build-env

# install all needed stuff
RUN apt-get update && apt-get install -y \
    curl \
    nano \
    sudo \
    git \
    build-essential \
    unzip \
    clang \
    cmake \
    ninja-build \
    libgtk-3-dev \
    liblzma-dev \
    libstdc++-12-dev \
    pkg-config

RUN apt update && apt install -y \
    nodejs \
    npm \
    gh

# install firebase-cli
RUN npm install -g firebase-tools

# define variables
ARG GIT_URL=https://github.com/flutter/flutter.git
ARG FLUTTER_SDK=/usr/local/flutter
ARG APP=/app/

# clone flutter
RUN git clone $GIT_URL $FLUTTER_SDK

# change dir to current flutter folder and make a checkout to the specific version
RUN cd $FLUTTER_SDK && git fetch && git checkout stable

# setup the flutter path as an enviromental variable
ENV PATH="$PATH:$FLUTTER_SDK/bin"

# Start to run Flutter commands
# doctor to see if all was installes ok
RUN flutter channel stable
RUN flutter upgrade
RUN flutter precache
RUN flutter doctor -v

# create folder to copy source code
RUN mkdir $APP
# copy source code to folder
COPY . $APP
# setup new folder as the working directory
WORKDIR $APP

# build flutter apps
RUN flutter clean
RUN flutter pub get
RUN flutter build linux
RUN flutter build web