Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easy way to change to a non-root user in Bitbucket Pipelines Docker container?

Bitbucket Pipelines is using Docker containers to executes tasks and by default Docker containers run as root. This is a problem for NPM's lifecycle scripts because NPM tries to downgrade its privileges when it runs scripts.

When executing the postinstall script, NPM throws an error that it cannot run in wd %s %s (wd=%s). The simplest solution is to run npm install with the --unsafe-perm flag, but I don't like this approach.

Docker's best practices for writing Dockerfiles states that:

If a service can run without privileges, use USER to change to a non-root user.

When configuring a typical Docker container I would create a new, non-root user and run my npm scripts as this user.

After reading Pipelines documentation I couldn't find any equivalent to Docker's USER command. I might be able to use useradd, chown and su (didn't test that yet) but is there a simpler solution?

Unfortunately adding useradd, chown and su to bitbucket-pipelines.yml script section breaks Pipelines and results in failing repo:push webhook.

image: node:6.2

pipelines:
  default:
    - step:
        script:
          - useradd --user-group --create-home --shell /bin/false node
          - chown -R node: /opt/atlassian/bitbucketci/agent/build
          - su -s /bin/sh -c "npm install" node
          - su -s /bin/sh -c "npm run test:coverage --silent" node

Pipelines responds with

{
  "code": 500,
  "message": "There was an error processing your request. It has been logged (ID <removed>)."
}
like image 621
Jakub Synowiec Avatar asked Aug 22 '16 11:08

Jakub Synowiec


People also ask

Does Docker run containers as root?

Docker containers typically run with root as the default user. To share resources with different privileges, we may need to create additional users inside a Docker container. Here, we'll create a Dockerfile and add a new user.

Should Docker be run as root?

Running the container as root brings a lot of risks. Although being root inside the container is not the same as root on the host machine (some more details here) and you're able to deny a lot of capabilities during container startup, it is still the recommended approach to avoid being root .


2 Answers

There's two things to address in this question.


To run as a non-root user in Bitbucket Pipelines, you can do exactly what you have suggested and use the USER Docker command. The node:6.2 image does not map to a non-root user, so if you would like to do so you can create a new Docker image with the following Dockerfile:

FROM node:6.2

USER foo

The 500 error you are receiving appears to be an issue with YAML parsing on this line:

- chown -R node: /opt/atlassian/bitbucketci/agent/build

The ':' is a special character in the YAML format. Indicating a key-value pair. In order to fix this, put the contents on that line inside of quotes instead like this:

- "chown -R node: /opt/atlassian/bitbucketci/agent/build"

I would also suggest you use the new default environment variable for the build path now. $BITBUCKET_CLONE_DIR. So change the line to instead be

- "chown -R node: $BITBUCKET_CLONE_DIR"
like image 116
phod Avatar answered Sep 28 '22 07:09

phod


Since the node image already creates a node user (at least in 6.9+), you don't need the useradd. It also seems to work well without the chown. In the end, I have a script looking like this - and it appears to be just fine:

image: node:7

pipelines:
  default:
    - step:
        script:
          - su -s /bin/bash -c "npm install" node
          - su -s /bin/bash -c "npm run build" node
like image 21
Konrad Garus Avatar answered Sep 28 '22 05:09

Konrad Garus