0

I have a node/docker app that runs some scripts, and downloads a file to the docker fs, which is then sent to an FTP server. The file is saved to the filesystem in a folder that resides in the same directory (app/src) as the node scripts, allowing easy access for the scripts to then ftp the file. Currently, the scripts are only able to download the file when the image is run as root user, with the --privileged flag. I want to production-ize this and deploy it (ideally on Heroku). Heroku does not allow images to be run as root afaik.

Changing the user to non-root causes the file to not be downloaded, though the container is built perfectly fine, and the image runs with no errors thrown. Seems to be a permissions issue.

Is there a way I can modify this so that I can run this as non-root user and still get the file into the filesystem? The scripts run a headless chrome browser that crawls a website and clicks a button to download an xls file. ( I have the non-privileged user commented out and root user uncommented here, just so I can switch back and forth when testing)

Dockerfile

FROM node:latest

# update and add all the steps for running with xvfb
RUN apt-get update &&\
apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
xvfb x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps \
&& apt-get install -y wget gnupg \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
  --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

#remove zombie images
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_x86_64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
ENTRYPOINT ["dumb-init", "--"]

# add the required dependencies
WORKDIR /app

# COPY node_modules /app/node_modules

RUN npm install puppeteer \
# Add user so we don't need --no-sandbox.
    # same layer as npm install to keep re-chowned files from using up several hundred MBs more space
    && groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && npm install express \
    && npm install basic-ftp 
    # && chown -R pptruser:pptruser /node_modules
EXPOSE 3000
# Run everything after as non-privileged user.
# USER pptruser
USER root
# Finally copy the build application
COPY . .

# make sure we can run without a UI
ENV DISPLAY :99

CMD Xvfb :99 -screen 0 1024x768x16 -nolisten unix & node server.js

Here are permissions for /app

root@d5c51850b0b7:/app# ls -al

total 92
drwxr-xr-x   1 root root  4096 Dec  8 17:24 .
drwxr-xr-x   1 root root  4096 Dec  9 17:05 ..
-rw-r--r--   1 root root  6148 Dec  7 18:00 .DS_Store
-rw-r--r--   1 root root    41 Dec  7 17:26 .dockerignore
-rw-r--r--   1 root root    46 Dec  7 18:53 .env
drwxr-xr-x   7 root root  4096 Dec  7 18:02 .git
-rw-r--r--   1 root root  1610 Dec  7 18:01 .gitignore
-rw-r--r--   1 root root  2120 Dec  8 17:24 Dockerfile
-rw-r--r--   1 root root   950 Dec  7 21:50 Readme.md
-rw-r--r--   1 root root   140 Dec  7 21:46 docker-compose.yml
drwxr-xr-x 102 root root  4096 Dec  4 17:10 node_modules
-rw-r--r--   1 root root 32485 Dec  7 19:36 package-lock.json
-rw-r--r--   1 root root   307 Dec  7 19:36 package.json
-rw-r--r--   1 root root   262 Dec  8 17:21 server.js
drwxr-xr-x   2 root root  4096 Dec  7 17:26 src
behindClouds
  • 81
  • 1
  • 9
  • 1
    can you paste the permissions of /app ? as a quick fix you can also use /tmp. – Naveen Kulkarni Dec 08 '20 at 18:14
  • How can I see the permissions of /app? or where can I paste them from? And do you mind elaborating on what /tmp is? Thanks for the reply :) – behindClouds Dec 08 '20 at 20:11
  • 1
    You can run `ls -al` to view the permissions ( you can add that in the docker file, or run the container in local and exec into it). /tmp in linux is a directory which will have 777 as permission so you will never get the permission error. You can set `WORKDIR /tmp` – Naveen Kulkarni Dec 09 '20 at 06:09
  • Ive edited my original post with the permissions for /app. I set `WORKDIR` to /tmp and set my user to non-root and turned off the --privileged flag, and ran the scripts, but no file was downloaded. I dont see a permissions error getting thrown on the logs though. Are there more steps I would need to take? Would I need to have the scripts download the file to the /tmp directory? – behindClouds Dec 09 '20 at 17:16
  • Update: Setting the work dir to temp seems to have worked! Hopefully this is a robust enough fix to be deployable. – behindClouds Dec 09 '20 at 17:28
  • 1
    yes you can use that. Also as you can see the permissions to `/app` is `root:root` and because heroku runs with a non root user you will get this problem. You can also try adding a user with appropriate permissions. https://stackoverflow.com/questions/39855304/how-to-add-user-with-dockerfile – Naveen Kulkarni Dec 10 '20 at 06:19

0 Answers0